Planet Octavehttp://planet.octave.org/atom.xml2021-06-20T18:45:08+00:00Planet/2.0 +http://www.planetplanet.orgabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1742021-06-10T14:10:58+00:00<p>Hello there. In this blog post, I will describe how to setup a GNU Octave package using the <a href="https://github.com/gnu-octave/pkg-example" target="_blank" rel="noreferrer noopener">new GitHub template</a>. This is what I did to create the package that I will be working on during this GSoC. Let’s get started.</p>
<p>I followed those easy steps to setup my package:</p>
<p>1- Create a repo from the template:</p>
<p>As I am a part of the GNU Octave GitHub organization, I was able to do that easily. If you are not a member, Join the <a href="https://github.com/gnu-octave">GNU Octave GitHub organization</a> by asking for an invitation at our <a href="https://octave.discourse.group/t/github-gitlab-organization-for-gnu-octave/178">Discourse forum</a>.</p>
<p>2- (Optional) Change the license:</p>
<p>the “COPYING” file contains the license text of the package. You may change the license if you want. For my package, I left it as it is.</p>
<p>3- Update DESCRIPTION:</p>
<p>Update the fields in this file to match your package. For my package, I used the following:</p>
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; first-line: 1; title: ; notranslate">
name: pkg-jupyter-notebook
version: 1.0.0
date: 2021-05-30
author: Abdallah Elshamy <abdallah.k.elshamy@gmail.com>
maintainer: Kai T. Ohlhus <k.ohlhus@gmail.com>,
Abdallah Elshamy <abdallah.k.elshamy@gmail.com>
title: A package to run and fill Jupyter Notebooks within GNU Octave.
description: A package to run and fill Jupyter Notebooks within GNU Octave.
This would enable Jupyter Notebook users to evaluate
long-running Octave Notebooks on a computing server without
a permanent browser connection, which is still a pending issue.
categories: package
depends: pkg-json (>= 1.0.0)
</pre></div>
<p>4- Update your README:</p>
<p>Right now, your README is the same as the template. Change it to suit your package.</p>
<p>5- Change the package icon in docs and remove the other images from there:</p>
<p>Currently, your icon is the same as the template. Change it to suit your package. There are also some other images that were used in the README of the template that you need to remove.</p>
<p>6- Remove unnecessary files from src:</p>
<p>Initially, this directory contains examples for Octave/Matlab code, FORTRAN code, C++ code called by the oct-interface, and C code called by the mex-interface. Remove the files that you don’t need and rename the rest of the files to match your package.</p>
<p>7- (Optional) Amend the initial commit and force push your changes:</p>
<p>The setup is now complete but you may want to amend the initial commit using <code>git commit --amend</code> if you don’t want the files that you removed to appear in the initial commit. To push those changes to the remote repo, use the <code>-f</code> option as you overwrote the initial commit.</p>
<blockquote><p>And that’s it! As you can see, setting up a package using the <a rel="noreferrer noopener" href="https://github.com/gnu-octave/pkg-example" target="_blank">new GitHub template</a> is very easy and simple.</p></blockquote>
<p></p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1682021-06-10T13:42:34+00:00<p>I am very pleased that I will be working with GNU Octave during Google summer of code for the second year in a row! This year, I will be working on the “Jupyter Notebook Integration” project.</p>
<p>The <a rel="noreferrer noopener" href="https://jupyter.org" target="_blank">Jupyter Notebook</a> is an open-source web application that allows you to create and share documents that contain live code, MathJax-rendered equations, visualizations, and narrative text. To interactively work with Octave code within Jupyter Notebooks, there already exists an <a href="https://github.com/Calysto/octave_kernel" target="_blank" rel="noreferrer noopener">Octave kernel for Jupyter</a>.</p>
<p>This project aims to support the opposite direction: running (and filling) Jupyter Notebook within GNU Octave. This would enable Jupyter Notebook users to evaluate long-running Octave Notebooks on a computing server without a permanent browser connection, which is <a href="https://github.com/jupyter/notebook/issues/1647" target="_blank" rel="noreferrer noopener">still a pending issue</a>.</p>
<p>There are some changes in my timeline as the schedule of my final exams changed. This how the timeline looks now:</p>
<p class="has-text-align-center"><img /></p>
<p>I’m looking forward to a fruitful and fun summer with GNU Octave.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comManage ImageJ update site on localhost with gittag:carandraug.net,2021-01-22:/posts/2021/2021-01-22-imagej-update-site-localhost.html2021-01-22T00:00:00+00:00<div class="section" id="summary">
<h2>Summary</h2>
<p>I've discovered that one can use the <tt class="docutils literal">file:</tt> "protocol" to manage
ImageJ update sites that are actually a git repository on the local
filesystem. This means that I can then have the update site <em>pull</em>
the changes from somewhere rather than have ImageJ <em>push</em> the changes
to the remote update site. This reduces the need for direct access to
the server with the overall goal being automating its deployment.</p>
</div>
<div class="section" id="why">
<h2>Why?</h2>
<p>To make a new release of <a class="reference external" href="https://www.micron.ox.ac.uk/software/SIMcheck/">SIMcheck</a>, an ImageJ plugin,
I do the following dance:</p>
<ol class="arabic simple">
<li>build new release of SIMcheck;</li>
<li>install it on a fresh local copy of Fiji;</li>
<li>use the ImageJ updater to update the remote update site.</li>
</ol>
<p>While most projects have their update site on <a class="reference external" href="https://sites.imagej.net/">sites.imagej.net</a>, we host the SIMcheck update site on
one of our own servers — the Micron downloads site — together with
some mirrors for other ImageJ update sites. I like to own my
infrastructure and I like it distributed <a class="footnote-reference" href="https://carandraug.net/feeds/atom.xml#id2" id="id1">[1]</a>.</p>
<p>Anyway, I was never very happy with step 3 of this dance, namely the
part where ImageJ pushes changes directly to the public website. This
is in large part because I'm not happy with our the current setup. I
don't like having to access the downloads server to upload files. I
would much rather have them somewhere else and then configure the
server to fetch/mount the files from that somewhere else. I also want
to have the downloads site under version control and integrity checks.
My plan is to use <a class="reference external" href="https://git-annex.branchable.com/">git-annex</a>
but there's always a lot of work to do and since infrastructure work
is never urgent it never gets done.</p>
</div>
<div class="section" id="how">
<h2>How?</h2>
<p>While restructuring our servers is not going to happen overnight, I'm
doing it one step at a time. For starters, I created a git repository
with the <a class="reference external" href="https://github.com/MicronOxford/SIMcheck-update-site">SIMcheck update site</a>. The plan
now is to set up the downloads site to serve that git repository and
only have to specify the git hash to deploy on the ansible playbook.</p>
<p>But the ImageJ updater only makes changes on remote servers. From its
<a class="reference external" href="https://imagej.net/How_to_set_up_and_populate_an_update_site">"documentation"</a>:</p>
<blockquote>
If you have an own server or web space with WebDAV, SFTP or SSH
access, you can create a directory in that web space and
initialize it as an update site, too.</blockquote>
<p>I could set one of those services locally but seems too much work when
the things are already local. So despite the documentation I tried to
use <tt class="docutils literal">file:</tt> as "host" and it worked just fine. This is how it looks
like on the ImageJ update site manager:</p>
<img alt="How the configuration looks like on the ImageJ update site manager." src="https://carandraug.net/files/simcheck-local-update-site.png" />
<p>So my dance now is as follow:</p>
<ol class="arabic simple">
<li>download a fresh copy of ImageJ;</li>
<li>configure the updater with a SIMcheck update site that is the local
git clone;</li>
<li>install new version of SIMcheck;</li>
<li>update the SIMcheck update site (local git clone) with the new
version with the ImageJ updater;</li>
<li>commit and push the changes to the SIMcheck update site;</li>
<li>pull the changes on the public server.</li>
</ol>
<p>Which at the command line, roughly translate into:</p>
<pre class="literal-block">
$ wget https://downloads.imagej.net/fiji/latest/fiji-linux64.zip
$ unzip fiji-linux64.zip
$ cd Fiji.app
$ ./ImageJ-linux64 --update update
$ ./ImageJ-linux64 --update add-update-site SIMcheck-local \
file:/home/carandraug/src/SIMcheck-update-site/ \
file: \
/home/carandraug/src/SIMcheck-update-site/
$ ./ImageJ-linux64 --update update
$ mv PATH-TO-SIMCheck-REPO/target/SIMcheck_-1.3.jar plugins/
$ rm plugins/SIMcheck_-1.2.jar
$ ./ImageJ-linux64 --update upload \
--update-site SIMcheck-local \
plugins/SIMcheck_-1.3.jar
$ cd ~/src/SIMcheck-update-site
$ git add plugins/SIMcheck_-1.3.jar-20210121203119
$ git add db.xml.gz
$ git commit -m "SIMcheck release 1.3"
</pre>
</div>
<div class="section" id="future-ideas">
<h2>Future Ideas</h2>
<p>I think it might be interesting to have something like this for
automating releases. An automation server can be triggered to build
new releases and push them to a git repository for each update site.
A site that serves those update sites can be configured to pull and
serve a specific commit for each update site.</p>
<table class="docutils footnote" frame="void" id="id2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="https://carandraug.net/feeds/atom.xml#id1">[1]</a></td><td>It's not only me. The ImageJ project itself seems interested
in having mirrors of its resources. If you can set a mirror,
checkout the image.sc thread <a class="reference external" href="https://forum.image.sc/t/who-can-mirror-imagej-online-resources/42451">Who can mirror ImageJ online
resources?</a></td></tr>
</tbody>
</table>
</div>David Miguel Susano Pintohttps://carandraug.net/abdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1512020-08-28T12:25:12+00:00<p>Hello there. In this blog post, I will describe my work with <a href="https://www.gnu.org/software/octave/">GNU Octave</a> during <a href="https://summerofcode.withgoogle.com/">Google summer of code</a> 2020. I will also add links to the commits I have made and repositories I have worked on. Let’s get started.</p>
<h3>About my project</h3>
<p>JavaScript Object Notation, in short JSON, is a very common human readable and structured data format. My project aims to provide GNU Octave with a builtin support for that data format.</p>
<p>Specifically, My project provides GNU Octave with two functions:</p>
<ul><li><code>jsondecode</code>: This function decodes JSON-formatted strings into Octave objects.</li><li><code>jsonencode</code>: This function encodes Octave objects into JSON-formatted strings.</li></ul>
<p>Having JSON support, Octave can improve for example its web service functions, which often exchange JSON data these days.</p>
<h3>My contribution to GNU Octave during GSoC</h3>
<p>For the past few months, I’ve been working with my mentors on my project. This work resulted in the following commits that were pushed into <a href="https://hg.savannah.gnu.org/hgweb/octave/">the main repository of Octave</a>:</p>
<ul><li><a href="https://hg.savannah.gnu.org/hgweb/octave/rev/5da49e37a6c9">5da49e37a6c9</a>: This commit contains nearly all of my work during GSoC. It adds the functions <code>jsonencode</code> and <code>jsondecode</code> to GNU Octave.</li><li><a href="https://hg.savannah.gnu.org/hgweb/octave/rev/aae9d7f098bd">aae9d7f098bd</a>: This commit improves the integration of the functions into Octave’s build system.</li><li><a href="https://hg.savannah.gnu.org/hgweb/octave/rev/34696240591e">34696240591e</a>: This commit improves the documentation of the functions.</li><li><a href="https://hg.savannah.gnu.org/hgweb/octave/rev/0da2fbd3a642">0da2fbd3a642</a>: This commit improves the documentation of the functions.</li><li><a href="https://hg.savannah.gnu.org/hgweb/octave/rev/174550af014f">174550af014f</a>: This commit adds more tests and improves the documentation of the functions.</li></ul>
<p>Those commits contain:</p>
<ul><li>The code of the two functions.</li><li>Unit tests.</li><li>Documentation (Doxygen documentation for the developers and Texinfo documentation for the users).</li><li>Code to add the new functions to the build system.</li></ul>
<p>I was working on this <a href="https://github.com/Abdallah-Elshamy/Octave-GSoC-JSON">stand-alone repository</a> then at the final stages of GSoC, The code was moved to <a href="https://github.com/abdallah-elshamy/octave">my fork</a> of the <a href="https://github.com/mtmiller/octave">Octave mirror on GitHub</a>.</p>
<h3>How to use my project</h3>
<p>As I said before, my project is already pushed to <a href="https://hg.savannah.gnu.org/hgweb/octave/">the main repository of Octave</a>. To use it, all you have to do is to build the default branch of Octave. This <a href="https://wiki.octave.org/Building">article</a> shows how to do this.</p>
<h3>What to do after GSoC</h3>
<p>A <a href="https://siko1056.github.io/blog/2020/08/19/gsoc2020-json-benchmark.html">benchmark</a> was implemented by <a href="https://github.com/siko1056">my mentor</a> to assess the performance of the functions. The benchmark results showed that <code>jsondecode</code> has some performance issues. After some investigations, we were able to pinpoint what slows the performance which is <code>makeValidName</code> function. This function is written in Octave scripting language which is much slower than C++. So, I am going to rewrite the core of this function in C++ and make the m-file of <code>makeValidName</code> call it. This will definitely improve the performance of <code>jsondecode</code>.</p>
<p>Finally, I would like to say that I really had a wonderful experience during Google Summer of Code 2020 with GNU Octave and I am looking forward to contribute more in the future. Also, I would like to thank:</p>
<ul><li>The team of the Google Summer of Code program for supporting such an amazing experience.</li><li>The community of GNU Octave for helping me during this wonderful journey.</li><li><a href="https://summerofcode.withgoogle.com/projects/#6263027378159616">My co-mentors and my mentor</a> for providing me with continuous support and help that facilitated my work a lot. It has been my pleasure to get to know you.</li></ul>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1412020-08-13T23:06:22+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>My mentors and I are glad to announce that an initial change set has been pushed to the main repository of Octave <a href="https://hg.savannah.gnu.org/hgweb/octave/rev/5da49e37a6c9">here</a>. We are waiting for your feedback. (Note: you must have the development version of <code>RapidJSON</code>.)</li></ul>
<h6>What I intend to do</h6>
<ul><li>Disable the <code>PrettyWritter</code> feature if the release version of <code>RapidJSON</code> is used instead of disabling the two functions.</li><li>Add docstrings to interpreter manual.</li><li>Move the function <code>equals</code> to <code>string_vector</code> class.</li></ul>
<p></p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1372020-08-06T19:32:28+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>I finished writing <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank">jsonencode</a> function in the <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/Octave-GSoC-JSON" target="_blank">new “standalone” repository</a>. The function now passes all the 64 tests in the test suite. The function now encodes:<ul><li>logical scalar</li><li>NaN, Inf and -Inf</li><li>numeric scalar</li><li>containers.Map</li><li>Structure scalar</li><li>Structure array</li><li>Cell scalar</li><li>Cell array</li><li>numeric array</li><li>logical array</li><li>character vector</li><li>character array</li></ul></li></ul>
<h6>How to compile and run tests on the code</h6>
<p>Right now, the code is treated as an external *.oct file. The integration of the code into Octave’s build system will be done at the end of the project. To compile it:</p>
<ul><li><code>cd</code> into the repo’s directory.</li><li>run <code>mkoctfile</code> command using the file name (eg. jsonencode.cc) as an argument.</li></ul>
<p>Octave test files are provided for each function. For example, you can run the one that tests <code>jsonencode</code> by running this command:</p>
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
test('test/jsonencodetest.m','quiet','test/log-jsonencode.txt')
</pre></div>
<p>The log file “log-jsonencode.txt” in “test” in your repo’s directory will have the data of the failed tests.</p>
<h6>What I intend to do</h6>
<ul><li>Write the documentation of both functions.</li><li>Integrate the test suite with the code (the test suite is already converted into Octave BIST)</li><li>Start integrating the functions with Octave’s code base. </li></ul>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1312020-07-24T18:13:09+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>I started writing <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank">jsonencode</a> function in the <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/Octave-GSoC-JSON" target="_blank">new “standalone” repository</a>. The function now passes 28 out of 42 tests in the test suite. The function now encodes:<ul><li>logical scalar</li><li>NaN, Inf and -Inf</li><li>numeric scalar</li><li>containers.Map</li><li>Structure scalar</li><li>Structure array</li><li>Cell scalar</li><li>Cell array</li></ul></li></ul>
<h6>How to compile and run tests on the code</h6>
<p>Right now, the code is treated as an external *.oct file. The integration of the code into Octave’s build system will be done at the end of the project. To compile it:</p>
<ul><li><code>cd</code> into the repo’s directory.</li><li>run <code>mkoctfile</code> command using the file name (eg. jsonencode.cc) as an argument.</li></ul>
<p>Octave test files are provided for each function. For example, you can run the one that tests <code>jsonencode</code> by running this command:</p>
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
test('test/jsonencodetest.m','quiet','test/log-jsonencode.txt')
</pre></div>
<p>The log file “log-jsonencode.txt” in “test” in your repo’s directory will have the data of the failed tests.</p>
<h6>What I intend to do</h6>
<ul><li>Finish writing <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank">jsonencode</a>.</li></ul>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1242020-07-18T18:55:27+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>Added the <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/octave/issues/5" target="_blank">“ReplacementStyle” and “Prefix”</a> options for <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a> function.</li><li>Extended the <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/Octave-GSoC-JSON/blob/json/test/jsondecodetest.m" target="_blank">test suite</a> for <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a>.</li><li>Added Doxygen comments to the internal functions of <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a>.</li><li>Made some modifications in <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a> functions after taking feedback from my mentors.</li><li>Made a <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/Octave-GSoC-JSON" target="_blank">new “standalone” repository</a> to facilitate communication and moved my commits and the issues from the old repo to the new repo as I think it is better to preserve the history of the commits. This is how I moved the files with commits: <ul><li>I made a clone of the json branch in my <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/octave" target="_blank">Octave’s repository</a>.</li><li>I checked through the history and files and used an “index-filter” to remove everything except the files I want. What remained in my clone after that was just some directories that contain only my files. Here is the command I used:</li></ul></li></ul>
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- test/json libinterp/corefcn/jsondecode.cc libinterp/corefcn/jsonencode.cc ' --prune-empty -- --all
</pre></div>
<p>After that, I just moved the files to the desired directories in the new repo and committed the changes.</p>
<h6>How to compile and run tests on the code</h6>
<p>Right now, the code is treated as an external *.oct file. The integration of the code into Octave’s build system will be done at the end of the project. To compile it:</p>
<ul><li><code>cd</code> into the repo’s directory.</li><li>run <code>mkoctfile</code> command using the file name (eg. jsondecode.cc) as an argument.</li></ul>
<p>Octave test files are provided for each function. For example, you can run the one that tests <code>jsondecode</code> by running this command:</p>
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
test('test/jsondecodetest.m','quiet','test/log-jsondecode.txt')
</pre></div>
<p>The log file “log-jsondecode.txt” in “test” in your repo’s directory will have the data of the failed tests.</p>
<h6>What I intend to do</h6>
<ul><li>Start writing <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank">jsonencode</a>.</li></ul>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1202020-07-09T22:00:04+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>I finished writing <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a> function on my <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/octave/blob/json/libinterp/corefcn/jsondecode.cc" target="_blank">repository</a>. The function now passes all the tests in the test suite. The function now decodes: <ul><li>null values in non-numeric arrays</li><li>null values in numeric arrays</li><li>Boolean values</li><li>Numeric values</li><li>String values</li><li>Array of booleans</li><li>Array of numbers</li><li>Array of strings</li><li>JSON objects</li><li>Array of objects — Same field names</li><li>Array of objects — Different field names</li><li>Array — elements that are of different data types</li></ul></li></ul>
<h6>How to compile and run tests on the code</h6>
<p>Right now, the code is treated as an external *.oct file. The integration of the code into Octave’s build system will be done at the end of the project. This is how to compile it:</p>
<ul><li>“cd” into “libinterp/corefcn” in your Octave’s code base directory</li><li>run “mkoctfile” command using the file name (jsondecode.cc) as an argument</li></ul>
<p>Octave test files are provided for each function. You can run the one that tests jsondecode in the “libinterp/corefcn” directory by running this command:</p>
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
test('../../test/json/jsondecodetest.m','quiet','../../test/json/log.txt')
</pre></div>
<p>The log file “log.txt” in “test/json” in your Octave’s code base directory will have the data of the failed tests.</p>
<h6>What I intend to do</h6>
<ul><li>Add the <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/octave/issues/5" target="_blank">“ReplacementStyle” and “Prefix”</a> options for the function.</li><li>Put the final touches on <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a> function after taking feedback from the community.</li><li>Start writing <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank">jsonencode</a>.</li></ul>
<p>That’s it for this week. See you next one.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1072020-07-02T20:36:19+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>I started writing <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a> function on my <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/octave/blob/json/libinterp/corefcn/jsondecode.cc" target="_blank">repository</a>. The function now fails only 6 tests of the 31 tests in the test suite. The function now decodes: <ul><li>null values in non-numeric arrays</li><li>null values in numeric arrays</li><li>Boolean values</li><li>Numeric values</li><li>String values</li><li>Array of booleans</li><li>Array of numbers</li><li>Array of strings</li><li>JSON objects</li><li>Array of objects — Same field names</li><li>Array of objects — Different field names</li></ul></li></ul>
<h6>How to compile and run tests on the code</h6>
<p>Right now, the code is treated as an external *.oct file. The integration of the code into Octave’s build system will be done at the end of the project. This is how to compile it:</p>
<ul><li>“cd” into “libinterp/corefcn” in your Octave’s code base directory</li><li>run “mkoctfile” command using the file name (jsondecode.cc) as an argument</li></ul>
<p>Octave test files are provided for each function. You can run the one that tests jsondecode in the “libinterp/corefcn” directory by running this command:</p>
<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
test('../../test/json/jsondecodetest.m','quiet','../../test/json/log.txt')
</pre></div>
<p>The log file “log.txt” in “test/json” in your Octave’s code base directory will have the data of the failed tests.</p>
<h6>What I intend to do</h6>
<ul><li>Finish <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a> function.</li><li>Since I like to use the method of “get things done first. then enhance it”, I will start to see if there is some thing in the code that can be written better after taking feedback and re-reading the code.</li></ul>
<p>That’s it for this week. See you next one.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=1032020-06-25T20:01:43+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>I finished writing tests for <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank">jsonencode</a> function. I wrote and extracted from the previous implementations tests for the encoding of:<ul><li>Structure array</li><li>Cell scalar</li><li>Cell array </li></ul></li><li>I used those tests to assess the previous implementations to encode/decode JSON.</li><li>I detected <a rel="noreferrer noopener" href="https://octave.1599824.n4.nabble.com/JSON-decode-td4697662.html" target="_blank">the reason of failure</a> for each failed test in the previous implementations.</li><li>Some decisions about the approach we will follow was discussed in <a rel="noreferrer noopener" href="https://octave.1599824.n4.nabble.com/JSON-Test-suite-status-td4697620.html" target="_blank">the mailing list. </a></li></ul>
<h6>What I intend to do</h6>
<ul><li>Start coding <a href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank" rel="noreferrer noopener">jsondecode</a>.</li></ul>
<p>That’s it for this week. See you next one.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=992020-06-18T22:00:16+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<p>My finals started this week so there isn’t much work done. (I organized this with my mentor.)</p>
<ul><li>I started writing tests for <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank">jsonencode</a> function. I wrote and extracted from the previous implementations tests for the encoding of:<ul><li>logical scalar</li><li>NaN, Inf and -Inf</li><li>numeric scalar</li><li>numeric array</li><li>logical array</li><li>character vector</li><li>character array</li><li>containers.Map</li><li>Structure scalar</li></ul></li></ul>
<h6>What I intend to do</h6>
<ul><li>Finish writing tests for<a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank"> jsonencode</a></li><li>Running those tests on the previous implementations to assess them and their approaches.</li><li>Taking some decisions with the community and the mentors about the approach we will follow in implementing the functionality required.</li></ul>
<p>That’s it for this week. See you next one.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=952020-06-11T21:54:42+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<p>My finals started this week so there isn’t much work done. (I organized this with my mentor.)</p>
<ul><li>I finished writing tests for <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a> function. I wrote and extracted from the previous implementations tests for the decoding of:<ul><li>JSON objects</li><li>Array of objects — Same field names</li><li>Array of objects — Different field names</li><li>Array — elements are of different data types</li></ul></li></ul>
<h6>What I intend to do</h6>
<ul><li>Start writing tests for jsonencode. </li></ul>
<p>That’s it for this week. See you next one.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=822020-06-04T20:57:29+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<p>My finals started this week so there isn’t much work done. (I organized this with my mentor.)</p>
<ul><li>I made a branch in my git repository called <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/octave/tree/test-suite" target="_blank">“test-suite”</a> that I will push my tests to in the directory “octave/test/json-encode-decode”.</li><li>Since MATLAB compatibility is a core target for my project, I learned how to write <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/matlab_prog/write-script-based-unit-tests.html" target="_blank">script-based unit tests</a> in MATLAB. This will help me in writing a test suite that MATLAB can run in order to verify its compatibility.</li><li>I started writing tests for <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html" target="_blank">jsondecode</a> function. I wrote and extracted from the previous implementations tests for the decoding of:<ul><li>null values in non-numeric arrays</li><li>null values in numeric arrays</li><li>Boolean values</li><li>Number values</li><li>String values</li><li>Array of booleans</li><li>Array of numbers</li><li>Array of strings</li></ul></li></ul>
<h6>What I intend to do</h6>
<ul><li>Continue writing tests for jsondecode. </li></ul>
<p>That’s it for this week. See you next one.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=652020-05-28T20:52:46+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>I finished my experiments with <a rel="noreferrer noopener" href="http://rapidjson.org/" target="_blank">RapidJSON</a>. I also finished reading the documentation of the library. A small example I did is to make an Octave function (written in C++) that adds two JSON objects. JSON objects are a set of key-value pairs. This function accepts objects with numeric values only and adds these values if they have the same key. Else, the values remain the same. This small function serves as a good warm up before the coding period. I think this is a good warm up as it uses two important things for my project: Creating Octave functions that are written in C++ and using <a rel="noreferrer noopener" href="http://rapidjson.org/" target="_blank">RapidJSON</a> which I will use in the project. enough talking here is the code:</li></ul>
<pre class="brush: plain; title: ; notranslate">
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/error/en.h"
#include <octave/oct.h>
using namespace rapidjson;
DEFUN_DLD (addJSON, args, , "adds two JSON objects.")
{
int nargin = args.length ();
if (args.length () != 2)
print_usage ();
if (! (args(0).is_string () && args(1).is_string ()))
error ("parameters must be Character Strings");
std::string first_json = args(0).string_value ();
std::string second_json = args(1).string_value ();
Document d1;
Document d2;
d1.Parse (first_json.c_str ());
if (d1.HasParseError ())
error("(offset %u): %s\n",
(unsigned)d1.GetErrorOffset(),
GetParseError_En(d1.GetParseError()));
d2.Parse (second_json.c_str ());
if (d2.HasParseError ())
error("(offset %u): %s\n",
(unsigned)d2.GetErrorOffset(),
GetParseError_En(d2.GetParseError()));
if(! (d1.IsObject () && d2.IsObject ()))
error ("parameters must be JSON objects");
// checking that the first json object has numeric values only
for (Value::ConstMemberIterator itr = d1.MemberBegin ();
itr != d1.MemberEnd () ; ++itr)
{
if (! itr->value.IsNumber ())
error ("values must be numbers");
}
for (Value::ConstMemberIterator itr = d2.MemberBegin ();
itr != d2.MemberEnd () ; ++itr)
{
if (! itr->value.IsNumber ())
error ("values must be numbers");
if (d1.HasMember (itr->name.GetString ()))
{
Value& s = d1[itr->name.GetString ()];
if (s.IsDouble () || itr->value.IsDouble ())
s.SetDouble(s.GetDouble() + itr->value.GetDouble ());
else
s.SetInt(s.GetInt () + itr->value.GetInt ());
}
else
{
Value key(itr->name.GetString (), d1.GetAllocator ());
Value value (itr->value, d1.GetAllocator ());
d1.AddMember (key, value, d1.GetAllocator ());
}
}
StringBuffer buffer;
Writer<StringBuffer> writer (buffer);
d1.Accept (writer);
return octave_value (buffer.GetString());
}
</pre>
<ul><li>I discovered this cool Octave command __run_test_suite__. This command runs the complete test suite of Octave (the one that gets run at the end of make check.) This is very useful for regression testing.</li><li>I also prepared my check list for the test suite. My goal here is to make the test suite covers all the conversion cases that <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsonencode.html" target="_blank">jsonencode</a> and <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html#d120e674315" target="_blank">jsondecode</a> cover in the official documentation of MATLAB (E.g. from boolean JSON data type to scalar logical) so my check list is simply the conversions listed at the end of the documentation of both functions (posting them here will overpopulate the post.)</li></ul>
<h6>Timeline and Milestones</h6>
<p>Since the coding will start next week. This is a good time to show you my plan for the project. Those are my milestones:</p>
<ul><li>26/6: Deliver test suite (first evaluation period starts on 29/6)</li><li>20/7: Deliver jsondecode (second evaluation period starts on 27/7)</li><li>05/8: Deliver jsonencode (final week starts on 24/8)</li></ul>
<p>Here is my timeline:</p>
<table><tbody><tr><td><strong>From-To</strong></td><td><strong>Duration</strong></td><td><strong>Task</strong></td><td><strong>Hours/Week</strong></td></tr><tr><td>01/6 – 21/6* (final exams)</td><td>20 days</td><td>Preparing the test suite</td><td>7-10</td></tr><tr><td>21/6 – 03/7</td><td>12 days</td><td>Finalizing the test suite, running tests on the libraries and Creating reliable figures.</td><td>40-45</td></tr><tr><td>03/7 – 06/7</td><td>3 days</td><td>Analyzing results and taking design decisions with the mentors.</td><td>40-45</td></tr><tr><td>06/7 – 18/7</td><td>12 days</td><td>Implementing jsondecode</td><td>40-45</td></tr><tr><td>18/7 – 20/7</td><td>2 days</td><td>Buffering</td><td>40-45</td></tr><tr><td>20/7 – 03/8</td><td>14 days</td><td>Implementing jsonencode</td><td>40-45</td></tr><tr><td>03/8 – 07/8</td><td>4 days</td><td>Buffering & Documenting </td><td>40-45</td></tr><tr><td>07/8 – 12/8</td><td>5 days</td><td>Converting the test suite to Octave BIST</td><td>40-45</td></tr><tr><td>12/8 – 17/8</td><td>5 days</td><td>Cleaning the code and preparing the patch</td><td>40-45</td></tr><tr><td>17/8 – 31/8</td><td>14 days</td><td>Perfecting the patch with the community feedback.</td><td>40-45</td></tr></tbody></table>My timeline
<h6>What I intend to do</h6>
<ul><li>Start coding the tests for <a rel="noreferrer noopener" href="https://www.mathworks.com/help/matlab/ref/jsondecode.html#d120e674315" target="_blank">jsondecode</a>.</li></ul>
<p>That’s it for this week. See you next one.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=562020-05-21T21:18:36+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>I finished my experiments with Oct-Files by working with a simple example that makes some checks on the input , generates some errors and manipulates a struct inside the function.</li><li>I refreshed my knowledge on shell scripting using this <a rel="noreferrer noopener" href="https://www.shellscript.sh" target="_blank">tutorial</a>, Here is some useful info:<ul><li>grep -r : This option is used to recursively search for a pattern. This was useful for me as it showed me where is the macro <a rel="noreferrer noopener" href="https://hg.savannah.gnu.org/hgweb/octave/file/70908e5d8865/m4/acinclude.m4#l414" target="_blank">OCTAVE_CHECK_LIB</a> so I can know its job.</li><li>which : An awesome feature of Octave that it implements its own version of “which” command. “which” command in Octave shows the file that contains a specific function.</li><li>A cool best practice I learned is using the backtick to improve performance if you want to run a set of commands and parse various bits of its output:</li></ul></li></ul>
<div class="wp-block-group alignfull"><div class="wp-block-group__inner-container">
<pre class="wp-block-preformatted">find / -name "*.html" -print | grep "/index.html$"
find / -name "*.html" -print | grep "/contents.html$"
This code could take a long time to run, and we are doing it twice!
A better solution is:
HTML_FILES=`find / -name "*.html" -print`
echo "$HTML_FILES" | grep "/index.html$"
echo "$HTML_FILES" | grep "/contents.html$"</pre>
</div></div>
<ul><li>I got more familiar with GNU Autotools.</li><li>I started reading about and experimenting with <a rel="noreferrer noopener" href="http://rapidjson.org/" target="_blank">RapidJSON</a> library.</li></ul>
<h6>What I intend to do</h6>
<ul><li>Extend configure.ac file to check for <a rel="noreferrer noopener" href="http://rapidjson.org/" target="_blank">RapidJSON</a> after some <a href="https://octave.1599824.n4.nabble.com/Extending-configure-ac-td4697219.html" target="_blank" rel="noreferrer noopener">discussions</a> on the mailing list about which macros to use and some build options.</li><li>Finish my experiments with <a rel="noreferrer noopener" href="http://rapidjson.org/" target="_blank">RapidJSON</a>.</li><li>Describe in details the parts of the test suite.</li><li>Find out how to do regression testing.</li></ul>
<p>That’s it for this week. See you next one.</p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comabdallahkelshamyhttp://abdallahshamy.wordpress.com/?p=442020-05-14T21:39:11+00:00<p>Hello there, this is my weekly report about my work. In this report, I will show what I did this past week. I will also show what I intend to do in the next week. let’s get started.</p>
<h6>That’s what is done</h6>
<ul><li>I read GSoC student guide.</li><li>I set up my public blog.</li><li>I will be using the <a rel="noreferrer noopener" href="https://github.com/mtmiller/octave" target="_blank">GitHub mirror of Octave</a> instead of using a mercurial repo so, I set up <a rel="noreferrer noopener" href="https://github.com/Abdallah-Elshamy/octave" target="_blank">my public repo</a> and prepared my local environment.</li><li>The decision on how to add <a rel="noreferrer noopener" href="http://rapidjson.org/" target="_blank">RapidJSON</a> library to Octave was discussed and made on the mailing list.</li><li>I started reading about and experimenting with Oct-Files to get familiar with the code base.</li></ul>
<h6>What I intend to do</h6>
<ul><li>Get more familiar with GNU Autotools.</li><li>Extend configure.ac file to check for <a rel="noreferrer noopener" href="http://rapidjson.org/" target="_blank">RapidJSON</a>.</li><li>Getting familiar with <a rel="noreferrer noopener" href="http://rapidjson.org/" target="_blank">RapidJSON</a>. </li><li>Finish my experiments with Oct-Files.</li></ul>
<p>That’s it for this week. See you next one.</p>
<p> </p>Abdallah Khaled Elshamyhttps://abdallahshamy.wordpress.comOctave in GSoC 2020http://epigrammar.wordpress.com/?p=262020-02-20T21:55:40+00:00<p><a href="https://summerofcode.withgoogle.com/organizations/4930645207285760/">Octave</a> is a mentor organization for <a href="https://summerofcode.withgoogle.com/">Google Summer of Code</a> this year. Applications from students are due by March 31. See the <a href="https://wiki.octave.org/Summer_of_Code_-_Getting_Started">Octave wiki</a> for tips on applying.</p>Nirhttps://epigrammar.wordpress.comGoogle Summer of Code 2019: Call for Codershttp://epigrammar.wordpress.com/?p=242019-03-04T15:35:16+00:00<p>Octave is in <a href="https://summerofcode.withgoogle.com/organizations/?sp-page=4#5389784319524864">GSoC</a> this year, for our fifth time as an independent organization!</p>
<p>Student applications for the paid summer internships are due <a href="https://summerofcode.withgoogle.com/how-it-works/">9 April</a>.</p>
<p>Check out the <a href="https://wiki.octave.org/Summer_of_Code_Project_Ideas">Wiki</a> for potential projects and application instructions.</p>Nirhttps://epigrammar.wordpress.comExercising software freedom on Firefoxhttp://jordi.inversethought.com/?p=4902019-02-24T18:07:31+00:00<p>I’m a little unusual. I use Emacs.</p>
<p>That alone is unusual. But I get the impression that even amongst Emacs users, I’m in the minority in another way: I use the default keybindings. I love them. A lot of new Emacs users seem to insist on jamming vim keys into Emacs, but not me. These are my friends: C-p C-n C-f C-b C-a C-e C-k; down up left right start end kill.</p>
<p>I’m so gung-ho about Emacs keybindings that I made them the default keybinding of GTK+, which means that any application that uses GTK+ will respect Emacs keybindings for motion. They also work in anything that uses readline or readline-like input, like bash, python, or psql (postgresql’s default CLI client). Being used to Emacs keys has paid off for me. I have a consistent interface across the software that matters to me.</p>
<p>I’m becoming a minority in another way: I use Firefox. And Firefox uses GTK+. That means I can use Emacs keybindings in Firefox.</p>
<p>Ah, but there’s a rub. Firefox binds C-n (or as most people would call it, “ctrl-n”) to new window. This is probably okay for people who don’t have the intersectionality of Emacs keybindings everywhere and Firefox. But for me, it’s intolerable. If I want to move a cursor down, I have to instead perform a very unnatural-feeling motion of moving my right hand to the arrow keys and hit the arrow down button. For those accostumed to using arrow keys, imagine if every time you pressed the down arrow Firefox would open a new window. Imagine software reacting so at odds to your habituation.</p>
<p>Up until Firefox 56 there was an easy workaround. You could download extensions that would let you configure Firefox’s keyboard shorcuts, including disable some of them. I used to do this. The world, however, marches on and so does Firefox. Many extensions cannot do what they once did and the easy fix was gone.</p>
<p>I tried to cope, for a while. After all, it’s just one key. I can still use the arrow keys. I tried.</p>
<p>But no. It wouldn’t work. I couldn’t help myself. I often wanted to move the cursor down three or four rows and would accidentally open up three or four new windows. It was even worse because I could move in every other direction and it all felt natural, but if I made the mistake of going down, the software would react in the wrong way. Everything else did it right except Firefox. And one day, I had enough.</p>
<h1>Software Freedom</h1>
<p>Enough was enough. I had accidentally opened a new window for the last time. I want to go <em>down</em>, you donut! And you won’t stop me anymore!</p>
<a href="http://jordi.inversethought.com/wp-content/uploads/2019/02/freedom.jpg"><img src="http://jordi.inversethought.com/wp-content/uploads/2019/02/freedom.jpg" alt="Freedom" width="413" height="479" class="size-full wp-image-495" /></a>FREEDOMMM!
<p>I had the motivation. I have some skill. We can rebuild Firefox. Make it better. More consistent. We have the technology.</p>
<p>I didn’t want to <a href="https://us.pycon.org/2015/schedule/presentation/381/">get involved in Firefox’s build drama</a>, though. I didn’t want to figure out how to clone its repo, how to setup a development environment, how to configure the build, what kinds of builds there are, and how to integrate all of this with my operating system. Luckily, someone else has already done all of this work for me: the Debian packagers.</p>
<p>A Debian package knows what dependencies are required to build a package and has all of the tooling ready to build that package and make it fit exactly with my operating system. Right system libraries, right compilation options, everything. I know how to build Debian packages:</p>
<ol>
<li>Get the source (<code class="codecolorer bash solarized-light"><span class="bash"><span>apt-get <span>source</span></span> <span>$packagename</span></span></code>)</li>
<li>Get the dependencies (<code class="codecolorer bash solarized-light"><span class="bash"><span>sudo</span> apt build-dep <span>$packagename</span></span></code>)</li>
<li>Build the package (<code class="codecolorer bash solarized-light"><span class="bash">dpkg-buildpackage</span></code>)</li>
</ol>
<p>Easy enough.</p>
<h1>Firefox, the behemoth</h1>
<p>As I started following the steps above, something was immediately evident. Firefox is <em>huge</em>. Enormous. Gargantuan. The biggest codebase I have ever seen. At a glance I saw a mix of Python, C++, Rust, and XML which I later came to recognise as XUL (“XUL?” I hear you ask. Yes. XUL. More on this below.) I can see why few dare tread in here.</p>
<p>I, on the other hand, with my motivation going strong, felt undaunted. I would tame The Beast of oxidised metal.</p>
<p>But I wouldn’t do it alone. I know that the Mozilla project still has a fairly active IRC network over at <a href="irc://irc.mozilla.org">irc.mozilla.org</a>, so I headed down that way. I started talking about my problem, asking for advice. While I waited for replies, I tried to do it on my own. I figured, GTK+, keybindings, C. I was looking for some C or C++ source file that would define the GTK+ keybindings. I would find this file and destroy the keybinding. I have done something similar in the past for other GTK+ programs.</p>
<p>My solo search proved unfruitful. I couldn’t find anything about new window in C++ source files. I even tried the Rust files, maybe they’ve done something there, but again nothing. My grepping did find new window commands in XML files, but I figured that couldn’t still be of use. Everyone knows it, it’s all over the software news: Firefox disabled XUL as part of its move to a Rust engine.</p>
<p>In the meantime, helpful people from IRC pushed me along my quest and pointed me in the right direction. Yes, XUL is all I needed.</p>
<h1>There is no Rust. There is only XUL!</h1>
<p>Yep! Firefox has been lying to us! It’s still all XUL. All they’ve disabled is the external interface for extensions, but under the hood, Firefox is still the XUL mess it always was. They say they’re ripping it out, yet the process seems slow.</p>
<p>So I followed the advice. I changed a single XML file. I built the Debian package. I was expecting a long compilation time and I got it. I was worried I wouldn’t have enough RAM for the build, but looks like 16 gigabytes with four cores (Thinkpad X1 Carbon 5th gen) was enough. People in IRC reassured me that it would take about two hours. They were right! Two hours later, I had a new Firefox in a neat little Debian package. I installed it (<code class="codecolorer bash solarized-light"><span class="bash"><span>dpkg</span> <span>-i</span> <span>*</span>.deb</span></code>) eager to see the results and…</p>
<p>XML parsing error. Undefined entity.</p>
<p>Oh no! I had made a mistake! All I could do was close this error window. Firefox just wouldn’t start.</p>
<p>However, this confirmed two things. One, the XUL really is still being used. In fact, it’s so important that Firefox won’t even start if you get it wrong. And two… I was on the right track. Modifying XUL could very well get me to my goal of disabling one key.</p>
<p>The error window reminded me a lot of similar errors I had seen in the past when XUL was available to 3rd party extension authors. It seems that not as much as advertised has changed.</p>
<p><a href="https://support.mozilla.org/en-US/questions/1191547"><img src="http://jordi.inversethought.com/wp-content/uploads/2019/02/2017-12-02-05-01-02-1fd406.png" alt="Bad XUL" width="865" height="330" class="size-full wp-image-498" />XUL parsing error</a></p>
<p>I tried again. I had removed the key but I hadn’t removed a few references to that key. Another build. Another two hours. In the meantime, Mozilla employees and enthusiasts in IRC kept asking me if I was doing an artifact build. I said no, that I wanted to learn as little as possible about Firefox’s build process. Turns out that an artifact build is an interesting thing where <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Artifact_builds">you download pre-built Firefox components</a> and the build just puts them together, greatly reducing the compilation times.</p>
<p>I had the very specific goals of building a Debian package and not wanting to get too involved in build drama, so I politely refused the suggestions of artifact builds.</p>
<p>I just want my cursor to move down, man.</p>
<p>My second try also didn’t work. I had neglected one further reference to the new window key. I didn’t think it was necessary, but the XML again failed to parse because the key for undoing closing a window is defined in terms of the key for opening a new window. I decided that if I wasn’t going to be opening new windows, I also wasn’t going to undo close them, so I also deleted this reference.</p>
<p>By now it was getting late, I had to sleep, and I couldn’t wait for another two-hour build. I made the change, started the build, and went to bed like a kid excited for Christmas morning.</p>
<h1>Free at last!</h1>
<p>The morning came. My new build was ready. I installed the third Debian package I built.</p>
<p>This time Firefox started. No more XML errors.</p>
<p>Could it be…?</p>
<p>I went to the first website I could think of that had a textarea element I could try to type in, <a href="https://paste.debian.net">paste.debian.net</a>.</p>
<p>I typed some text. I hit enter a few times. I pressed C-p to go back up.</p>
<p>The moment of truth!</p>
<p>I hit C-n.</p>
<p>No new window.</p>
<p>The cursor moved down.</p>
<p>YES!!</p>
<a href="http://jordi.inversethought.com/wp-content/uploads/2019/02/SvvJx34.jpg"><img src="http://jordi.inversethought.com/wp-content/uploads/2019/02/SvvJx34.jpg" alt="Victoly!" width="918" height="610" class="size-full wp-image-499" /></a>Great success!
<h1>The patch</h1>
<p>So here’s the patch, for anyone else who wants it. I made it against ESR (currently Firefox 60) because that’s what’s packaged for Debian stable, but all of these modified files are still there in the current Mercurial repository I just checked right now.</p>
<ul>
<li><a href="https://hg.mozilla.org/mozilla-central/file/1cacb0b1fe7b/browser/base/content/browser-menubar.inc">browser/base/content/browser-menubar.inc</a></li>
<li><a href="https://hg.mozilla.org/mozilla-central/file/1cacb0b1fe7b/browser/base/content/browser-sets.inc">browser/base/content/browser-sets.inc</a></li>
<li><a href="https://hg.mozilla.org/mozilla-central/file/1cacb0b1fe7b/browser/components/customizableui/content/panelUI.inc.xul">browser/components/customizableui/content/panelUI.inc.xul</a></li>
<li><a href="https://hg.mozilla.org/mozilla-central/file/1cacb0b1fe7b/browser/locales/en-US/chrome/browser/browser.dtd">browser/locales/en-US/chrome/browser/browser.dtd</a></li>
</ul>
<div class="codecolorer-container diff solarized-light"><div class="diff codecolorer">diff --git a/firefox-esr-60.5.1esr/browser/base/content/browser-menubar.inc b/firefox-esr-60.5.1esr/browser/base/content/browser-menubar.inc<br />
<span>--- a/firefox-esr-60.5.1esr/browser/base/content/browser-menubar.inc</span><br />
<span>+++ b/firefox-esr-60.5.1esr/browser/base/content/browser-menubar.inc</span><br />
<span>@@ -27,7 +27,6 @@</span><br />
<menuitem id="menu_newNavigator"<br />
label="&newNavigatorCmd.label;"<br />
accesskey="&newNavigatorCmd.accesskey;"<br />
<span>- key="key_newNavigator"</span><br />
command="cmd_newNavigator"/><br />
<menuitem id="menu_newPrivateWindow"<br />
label="&newPrivateWindow.label;"<br />
diff --git a/firefox-esr-60.5.1esr/browser/base/content/browser-sets.inc b/firefox-esr-60.5.1esr/browser/base/content/browser-sets.inc<br />
<span>--- a/firefox-esr-60.5.1esr/browser/base/content/browser-sets.inc</span><br />
<span>+++ b/firefox-esr-60.5.1esr/browser/base/content/browser-sets.inc</span><br />
<span>@@ -196,10 +196,6 @@</span><br />
</broadcasterset><br />
<br />
<keyset id="mainKeyset"><br />
<span>- <key id="key_newNavigator"</span><br />
<span>- key="&newNavigatorCmd.key;"</span><br />
<span>- command="cmd_newNavigator"</span><br />
<span>- modifiers="accel" reserved="true"/></span><br />
<key id="key_newNavigatorTab" key="&tabCmd.commandkey;" modifiers="accel"<br />
command="cmd_newNavigatorTabNoEvent" reserved="true"/><br />
<key id="focusURLBar" key="&openCmd.commandkey;" command="Browser:OpenLocation"<br />
<span>@@ -378,7 +374,6 @@</span><br />
#ifdef FULL_BROWSER_WINDOW<br />
<key id="key_undoCloseTab" command="History:UndoCloseTab" key="&tabCmd.commandkey;" modifiers="accel,shift"/><br />
#endif<br />
<span>- <key id="key_undoCloseWindow" command="History:UndoCloseWindow" key="&newNavigatorCmd.key;" modifiers="accel,shift"/></span><br />
<br />
#ifdef XP_GNOME<br />
#define NUM_SELECT_TAB_MODIFIER alt<br />
diff --git a/firefox-esr-60.5.1esr/browser/components/customizableui/content/panelUI.inc.xul b/firefox-esr-60.5.1esr/browser/components/customizableui/content/panelUI.inc.xul<br />
<span>--- a/firefox-esr-60.5.1esr/browser/components/customizableui/content/panelUI.inc.xul</span><br />
<span>+++ b/firefox-esr-60.5.1esr/browser/components/customizableui/content/panelUI.inc.xul</span><br />
<span>@@ -205,7 +205,6 @@</span><br />
<toolbarbutton id="appMenu-new-window-button"<br />
class="subviewbutton subviewbutton-iconic"<br />
label="&newNavigatorCmd.label;"<br />
<span>- key="key_newNavigator"</span><br />
command="cmd_newNavigator"/><br />
<toolbarbutton id="appMenu-private-window-button"<br />
class="subviewbutton subviewbutton-iconic"<br />
diff --git a/firefox-esr-60.5.1esr/browser/locales/en-US/chrome/browser/browser.dtd b/firefox-esr-60.5.1esr/browser/locales/en-US/chrome/browser/browser.dtd<br />
<span>--- a/firefox-esr-60.5.1esr/browser/locales/en-US/chrome/browser/browser.dtd</span><br />
<span>+++ b/firefox-esr-60.5.1esr/browser/locales/en-US/chrome/browser/browser.dtd</span><br />
<span>@@ -298,7 +298,6 @@ These should match what Safari and other</span><br />
<!ENTITY newUserContext.label "New Container Tab"><br />
<!ENTITY newUserContext.accesskey "B"><br />
<!ENTITY newNavigatorCmd.label "New Window"><br />
<span>-<!ENTITY newNavigatorCmd.key "N"></span><br />
<!ENTITY newNavigatorCmd.accesskey "N"><br />
<!ENTITY newPrivateWindow.label "New Private Window"><br />
<!ENTITY newPrivateWindow.accesskey "W"></div></div>
<p>So there you have it. You can still alter Firefox’s XUL. You just have to compile it in instead of doing an extension.</p>Jordi Gutiérrez Hermosohttp://jordi.inversethought.comTo Translate Is To Lie, So Weave A Good Yarnhttp://jordi.inversethought.com/?p=4682019-02-21T01:59:33+00:00<p>I’m not a professional translator, but I know what I like in fiction.</p>
<p>When I was a Mexican kid in the 1980s we used to get old re-runs of the Flintstones in Spanish. Of course, my English wasn’t very good when I was very young, and I didn’t know them as “the Flintstones at all.” They were “Los Picapiedra” (something like “The Pickstones”), and not only that, but I had no idea who Fred or Barney were. Instead, I knew Pedro Picapiedra and Pablo Mármol (something like “Peter Pickstone” and “Paul Marble”). I liked them, and they felt familiar and comfortable. They spoke with a Spanish accent very close to mine and they used expressions that were similar to how my parents spoke.</p>
<p>It wasn’t until I got older and got more experienced that I realised I had been lied to, like many other lies we tell children. Pedro and Pablo weren’t a caricature of my Mexican lifestyle at all, but of a different, 1950s lifestyle from another country up north. I didn’t exactly feel cheated or lied to, but it was another cool new thing to learn about the world. I still felt much endeared to the original names and to this day, if I have to watch the Flintstones, I’d much rather view them as Los Picapiedra instead.</p>
<h1>Other Lies I Grew Up With</h1>
<p>This wasn’t the only time this happened. Calvin & Hobbes fooled me too. This time their names didn’t change, but their language did. Calvin spoke to me from the comic book pages with a hip, cool Mexico City slang like other kids my age would use to elevate themselves in the eyes of other kids. Calvin talked about the prices of candy and magazines in pesos, with peso amounts appropriate for the time of publication, and used phrases like “hecho la mocha” (something like “made a blur”) when he said he was gonna do something very quickly. His mother sounded like my mother. This time the deception was even better, and for the longest time I honestly thought Calvin was a Mexican kid like me.</p>
<p>And there were others. The Thundercats were Los Felinos Cósmicos (something like “Cosmic Felines”), the Carebears were Los Ositos Cariñositos (something like “The Little Loving Bears”), and The Little Mermaid was La Sirenita (interesting how mythological sirens and mermaids are different in English but not in Spanish).</p>
<p>Again, as I grew up, so did my languages, and I was able to experience the other side of the localisation. It was always a small revelation to realise that the names I had known were an alteration, that the translators had taken liberties, that the stories had been subtly tampered with. In some cases, like with Calvin, I was thoroughly fooled.</p>
<h1>The Translator’s Task</h1>
<p>I’m of the opinion that the translators and localisers of my youth performed their task admirably. A good translator should be a good illusionist. Making me believe that Calvin was Mexican or that the Flintstones could have been my neighbours is what a good translator should do. Translation is always far more than language, because languages are more than words. A language always comes with a culture, a people, habits and customs. You cannot just translate words alone; you have to translate everything else.</p>
<p>Only bad translators believe in the untranslateable. Despite differences in language, culture, and habits, a translator must seek out the closest points of contact across the divide and build bridges on those points. When no point of contact exists, a translator must build it. A new pun may be needed. The cultural references might need to be altered. If nothing else can be done and if there is time and space for it, a footnote can be the last resort, when a translator admits defeat and explains the terms of their surrender. Nothing went according to keikaku.</p>
<p>The world has changed a lot since I was a child. It has gotten a lot bigger. We have more ways to talk to each other. As a result, it’s getting harder for translators to perform their illusions.</p>
<h1>Modern Difficulties of Translation</h1>
<p>With the internet and other methods of communication, a more unified global presence has become more important. Translations now have to be more alike to the source material. Big alterations to characters’ names or, worse, to the title of the work, are now out of the question.</p>
<p>Thus we get The Ice Queen becoming Frozen, because it’s good marketing (things didn’t go so well last time we made a title about a princess or a queen), and Frozen she shall be in Spanish as well, leaving Spanish speakers to pronounce it as best they can. As a small concession, we will allow the forgettable and bilingually redundant subtitle “Una Aventura Congelada” (something like “A Frozen Adventure”), but overall, the trademark must be preserved. There’s now far too much communication between Spanish and English speakers to allow the possibility of losing brand recognition.</p>
<p>Something similar and strange happened with the localisation of Japanese pop culture. We went from Japanimation to anime, from comics to manga. The fans will no longer let a good lie in their stories, and while we will grandfather in Megaman instead of Rockman or Astroboy instead of Mighty Atom, from now on new material must retain as foreign of a feeling as possible, because we now crave the foreign. It doesn’t matter if we really can understand it as closely as the Japanese do, because we crave the experience of the foreign.</p>
<p>The reverse also happens and the Japanese try their best to assimilate the complicated consonants of English into their language, but they have had more practice with this assimilation. Their faux pas have been documented on the web for the amusment of English speakers.</p>
<h1>When Lies Won’t do</h1>
<p>I should be more fair to translators. Sometimes, a torrent of footnotes is all that will work. Of course, this should be reserved for the written word. Such is the case of the English translation of Master and Margarita. The endless stream of jokes making fun of Soviet propaganda and Soviet life are too much of a you-had-to-be-there. Explaining the jokes sadly makes them no longer funny, but there’s no other recourse except writing a completely different book, far removed from the experience of a modern Russian reading a Soviet satire.</p>
<p>But it doesn’t have to be this way. The Japanese translations of Don Quixote works without burdening the readers with the minutiae of life from a time long, long ago, in a country far, far away. Don Quixote’s exaggerated chivalric speech is rendered in Japanese translations as samurai speech. Tatamis suddenly appear in a place of La Mancha that I don’t care to call to mind.</p>
<p>And that’s the best kind of translation. The one that works and makes the fans love it, that makes them feel like they belong in this translated world.</p>Jordi Gutiérrez Hermosohttp://jordi.inversethought.comGSoC: final posttag:blogger.com,1999:blog-7386105313127736439.post-486730930999067572018-09-07T16:10:23+00:00<div dir="ltr">Welcome to the final post regarding my Google Summer of Code 2018 project. In this post, I'd like to talk about the overall work product and how it corresponds (or varies) from the original plan. Then, I would like to acknowledge some suggestions of my mentors and talk about some new ideas that were recently discussed with them.<br /><br />However, before talking about any of those things, I'd like to share the code that was written down in the last twelve weeks. So <a href="https://bitbucket.org/peesu_97/octave/commits/all" target="_blank">here</a> is the link to my public repository where all the code can be found and <a href="https://drive.google.com/open?id=1uPkZzIZXQ-UjbT8hjxtYTuZXsegkRP4J" target="_blank">here</a> is a patch that can be merged with the main line of development.<br /><br />Now, coming to final work product, functionality wise, the feature turned out to be exactly what it was supposed to be, a fast and accurate way to suggest corrections for typographic errors, made while working on the command window of Octave. The difference, however, was in the way of implementation.<br /><br />My original idea was to make a Neural Network for this problem and I did go to some lengths to make that happen. Precisely, I did collect some data about the most common typographic errors made by Octave users and did code up a small model that could learn the correct spellings of a few commands of Octave. At the time, the motivation behind the Neural Network model was to have an algorithm that could work better than the existing algorithms that are used to compare two strings, in terms of the speed-accuracy trade-off. <br /><br />However, during the community bonding period, some loopholes in my Neural Network implementation were pointed out by a few members of the Octave community. As a student who wants to pursue a career in data science, those counter points, and further research that was done on the Neural Network approach during the third phase of coding, turned out to be invaluable, for it taught me that 'Neural Networks + Data' is not a magical combination that solves every problem of this world. Maybe they can, but sometimes, simpler, more optimal solutions exist, and in those times, one must look at those solutions and optimize them further according to the problem at hand. Somewhere down the line, it also gave me a better understanding of the nature of Neural Networks.<br /><br />Now, coming back to the technical details of this project, to summarize it all, I used the faster variation of the edit distance algorithm, the one that uses dynamic programming, and optimized it further by reducing the sampling space on which the algorithm had to work on. To reduce the sample space, I analyzed the data that I had originally collected to make a Neural Network and based on the results of the analysis, I was able to make certain assumptions about the misspellings. These assumptions coupled with some clever data organization techniques helped me code up a fast, and yet very accurate version of the edit distance algorithm. One can read about this implementation in great detail in the previous blog posts.<br /><br />The plan was to replace this algorithm with Neural Networks, during the third phase, 'if' they happen to perform better. As of now however, I found no way to make a Neural Networks perform better than what had been already made and so the suggestion engine still uses my original algorithm. <br /><br />Additionally, I had to write the documentation and the tests for all of my code during the third phase of coding and I am glad to say that this work has been successfully completed. The main documentation for the m-scripts can be seen in the help text of those scripts. Besides that, I've also written down the documentation for the database file in a markdown file that is included with the database.<br /><br />I must acknowledge the fact that Nick had guided me very well on how the documentation should be done, during the second phase evaluations. I did keep his guidance in mind while writing the documentation and the tests, and have, hopefully, made a well documented, well tested product.<br /><br />Now, although, the main documentation should be enough for anyone who wishes to understand how the feature works, if any additional help is required by anyone, the previous posts of this blog (which contain a very detailed explanation), and the public mailing list of Octave (which I shall continue to follow), should be a good place to visit.<br /><br />During the community bonding period, Rik and I had discussed the importance of an on/off switch for this feature. This switch was already created by the time the first evaluations took place, but during the third phase, I took some time to wrap up this toggling command into a nice m-script. The users can now do a simple >>command_correction ("off") to switch off the feature and do a simple >>command_correction ("on") to turn it back on.<br /><br />Next, I'd like to talk about something that Doug recently mentioned to me. He asked me if I could think of some way in which we can track the identifiers that don't get resolved by my software. Essentially, this problem is directly related to the maintenance of the database file. With Octave under constant development, new identifiers will be created and some identifiers will deprecate as well. To make sure that the correction suggestion feature does not loose its value, the database of the identifiers would have to be updated in some regular intervals of time. Maybe an update every 6 months would be enough.<br /><br />Currently, I've included a markdown file with the database that explains how this update can be done, and for now, this update could be done manually only. For now, I cannot not think of a way in which the database file gets automatically updated. Later on, maybe I or someone else could come up with a way to make a program read the release notices of Octave and its various packages and then modify the database accordingly. Maybe this could be a GSoC project for a future batch of students? <br /><br />So in conclusion, the planned part of the project is absolutely complete and we have already started thinking of ways in which this feature can be improved. For further testing of the current implementation of the feature, I'd need the support of the members of the community. I would really appreciate it if anyone could try this feature for themselves and see if they could break it, or find any other kind of bugs, or maybe suggest some changes to the suggestion engine that could speed up the feature, or, maybe do something as small as pointing out some pieces of code where the coding style has not been followed properly.<br /><br />Finally, I'd like to thank the Octave community. Working with them was an invaluable learning experience and I hope to be able to continue to associate myself with them for the years to come. :)</div>Sudeepam Pandeynoreply@blogger.comhttps://sudeepam.blogspot.com/Final Posttag:eriveltongualter.github.io,2018-08-13:/GSoC2018/final.html2018-08-13T05:00:00+00:00<p>The Google Summer of Code program is over and I am positive I have gained so many experience in this period and additionally I have been done a significant work for GNU Octave about the Sisotool. Therefore, in this last post I all will go over in the project, describe …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/Second Evaluation - week 8tag:eriveltongualter.github.io,2018-07-06:/GSoC2018/week8.html2018-07-06T16:36:00+00:00<p>So, here is my last post before the second evaluation. If you have been following <a class="reference external" href="https://eriveltongualter.github.io/GSoC2018/">my blog</a> or the <a class="reference external" href="http://planet.octave.org/">octave blog</a>, you know that the purpose of this google summer of code project is to create an <a class="reference external" href="https://summerofcode.withgoogle.com/projects/#5842927301951488">Interactive Tool for Single Input Single Output (SISO) Linear Control System Design</a>. Also …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/GSoC project progress: part threetag:blogger.com,1999:blog-7386105313127736439.post-83640144326560726982018-07-03T10:09:51+00:00<div dir="ltr">The goal for the second evaluations was to code up a complete, working, command line suggestion feature that supports identifiers and graphic properties of core octave and all the octave forge packages. I am happy to say that this goal has been achieved and we do have a working suggestion feature now. The link to public repository where the code can be found is <a href="https://bitbucket.org/peesu_97/octave/commits/all" target="_blank">this</a>.<br /><br />If you haven't already, you should read my previous posts to find out what the community wanted the feature to look like and how much progress had been already made. You may need that to understand the contents of this post. In this post, I would like to talk about the additional work that has been done and the work that will be done in the days to come.<br /><br />At the time of the first evaluations, one of my mentors, Nicholas, expressed how he would be interested in seeing how the rest of the project progresses, including the aspects related to user interface and maintainability of the code by other developers. I'd like to address these points first.<br /><br />So the UI is relatively simple. You enter a misspelling and some suggestions are displayed. We could have tried adding some GUI pop-ups but I refrained myself from trying to do those. There were two primary reasons for that.<br /><ul><li>First reason is that a GUI pop-up looks very unpleasant when you are working on the CLI of Octave, but honestly, that is more of a personal opinion I suppose.</li><li>Second, and the more strong reason is that adding a GUI pop-up would have been a really complicated task due to the way octave handles errors and would have resulted in things like displaying of the "undefined near line..." error messages for the misspelled command, <b>after</b> the correct command has been executed. </li></ul>There are some other reasons as well which have been discussed with the members of the community before. Obviously we can try changing things later on, if we really want to, but as of now, suggestions are simply displayed and the user can just use the upward arrow key of their keyboard and edit the previous command to quickly correct their misspelling.<br /><br />I have accounted for code maintainability as well. I moved a few pieces of code here and there (see commit log) and have made the feature in a way that . . . all the code related to the UI, or how the feature presents itself to the user is in a separate file (scripts/help/__suggestions__.m) and all the code related to the suggestion engine, that generates the possible corrections for the misspelled identifier is in a separate file (scripts/help/__generate__.m). A lot of comments have been included in the code and the code is simple enough to be red and understood by anyone who knows how the Octave or MATLAB programming language works. Another important point is that, all the graphic properties and identifiers of Octave core and forge with which a misspelling can be compared have been stored in a database file called func.db (examples/data/func.db). I had described this file in my in <a href="https://sudeepam.blogspot.com/2018/06/gsoc-project-progress-part-two.html" target="_blank">my previous post</a>.<br /><br />Maintainability shall be very easy due to such an implementation. If UI changes are required, major changes must be done only to the file __suggestions__.m. If the algorithm of the suggestion engine has to be changed, changing the code of the file __generate__.m shall be enough and if new identifiers are added to octave (something that will be constantly done), including them in the well organized database file (which can be very easily done with a load>edit>save) would be enough.<br /><br />Now I'd like to describe the other tasks that have been done in this coding phase. These include adding the support for the remaining packages of Octave forge and adding support for the graphic properties.<br /><br />Including the remaining packages of Octave forge was very easy, all I had to do was, fetch the list of identifiers, clean up the data a little, and include it in the database file.<br /><br />The challenging part was adding the support for graphic properties. This was mainly because of the fact that it required me to write a C++ code for a missing_property_hook() function which had to be similar in architecture to the already existing, missing_function_hook() function.<br /><br />In the codebase of Octave, missing_function_hook() is a function that points to a particular m-script which is called when an unknown command is encountered by the parser. Like I had described earlier, I had extended its functionality to trigger the suggestion feature when an unknown identifier was found. The missing_property_hook() had to do something similar, call a certain m-script when an unknown graphic property is encountered.<br /><br />Rik helped a lot with this part and finally, I was able to code up a missing_property_hook() function which would trigger the suggestion feature when an unknown graphic property is encountered. Although, the code does what it is supposed to, I'd be honest here and say that this part is still a little black-box to me. I'd appreciate it if some other maintainer who is good with c++ and familiar with the code of the missing_function_hook() function would take a look at the missing_property_hook() function and point out or fix any issues that they find.<br /><br />I'd like to mention that the suggestion feature differentiates between the levels of parsing, i.e. whether the trigger is an unknown property or an unknown command, by looking at the number of input arguments. The rest of the functionality is same.<br /><br />With all these things done, I was able to realize a complete and working command line suggestion feature and complete the goal that was set for the phase two evaluations. Future work that had been planed for phase three of coding includes writing the documentation, writing some tests, fixing any and every bug that is reported, and seeing if I could use a better algorithm for the suggestion engine. An additional thing that I would like to do is to nicely wrap up the on/off button and other such user settings into a single m-script for better user experience.<br /><br />Since the phase two work is done, I'll start working on these things that have been planned for phase three from tomorrow onwards. I'll publish another post when I make some more significant changes, till then, thank you for reading and goodbye.</div>Sudeepam Pandeynoreply@blogger.comhttps://sudeepam.blogspot.com/Edit Compensantor Dynamicstag:eriveltongualter.github.io,2018-07-01:/GSoC2018/week7.html2018-07-01T14:34:00+00:00<p>So far, to design a controller using sisotool we need to select the desired feature to add to the compensator, such as real and complex pole or zero. In order to perform this task, we have two options. First, we can go to the main tab and select the feature …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/Back to Codingtag:eriveltongualter.github.io,2018-06-24:/GSoC2018/week5-6.html2018-06-24T06:19:00+00:00<p>Results from the first evaluation came 9 days ago. All of the three gsoc student were successful! For the readers of my blog, you can find them at <a class="reference external" href="http://planet.octave.org/">http://planet.octave.org/</a>. If you already a reader of planet octave, you are in the right place.</p>
<p>The feedback from my …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/GSoC project progress: part twotag:blogger.com,1999:blog-7386105313127736439.post-32333378504685285972018-06-11T10:03:19+00:00<div dir="ltr">In my previous post, I talked about all the major discussions that have been made with the community, what the suggestion feature would be like, how I plan to realize this feature, and how I have extended the functionality of the scripts/help/__unimplemented__.m function file to integrate the command line suggestion feature with Octave. In this post, I would like to share my progress and talk about how the current implementation of the suggestion feature is working. The link to the public repository that contains the code for this feature can be found <a href="https://bitbucket.org/peesu_97/octave/commits/all" target="_blank">here</a>.<br /><br />The goal for the first evaluations was to code up a small model that would show how this feature integrates itself with Octave. That part, however, was completed by the time I had made my last blog post. I had been working on a full-fledged command line suggestion feature since then and till now, I have been able to complete a working command suggestion feature that supports identifiers from core octave and 40 octave-forge packages. Lets start looking at various parts of the feature.<br /><br />Whenever the __unimplemented__.m function file, fails to identify, whatever the user entered, as a valid, unimplemented octave command, it calls one of my m-script, called <b>__suggestions__.m</b> and the command suggestion feature gets triggered. This script, __suggestions__.m, does the following things...<br /><ul><li>Firstly, based on the setting of the custom preference (set by the user with the command <b>setpref ("Octave", "autosuggestion", true/false</b>) it decides whether to display/not to display any suggestions. If the preference is 'false', it realizes that the user has turned off the feature and so it returns the control without calculating or displaying any suggestions. </li><li>However, if the preference is true, it checks if whatever the user has entered is at-least a two letter string. If not, it again, returns the control without calculating or displaying any suggestions. This is done because it is less likely that a one letter strings is a misspelled form of some command.</li><li>However, if the string entered by the user is two lettered or more, the script goes on to calculate the commands that closely match the misspelling. The work of calculation is done by a different script and __suggestions__.m, only calls that script to get the closest matching commands. These commands are then displayed to the user as potential corrections.</li><li>If the misspelling of the user is short (length of the misspelling < 5), the script entertains one typo only, However, if the length of the misspelling is more than or equal to 5, two typos are entertained as well. This essentially means that for short misspellings, commands which are at an edit distance of 1 from the misspelling are shown as potential corrections and for relatively longer misspellings, commands which are at an edit distance of 2 from the misspelling are also shown as potential corrections.</li></ul>Commands that closely match the misspelling are calculated by a different m-script. This m-script is called <b>__generate__.m</b>. It loads a list of possible commands from a database file called <b>func.db</b> and then calculates the edit distance between the misspelling and each entry of the list using a different script called <b>edit_distance.m</b>. The commands having an edit distance equal to one or two are accepted as close matches and a list of all such commands along with their edit distances is returned to __suggestions__.m which displays some or all of these suggestions depending on the logic described before.<br /><br />I'd like to mention that the strings package of Octave forge also has a function file that calculates the edit distance. It is called "editdistance.m". Therefore, to avoid compatibility issues or to avoid having two different function files that do the same thing, later on, I will include the edit_distance function that I wrote within the __generate__.m script.<br /><br /><h3><u>Improving the speed of the generation script</u> </h3>If we go on and calculate the edit distance between the misspelling and <b>each and every</b> identifier of octave (core+forge), our algorithm would take nearly 20 years to generate an output for each typographic error that the user makes. We, however, would like the time to be 20 milliseconds or so. For that, we use some smart techniques that reduce the sample space on which the algorithm has to operate.<br /><br />To reduce the time, I've made a small assumption. I have assumed that the user never mistypes the first letter of a command. A rough analysis of the misspelling data that I received from Shane of octave-online before the commencement of the project, suggests that this is a reasonable assumption and would hardly reduce the accuracy of the suggestion feature. How good is this assumption for the speed? Well, I'd just say that, for a misspelling starting with the letter 'n', this small assumption reduces the sample size from 1492 to 36 (and that is not the best case!). The worst case was that of the letter 's' in which 178 out of 1492 commands were left. Even that corresponds to an 88% reduction in the sample size.<br /><br />It is important to mention that doing this alphabetical separation at run-time would be a redundant task and a stupid idea, that would correspond to the algorithm taking 20 years again.<br /><br />Another thing that we should consider, to improve the speed, is to show suggestions from octave core + <b>loaded packages only</b>. Obviously it is not a good idea to check among the commands that belong to a package which the user is not currently using (or worst, a package that is not installed on the user's machine).<br /><br />Keeping these things in mind, I have created the func.db database file in such a way that the commands belonging to different packages are stored in different structures and are alphabetically separated as fields of that structure. So for example, func.db contains a structure called <b>control</b> which holds the identifiers from the control package only, and another structure <b>core</b> which holds the identifiers of core Octave only, and another structure <b>signal</b> which holds the identifiers of the signal package only and so on. The field <b>a</b> of the control structure (accessed by typing <i>control.a</i>) contains all the identifiers of control package starting with 'a', The field <b>b</b> (accessed by typing <i>control.b</i>) contains those identifiers of the control package that start with b, and so on. This has been repeated for all the packages available.<br /><br />To make our __generate__.m script memory efficient as well, we load the core structure (which is always required) and then check for the loaded packages and load the structures corresponding to the loaded packages only, then, using a switch case, fetch all those commands which have the same first letter as that of the misspelling (in O(1), thanks to the way in which the database is arranged) and then proceed to the next step.<br /><br />To understand the next step, we need to understand that the if a misspelling is of length p (say), and we are accepting corrections that are at an edit distance of one or two from the misspelling, then the corrections could have the following lengths only...<br /><ul><li><b>p-2</b>: Two deletes in the misspelling,</li><li><b>p-1</b>: One delete and one substitution, or one delete only.</li><li><b>p</b>: One delete and one addition, or one or two substitutions.</li><li><b>p+1</b>: One addition and one substitution, or one substitution only.</li><li><b>p+2</b>: Two additions to the misspelling.</li></ul>This fact, allows us to reduce the list further and would cut out some 5-10 more entries for normal length misspellings. This logic, however, is particularly useful for large length misspellings, because commands with large lengths are very less in number. If a user misspells the command "<i>suppress_verbose_help_message" </i>the script would take days to suggest a correction for this command without this logic, this is because edit distance algorithm is O(n1*n2) with dynamic programming, where n1 and n2 are the lengths of the strings being compared. This O(n1*n2) is repeated m times where m is the number of possible commands that could be close matches. With this logic however, the possible list would be cut down to one or two commands only. Thus, the value of m will be reduced and the close matches will be found within one or two iterations.<br /><br />That summarizes all the measures that I have taken to improve the speed of the suggestion feature. The control flow had been described before this and so that concludes the working of the suggestion feature.<br /><br /><h3><u>Conclusion</u></h3><div>This concludes phase one. What's left is to include more forge packages and to include graphic properties within the scope of this feature. Writing the documentation, writing the tests, and debugging also remains but these shall be the tasks for subsequent coding phases. Till then, goodbye, see you in the next blog post. :)</div></div>Sudeepam Pandeynoreply@blogger.comhttps://sudeepam.blogspot.com/First Evaluation - week 4tag:eriveltongualter.github.io,2018-06-10:/GSoC2018/week4.html2018-06-10T16:36:00+00:00<p>So, here is my last post before the first evaluation. If you have been following <a class="reference external" href="https://eriveltongualter.github.io/GSoC2018/">my blog</a> or <a class="reference external" href="http://planet.octave.org/">octave blog</a>, you know that the purpose of this google summer of code project is to create an <a class="reference external" href="https://summerofcode.withgoogle.com/projects/#5842927301951488">Interactive Tool for Single Input Single Output (SISO) Linear Control System Design</a>. Also, well-known …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/GSoC project progress: part onetag:blogger.com,1999:blog-7386105313127736439.post-50332356560679309452018-06-10T14:37:02+00:00<div dir="ltr">p { margin-bottom: 0.25cm; line-height: 120%; } <br /><div><h3><u><b>An Initial note....</b></u></h3><br />Alright, so first of all, I would like to apologize for not writing a proper blog post up till now. I had my Final examinations during the first week of the coding period and immediately after that, to catch up, I got so involved with the coding part that I forgot to share the progress of the project on the blog. On the positive side however, I have completed a lot of work. I can safely say that I have completed the goals that were set for phase 1 evaluations (possible style fixes may be left), but that’s not the entire good news. The phase two evaluations goal is also halfway done!<br /><br />Now, I do realize that I have not shared any details of my project until now, and so, in this blog post, I’ll share a lot of important details and talk about everything that has been discussed and done so far. I promise to post more often after this, ‘cumulative’ post. Here goes...<br /><br /><h3><u><b>The Project</b> <b>Idea</b>....</u></h3><br />If you've red the last blog post, you'd know that I plan to add something called a 'Command Line suggestion feature' to Octave and you may be wondering what that means. Basically this feature would do something like this...<br /><br />Whenever the users make a typographic error while working on Octave's command window, the command line suggestion feature would suggest a correction to them and say something like "The command you entered was not recognized, did you mean any of the following...?"<br /><br />Now I could share a detailed time-line explaining 'when' I plan to do 'what' but I believe that not everyone would be interested in reading that and so I'll skip that for now. Instead, I'll quickly talk about the following...<br /><ul><li>What the community wants the overall project to be like.</li><li>What are the challenging parts of the project.</li><li>What are my evaluation goals.</li><li>What discussions have been made, and</li><li>How much progress has been made.</li></ul>If you really would like to see my time-line then just ask for it in the comments section and I'll share a link.<br /><br /><h3><u><b>The Community Bonding Period...</b></u></h3><b><br /></b>By the time you finish reading this section, probably the only thing left to talk about would be "How much progress has been made". That is just a glimpse of how much the community has been involved in this project. It also shows how successful GNU Octave is as an open source community, not every open-source community is as open when it comes to discussions.<br /><br />Now the first thing to understand is that this project is essentially a UX improvement, and as such, Octave is not bound by 'MATLAB compatibility issues'. This is one of the primary reasons why there was so much to discuss in the community bonding period. Here are the main points that summarize the collective decision of the community on what the overall project should be like:<br /><ul><li>First of all, it was decided that the user interface, or the part handling 'how this feature hooks itself to octave' should be well separated from how the 'suggestions are generated'. This need was realized, immediately after realizing the fact that there are a lot of algorithms available that could be used to generate suggestions. Separating the integration and generation part would allow us to make sure that, in future, if a faster or a more accurate algorithm to generate suggestions is discovered, replacing the existing implementation becomes easier.</li><li>Secondly, a few problems such as, a very large output layer size, and failure on dynamic package loading were found with my proposed Neural Networks, based approach. Therefore, we decided to use a well established approach called the Edit distance algorithm for now and the Neural Networks based approach will be the 'research part' of the project. Essentially, the plan is to first use 'smart implementations' of the good old Edit-distance algorithm to realize this feature and to research and see if a Neural Network could do better after that has been done. If later on, we realize that a Neural Network (or for that matter, any other approach), really could do better than the Edit-distance approach, the algorithm can be replaced very easily (thanks to the previous point).</li><li>Next, we decided to include keywords, functions, and graphic properties within the scope of this feature. Very short keywords, user variables, and internal functions will not be included in its scope. Deprecated functions would also be included in the scope for now. Essentially, corrections would be suggested for typos close to anything that is within the scope of this feature and would not be suggested for anything that isn't.</li><li>Also, we decided to use the missing_function_hook() to realize the integration part of this feature. More about this later in this post.</li><li>Lastly, we decided that it is absolutely necessary to include an 'on/off switch' type of command that would let the users decide whether they want to use this feature or not. We plan to use custom preference for now to do this.</li></ul>That summarizes the most important discussions that took place and with that, we are in a position to talk about how the second point and the last point are directly related to what are the 'challenging parts of the project'. Let's start with that.</div><div></div><div><br />Essentially, the second point talks about the algorithm that will be used to generate the corrections that are ultimately going to be shown to the user. The challenging part is that this algorithm should provide a <b>minimum speed-accuracy trade-off</b>. I did know about the Edit-distance algorithm beforehand but I initially believed that a Neural Network would outperform it in terms of the speed accuracy trade-off. Discussing the idea with the community made me realize that there are some critical loopholes in the Neural Network based model and although they could definitely be improved with more research, I should not jeopardize the entire project just to proof that Neural Networks could do better. We therefore decided to do what I had described earlier in the second point. <br /><br />At this point, defining a 'smart implementation' of Edit distance remains. Basically, Edit distance is a very accurate algorithm that quantifies how dissimilar two strings are. The only problem with it is its speed (my primary reason for initially proposing a trained Neural Network). Essentially, by a smart implementation of the algorithm, we mean an implementation which would maximize the computation speed by reducing the sample space, on which the algorithm has to work on. This would be done using some clever data management techniques and some probability based assumptions. Some discussions related to these were also done during the community bonding and since then, I have been looking at a lot of suggestion features of other free and open source softwares to device some clever techniques. Good progress has been made but I'll share that in another blog post.<br /><br />The last point talks about a very important 'on/off' feature, the tricky part with this was that Octave comes in both a GUI and a CLI and so a common method that does the job could have been hard to find. However, this problem was solved with relative ease, and we decided to use <b>custom preference </b>to realize this part. This gave us a simple and common command to switch on/ switch off the feature.<br /><br /></div><div>These discussions led me to reset my term evaluation goals which are as follows now:- <br /><ul><li><b><u>Phase-1 goal</u></b>: To code up and push an algorithm independent version of the suggestion feature into my public repository. Essentially this would show how this feature integrates itself with Octave.</li><li><u><b>Phase-2 goal</b></u><b>:</b> A development version of Octave with a working (but maybe bugged and surely undocumented) command line suggestion feature integrated into it.</li><li><u><b>Phase-3 goal</b></u>: The primary goal would be to have a well documented, well tested and bug free command line suggestion feature. The secondary goal would be to research and try to produce a Neural Network based correction generation script that outperforms the edit distance algorithm.</li></ul>...and that, marked the end of the major discussions and the community bonding period.</div><div><br /></div><div><h3><u><b>Progress made so far...</b></u></h3></div><div><b><br /></b></div><div>So far, I have coded up the phase-1 goal. The public repository can be seen <a href="https://bitbucket.org/peesu_97/octave/commits/all" target="_blank">here</a>. It very well shows how we have used the missing_function_hook() to integrate the feature with octave. The following points summarize the working:<br /><ul><li>Essentially, whenever the parser fails to identify something as a valid octave command it calls the missing_function_hook() which points to an internal function file, '__unimplemented__.m'.</li><li>This file checks if whatever the user entered is a valid, unimplemented octave (core or forge) command or if it is a implemented command but belongs to an unloaded forge package. If yes, it returns an appropriate message to the user and if not, it does, or rather, used to, do nothing.</li><li>To realize the suggestion feature, I have extended its functionality to check for typographic errors whenever the command entered was not identified as a valid unimplemented/ forge command.</li></ul>By using the missing_function_hook() the keywords and built-in functions were automatically bought into the scope of this feature. Graphic properties remain because there is no missing_property_hook() in octave right now. I have discussed this with the community and I'll try to code it up in the subsequent weeks.<br />Besides that I have also figured out how the Edit Distance algorithm can be made 'smart'. I'll push an update and write another blog post as soon I master and code up the entire thing. For now, thanks for reading, see you in the next post. :)</div></div>Sudeepam Pandeynoreply@blogger.comhttps://sudeepam.blogspot.com/Geeting closer to the First Evaluation - week 3tag:eriveltongualter.github.io,2018-06-03:/GSoC2018/week3.html2018-06-03T10:48:00+00:00<p>First Evaluation period is around in the corner. As was proposed on my <a class="reference external" href="https://eriveltongualter.github.io/GSoC2018/welcome-gsoc.html">first post</a> of my timeline, the work I have been doing is on time.</p>
<p>For this past week, I added some functionalities to the Root Locus Editor. This time, the user can add: real poles, complex poles …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/Plots are Working - week 2tag:eriveltongualter.github.io,2018-05-29:/GSoC2018/week2.html2018-05-29T17:38:00+00:00<p>Here we go one more week of code. This week I have continued my work from previous week related to interface of sisotool. Just reiterating what was done last week, I created a couple GUI to understand a little better how the UI Elements works in Octave. For this week …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/Code begins - week 1tag:eriveltongualter.github.io,2018-05-21:/GSoC2018/week1.html2018-05-21T16:27:00+00:00<p>The first week of coding has been completed.</p>
<p>As I mentioned in the <a class="reference external" href="https://eriveltongualter.github.io/GSoC2018/bonding.html">last post</a>, the goal of this previous week was to create a fixed layout to study the plot diagrams for the sisotool, as well as to add some UI Element functionality to control the interface. The following …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/Community Bonding Periodtag:eriveltongualter.github.io,2018-05-15:/GSoC2018/bonding.html2018-05-15T16:16:00+00:00<p>The community bonding period is over. The past 3 weeks were really busy because I was in my finals week, final projects and my doctoral research. However, I basically completed everything I wanted to before the “Coding officially begins!”:</p>
<ul class="simple">
<li>Finished Optimal Control and Intelligent Control System classes;</li>
<li>Submitted a conference …</li></ul>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/Starting with GSoC 2018.tag:blogger.com,1999:blog-7386105313127736439.post-40354355411889230522018-04-26T12:57:05+00:00<div dir="ltr">So this year, I applied to the Google summer of code and got in. Google summer of code, or GSoC, as it is usually called, is a program funded by Google that has helped open source grow for over a decade. Under this program, Google awards stipends to university students for contributing code to open source organizations during their summer breaks from the university. The details of the program can be found here: <a href="https://summerofcode.withgoogle.com/">Starting with Google summer of code.</a><br /><br />Now this year, I have been selected to work with GNU Octave. It is a free and open source software/ high level programming language which is primarily focused on scientific computing. It is largely compatible with MATLAB and is a brilliant open source alternative to it. More details about GNU Octave can be found at <a href="https://www.gnu.org/software/octave/">Free your numbers! Introducing GNU Octave.</a><br /><br />My GSoC project is about adding a <b>Command line suggestion feature</b> to GNU Octave. Stay tuned, I will share the details of the project very soon.</div>Sudeepam Pandeynoreply@blogger.comhttps://sudeepam.blogspot.com/Welcome to Octave and Google Summer of Codetag:eriveltongualter.github.io,2018-04-23:/GSoC2018/welcome-gsoc.html2018-04-23T07:46:00+00:00<p>This summer I got accepeted to the Summer Google of Code under the GNU Octave. This program, admistred by Google, facilates the emergence of students to the Open Source Community. My primary goal to participate in the GSoC is to build a long term relationship with the open source community …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/Welcome to Octave and Google Summer of Codetag:None,2018-04-23:/welcome-gsoc.html2018-04-23T07:46:00+00:00<p>This summer I got accepeted to the Summer Google of Code under the GNU Octave. This program, admistred by Google, facilates the emergence of students to the Open Source Community. My primary goal to participate in the GSoC is to build a long term relationship with the open source community …</p>Erivelton Gualterhttps://eriveltongualter.github.io/GSoC2018/Advent of Dhttp://jordi.inversethought.com/?p=4292018-03-06T04:24:45+00:00<p>I wrote my <a href="https://adventofcode.com/">Advent of Code</a> in D. The programming language. It was the first time I used D in earnest every day for something substantial. It was fun and I learned things along the way, such as easy metaprogramming, concurrency I could write correctly, and functional programming that doesn’t feel like I have one arm tied behind my back. I would do it all over again.</p>
<p>My main programming languages are C++ and Python. For me, D is the combination of the best of these two: the power of C++ with the ease of use of Python. Or to put it another way, D is the C++ I always wanted. This used to be D’s sales pitch, down to its name. There’s lots of evident C++ heritage in D. It is a C++ successor worthy of consideration.</p>
<h1>Why D?</h1>
<p>This is the question people always ask me. Whenever I bring up D, I am faced with the following set of standard rebuttals:</p>
<ul>
<li>Why not Rust?
</li>
<li>D? That’s still around?</li>
<li>D doesn’t bring anything new or interesting</li>
<li>But the GC…</li>
</ul>
<p>I’ll answer these briefly: D was easier for me to learn than Rust, yes, it’s still around and very lively, it has lots of interesting ideas, and what garbage collector? I guess there’s a GC, but I’ve never noticed and it’s never gotten in my way.</p>
<p>I will let D speak for itself further below. For now, I would like to address the “why D?” rebuttals in a different way. It seems to me that people would rather not have to learn another new thing. Right now, Rust has a lot of attention and some of the code, and right now it seems like Rust may be the solution we always wanted for safe, systems-level coding. It takes effort to work on a new programming language. So, I think the “why D?” people are mostly saying, “why should <em>I</em> have to care about a different programming language, can’t I just immediately dismiss D and spend time learning Rust instead?”</p>
<p>I posit that no, you shouldn’t immediately dismiss D. If nothing else, try to listen to its ideas, many of which are distilled into Alexandrescu’s <a href="https://www.worldcat.org/title/d-programming-language/oclc/456837504">The D Programming Language</a>. I recommend this book as good reading material for computer science, even if you never plan to write any D (as a language reference itself, it’s already dated in a number of ways, but I still recommend it for the ideas it discusses). Also browse the <a href="https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs">D Gems</a> section in the D tour. In the meantime, let me show you what I learned about D while using it.</p>
<h1>Writing D every day for over 25 days</h1>
<p>I took slightly longer than 25 days to write my advent of code solutions, partly because some stumped me a little and partly because around actual Christmas I wanted to spend time with family instead of writing code. When I was writing code, I would say that nearly every day of advent of code forced me to look into a new aspect of D. You can see my solutions <a href="http://inversethought.com/hg/aoc">in this Mercurial repository.</a></p>
<p>I am not going to go too much into details about the abstract theory concerning the solution of each problem. Perhaps another time. I will instead focus on the specific D techniques I learned about or found most useful for each.</p>
<h1>Contents</h1>
<ol>
<li>
<a href="http://jordi.inversethought.com/feed/#day01">Day 1: parsing arguments, type conversions, template constraints</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day02">Day 2: functional programming and uniform function call syntax</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day03">Day 3: let’s try some complex arithmetic!</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day04">Day 4: reusing familiar tools to find duplicates</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day05">Day 5: more practice with familiar tools</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day06">Day 6: ranges</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day07">Day 7: structs and compile-time regexes</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day08">Day 8: more compile-time fun with mixin</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day09">Day 9: a switch statement!</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day10">Day 10: learning what ranges <em>cannot</em> do</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day11">Day 11: offline hex coding</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day12">Day 12: for want of a set</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day13">Day 13: more offline coding</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day14">Day 14: reusing older code as a module</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day15">Day 15: generators, lambdas, functions, and delegates</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day16">Day 16: permutations with primitive tools</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day17">Day 17: avoiding all the work with a clever observation</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day18">Day 18: concurrency I can finally understand and write correctly</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day19">Day 19: string parsing with enums and final switches</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day20">Day 20: a physics problem with vector operations</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day21">Day 21: an indexable, hashable, comparable struct</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day22">Day 22: more enums, final switches, and complex numbers</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day23">Day 23: another opcode parsing problem</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day24">Day 24: a routine graph-search problem</a>
</li>
<li>
<a href="http://jordi.inversethought.com/feed/#day25">Day 25: formatted reads to finish off Advent of D</a>
</li>
</ol>
<p><a name="day01"></a></p>
<h2>Day 1: parsing arguments, type conversions, template constraints</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day01/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day01/app.d">my solution</a>)</p>
<p>For Day 1, I was planning to be a bit more careful about everything around the code. I was going to carefully parse CLI arguments, produce docstrings and error messages when anything went wrong, and carefully validate template arguments with constraints (comparable to <a href="https://en.wikipedia.org/wiki/Concepts_(C%2B%2B)">concepts in C++</a>). While I could have done all of this, as days went by I tried to <abbr title="Minimise program length">golf</abbr> my solutions, so I abandoned most of this boilerplate. Instead, I lazily relied on getting D stack traces at runtime or compiler errors when I messed up.</p>
<p>As you can see from my solution, had I kept it up, the boilerplate isn’t <em>too</em> bad, though. Template constraints are achieved by adding <code class="codecolorer d solarized-light"><span class="d"><span>if</span><span>(</span>isNumeric<span>!</span>numType<span>)</span></span></code>, which checks at compile time that my template was given a template argument of the correct type, where <code class="codecolorer d solarized-light"><span class="d">isNumeric</span></code> comes from <code class="codecolorer d solarized-light"><span class="d"><span>import</span> std.<span>traits</span></span></code>. I also found that <code class="codecolorer d solarized-light"><span class="d">getopt</span></code> was a sufficiently mature standard library for handling command-line parsing. It’s not quite as rich as Python’s <code class="codecolorer d solarized-light"><span class="d">argparse</span></code>, merely sufficient. This about shows all it can do:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> <span>string</span> input<span>;</span><br />
<span>auto</span> opts <span>=</span> getopt<span>(</span><br />
args<span>,</span><br />
<span>"input|i"</span><span>,</span> <span>"Input captcha to process"</span><span>,</span> <span>&</span>input<br />
<span>)</span><span>;</span><br />
<br />
<span>if</span> <span>(</span>opts.<span>helpWanted</span><span>)</span> <span>{</span><br />
defaultGetoptPrinter<span>(</span><span>"Day 1 of AoC"</span><span>,</span> opts.<span>options</span><span>)</span><span>;</span><br />
<span>}</span></div></div>
<p>Finally, a frequent workhorse that appeared from Day 1 was <code class="codecolorer d solarized-light"><span class="d">std.<span>conv</span></span></code> for parsing strings into numbers. A single function, <code class="codecolorer d solarized-light"><span class="d">to</span></code> is surprisingly versatile and does much more than that, by taking a single template argument for converting (not casting) one type into another. It knows not only how to parse strings into numbers and vice versa, but also how to convert numerical types keeping as much precision as possible or reading list or <abbr title="dict">associative array</abbr> literals from strings if they are in their standard string representation. It’s a good basic example of D’s power and flexibility in generic programming.</p>
<p><a name="day02"></a></p>
<h2>Day 2: functional programming and uniform function call syntax</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day02/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day02/app.d">my solution</a>)</p>
<p>For whatever reason, probably because I was kind of trying to golf my solutions, I ended up writing a lot of functionalish code, with lots of map, reduce, filter, and so forth. This started early on with Day 2. D is mostly unopinionated about which style of programming one should use and offers tools to do object-orientation, functional programming, or just plain procedural programming, presenting no obstacle to the mixing these styles. Lambdas are easily written inline with concise syntax, e.g. <code class="codecolorer d solarized-light"><span class="d">x <span>=></span> x<span>*</span>x</span></code>, and the basic standard functional tools like <code class="codecolorer d solarized-light"><span class="d">map<span>,</span> reduce<span>,</span> filter</span></code> and so on are available.</p>
<p>D’s approach to functional programming is quite pragmatic. While I rarely used it, because I wasn’t being too careful for these solutions, D functions can be labelled <a href="https://dlang.org/spec/function.html#pure-functions"><code class="codecolorer d solarized-light"><span class="d"><span>pure</span></span></code></a>, which means that they can have no side effects. However, this still lets them do local impure things such as reassigning a variable or having a for loop. The only restriction is that all of their impurity must be “on the stack”, and that they cannot call any impure functions themselves.</p>
<p>Another feature that I came to completely fall in love with was what they call <a href="https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs">uniform function call syntax</a> (UFCS). With some caveats, this basically means that</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> foo.<span>bar</span><span>(</span>baz<span>)</span></div></div>
<p>is just sugar for</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> bar<span>(</span>foo<span>,</span> baz<span>)</span></div></div>
<p>If the function only has one argument, the round brackets are optional and <code class="codecolorer text solarized-light"><span class="text">foo.bar</span></code> is sugar for <code class="codecolorer text solarized-light"><span class="text">bar(foo)</span></code>. This very basic syntactic convenience makes it so easy and pleasant to chain function calls together, lending itself to making it more inviting to write functional code. It also is a happy unification between OOP and FP, because syntactically it’s the same to give an object a new member function as it is to create a free-standing function whose first argument is the object.</p>
<p><a name="day03"></a></p>
<h2>Day 3: let’s try some complex arithmetic!</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day03/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day03/app.d">my solution</a>)</p>
<p>For me, 2-dimensional geometry is often very well described by complex numbers. The spiral in the problem here seemed easy to describe as an <abbr title="dict">associative array</abbr> from complex coordinates to integer values. So, I decided to give D’s <code class="codecolorer text solarized-light"><span class="text">std.complex</span></code> a try. It was easy to use and there were no big surprises here.</p>
<p><a name="day04"></a></p>
<h2>Day 4: reusing familiar tools to find duplicates</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day04/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day04/app.d">my solution</a>)</p>
<p>There weren’t any new D techniques here, but it was nice to see how easy it was to build a simple word counter from D builtins. Slightly disappointed that this data structure itself wasn’t builtin like Python’s own <code class="codecolorer text solarized-light"><span class="text">collections.Counter</span></code> but hardly an insurmountable problem.</p>
<p><a name="day05"></a></p>
<h2>Day 5: more practice with familiar tools</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day05/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day05/app.d">my solution</a>)</p>
<p>Again, not much new D here. I like the relative ease with which it’s possible to read integers into a list using <code class="codecolorer text solarized-light"><span class="text">map</span></code> and <code class="codecolorer text solarized-light"><span class="text">std.conv.to</span></code>.</p>
<p><a name="day06"></a></p>
<h2>Day 6: ranges</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day06/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day06/app.d">my solution</a>)</p>
<p>There’s usually a fundamental paradigm or structure in programming languages out of which everything else depends on. Haskell has functions and monads, C has pointers and arrays, C++ has classes and templates, Python has dicts and iterators, Javascript has callbacks and objects, Rust has borrowing and immutability. Ranges are one of D’s fundamental concepts. Roughly speaking, a range is anything that can be iterated over, like an array or a lazy generator. Thanks to D’s powerful metaprogramming, ranges can be defined to satisfy a kind of compile-time duck typing: if it has methods to check for emptiness, get the first element, and get the next element, then it’s an <code class="codecolorer text solarized-light"><span class="text">InputRange</span></code>. This duck typing is kind of reminiscent of type classes in Haskell. D’s general principle of having containers and algorithms on those containers is built upon the range concept. Ranges are intended to be simpler reformulation of iterators from the C++ standard libary.</p>
<p>I have been using ranges all along, as <code class="codecolorer text solarized-light"><span class="text">foreach</span></code> loops are kind of like sugar for invoking those methods on ranges. However, for day 6 I actually wanted to use a method that had to invoke an <code class="codecolorer text solarized-light"><span class="text">std.range</span></code> method, <code class="codecolorer text solarized-light"><span class="text">enumerate</span></code>. It simply iterates over a range while simultaneously producing a counter. This I used to write some brief code to obtain both the maximum of an array and the index in which it occurs.</p>
<p>Another range-related feature that appears for the first time here is slicing. Certain random-access ranges which allow integer indexing also allow slicing. The typical method to remove elements from an array is to use this slicing. For example, to remove the first five elements and the last two elements from an array:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> arr <span>=</span> arr<span>[</span><span>5</span><span>..</span>$<span>-</span><span>2</span><span>]</span><span>;</span></div></div>
<p>Here the dollar sign is sugar for <code class="codecolorer text solarized-light"><span class="text">arr.length</span></code> and this removal is simply done by moving some start and end pointers in memory — no other bytes are touched.</p>
<p>The D Tour has <a href="https://tour.dlang.org/tour/en/basics/ranges">a good taste of ranges</a> and <em>Programming in D</em> goes into <a href="http://ddili.org/ders/d.en/ranges.html">more depth</a>.</p>
<p><a name="day07"></a></p>
<h2>Day 7: structs and compile-time regexes</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day07/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day07/app.d">my solution</a>)</p>
<p>My solution for this problem was more complicated, and it forced me to break out an actual tree data structure. Because I wasn’t trying to be particularly parsimonious about memory usage or execution speed, I decided to create the tree by having a node struct with a global associative array indexing all of the nodes.</p>
<p>In D, structs have value semantics and classes have reference semantics. Roughly, this means that structs are on the stack, they get copied around when being passed into functions, while classes are always handled by reference instead and dynamically allocated and destroyed. Another difference between structs and classes is that classes have inheritance (and hence, polymorphic dispatch) but structs don’t. However, you can give structs methods, and they will have an implicit <code class="codecolorer d solarized-light"><span class="d"><span>this</span></span></code> parameter, although this is little more than sugar for free-standing functions.</p>
<p>Enough on OOP. Let’s talk about the really exciting stuff: compile-time regular expressions!</p>
<p>For this problem, there was some input parsing to do. Let’s look at what I wrote:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>void</span> parseLine<span>(</span><span>string</span> line<span>)</span> <span>{</span> <br />
<span>static</span> nodeRegex <span>=</span> regex<span>(</span><span>r"(?P<name>\w+) \((?P<weight>\d+)\)( -> (?P<children>[\w,]+))?"</span><span>)</span><span>;</span> <br />
<span>auto</span> row <span>=</span> matchFirst<span>(</span>line<span>,</span> nodeRegex<span>)</span><span>;</span> <br />
<span>// init the node struct here </span><br />
<span>}</span></div></div>
<p>The <code class="codecolorer text solarized-light"><span class="text">static</span></code> keyword instructs D that this variable has to be computed at compile-time. D’s compiler basically has its own interpreter that can execute arbitrary code as long as all of the inputs are available at compile time. In this case, this parses and compiles this regex into the binary. The next line, where I call <code class="codecolorer text solarized-light"><span class="text">matchFirst</span></code> on each line, is done at runtime, but if for whatever reason I had these strings available at compile time (say, defined as a big inline string a few lines above the same source file), I could also do the regex parsing at compile time if I wanted to.</p>
<p>This is really nice. This is one of my favourite D features. Add a <code class="codecolorer text solarized-light"><span class="text">static</span></code> and you can precompute into your binary just about anything. You often don’t even need any extra syntax. If the compiler realises that it has all of the information at compile time to do something, it might just do it. This is known as compile-time function execution, hereafter, CTFE. The D Tour has <a href="https://tour.dlang.org/tour/en/gems/compile-time-function-evaluation-ctfe">a good overview of the topic</a>.</p>
<p><a name="day08"></a></p>
<h2>Day 8: more compile-time fun with mixin</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day08/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day08/app.d">my solution</a>)</p>
<p>Day 8 was another problem where the most interesting part was parsing. As before, I used a compile-time regex. But the interesting part of this problem was the following bit of code for parsing strings into their corresponding D comparison operation, as I originally wrote it:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>auto</span> comparisons <span>=</span> <span>[</span><br />
<span>"<"</span><span>:</span> <span>function</span><span>(</span><span>int</span> a<span>,</span> <span>int</span> b<span>)</span> <span>=></span> a <span><</span> b<span>,</span> <br />
<span>">"</span><span>:</span> <span>function</span><span>(</span><span>int</span> a<span>,</span> <span>int</span> b<span>)</span> <span>=></span> a <span>></span> b<span>,</span><br />
<span>"=="</span><span>:</span> <span>function</span><span>(</span><span>int</span> a<span>,</span> <span>int</span> b<span>)</span> <span>=></span> a <span>==</span> b<span>,</span><br />
<span>"<="</span><span>:</span> <span>function</span><span>(</span><span>int</span> a<span>,</span> <span>int</span> b<span>)</span> <span>=></span> a <span><=</span> b<span>,</span><br />
<span>">="</span><span>:</span> <span>function</span><span>(</span><span>int</span> a<span>,</span> <span>int</span> b<span>)</span> <span>=></span> a <span>>=</span> b<span>,</span><br />
<span>"!="</span><span>:</span> <span>function</span><span>(</span><span>int</span> a<span>,</span> <span>int</span> b<span>)</span> <span>=></span> a <span>!=</span> b<span>,</span> <br />
<span>]</span><span>;</span></div></div>
<p>Okay, this isn’t terrible. It’s just… not very pretty. I don’t like that it’s basically the same line repeated six times. I furthermore also don’t like that within each line, I have to repeat the operator in the string part and in the function body. Enter the <code class="codecolorer text solarized-light"><span class="text">mixin</span></code> keyword! Basically, string mixins allow you to evaluate any string at compile time. They’re kind of like the C preprocessor, but much safer. For example, string mixins only evaluate complete expressions, so no shenanigans like <code class="codecolorer cpp solarized-light"><span class="cpp"><span>#define private public</span></span></code> are allowed. My first attempt to shorten the above looked like this:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>bool</span> <span>function</span><span>(</span><span>int</span><span>,</span><span>int</span><span>)</span><span>[</span><span>string</span><span>]</span> comparisons<span>;</span> <br />
<span>static</span> <span>foreach</span><span>(</span>cmp<span>;</span> <span>[</span><span>"<"</span><span>,</span> <span>">"</span><span>,</span> <span>"=="</span><span>,</span> <span>"<="</span><span>,</span> <span>">="</span><span>,</span> <span>"!="</span><span>]</span><span>)</span> <span>{</span> <br />
comparisons<span>[</span>cmp<span>]</span> <span>=</span> <span>mixin</span><span>(</span><span>"function(int a, int b) => a "</span><span>~</span>cmp<span>~</span><span>" b"</span><span>)</span><span>;</span> <br />
<span>}</span></div></div>
<p>Since I decided to use a compile-time static loop to populate my array, I now needed a separate declaration of the variable which forced me to spell out its ungainly type: an associative array that takes a <code class="codecolorer d solarized-light"><span class="d"><span>string</span></span></code> and returns a function with that signature. The mixin here takes a concatenated string that evaluates to a function.</p>
<p>However, this didn’t work for two reasons!</p>
<p>The first one is that <code class="codecolorer d solarized-light"><span class="d"><span>static</span> <span>foreach</span></span></code> was <a href="https://dlang.org/blog/2017/09/01/dmd-2-076-0-released/">introduced on September 2017</a>. The D compilers packaged in Debian didn’t have it yet when I wrote that code! The second problem is more subtle: initialisation of associative arrays currently cannot be statically done because their internal data structures rely on runtime computations, according to my understanding of <a href="http://jordi.inversethought.com/feed///forum.dlang.org/thread/CANHcaG=vACzvcD=xSXaiCNe4FiUJAW7VPRQaPoxEh2-su9+GNg@mail.gmail
.com">this discussion</a>. They might fix it some day?</p>
<p>So, next best thing is my final answer:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>bool</span> <span>function</span><span>(</span><span>int</span><span>,</span><span>int</span><span>)</span><span>[</span><span>string</span><span>]</span> comparisons<span>;</span><br />
<br />
<span>auto</span> getComparisons<span>(</span>Args<span>...</span><span>)</span><span>(</span><span>)</span> <span>{</span> <br />
<span>foreach</span><span>(</span>cmp<span>;</span> Args<span>)</span> <span>{</span> <br />
comparisons<span>[</span>cmp<span>]</span> <span>=</span> <span>mixin</span><span>(</span><span>"function(int a, int b) => a "</span><span>~</span>cmp<span>~</span><span>" b"</span><span>)</span><span>;</span> <br />
<span>}</span> <br />
<span>return</span> comparisons<span>;</span> <br />
<span>}</span><br />
<br />
<span>shared</span> <span>static</span> <span>this</span><span>(</span><span>)</span> <span>{</span> <br />
comparisons <span>=</span> getComparisons<span>!</span><span>(</span><span>"<"</span><span>,</span> <span>">"</span><span>,</span> <span>"=="</span><span>,</span> <span>"<="</span><span>,</span> <span>">="</span><span>,</span> <span>"!="</span><span>)</span><span>;</span> <br />
<span>}</span></div></div>
<p>Alright, by size this is hardly shorter than the repetitive original. But I still think it’s better! It has no dull repetition where bugs are most often introduced, and it’s using a variable-argument templated function so that the mixin can have its values available at compile time. It uses the next best thing to compile-time initialisation, which is a module initialiser <code class="codecolorer d solarized-light"><span class="d"><span>shared</span> <span>static</span> <span>this</span><span>(</span><span>)</span></span></code> that just calls the function to perform the init.</p>
<p><a name="day09"></a></p>
<h2>Day 9: a switch statement!</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day09/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day09/app.d">my solution</a>)</p>
<p>Day 9 was a simpler parsing problem, so simple that instead of using a regex I decided to just use a switch statement. There isn’t anything terribly fancy about switch statements, and they work almost exactly the same as they do in other languages. The only distinct features of switch statements in D is that they work on numeric, string, or bool types and that they have deprecated implicit fallthrough. Fallthrough instead must be explicitly done with <code class="codecolorer d solarized-light"><span class="d"><span>goto</span> <span>case</span><span>;</span></span></code> or will be once the deprecation is complete.</p>
<p>Oh, and you can also specify ranges for a case statement, e.g.</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> <span>case</span> <span>'a'</span><span>:</span> <span>..</span> <span>case</span> <span>'z'</span><span>:</span><br />
<span>// do stuff with lowercase ASCII</span><br />
<span>break</span><span>;</span></div></div>
<p>It’s the small conveniences that make this pleasant. <em>Programming in D</em> has <a href="http://ddili.org/ders/d.en/switch_case.html">a good discussion</a> on switch statements.</p>
<p><a name="day10"></a></p>
<h2>Day 10: learning what ranges <em>cannot</em> do</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day10/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day10/app.d">my solution</a>)</p>
<p>So, superficially, you might think that expressions like <code class="codecolorer d solarized-light"><span class="d">arr<span>[</span><span>2</span><span>..</span>$<span>-</span><span>2</span><span>]</span></span></code>, which is valid, would also allow for things like <code class="codecolorer d solarized-light"><span class="d">arr<span>[</span>$<span>-</span><span>2</span><span>..</span><span>1</span><span>]</span></span></code> to traverse the array in reverse order or some other syntax for having a different step size than +1. At least I did. These kinds of array indexing are common in numeric-based arrays such as Octave, Julia, R, or Python’s numpy. So for day 10’s hash, which requires reversing an array, I thought I could just do that.</p>
<p>Turns out that the language doesn’t have syntax to allow this, but after <a href="https://dlang.org/phobos/std_algorithm_mutation.html#.reverse">a quick trip to the standard library</a> I found the necessary functions. What I thought could be written as</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer">arr<span>[</span>a<span>..</span><span>b</span><span>]</span> <span>=</span> arr<span>[</span>b<span>..</span><span>a</span><span>]</span><span>;</span></div></div>
<p>instead became</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer">reverse<span>(</span>arr<span>[</span>a<span>..</span><span>b</span><span>]</span><span>)</span><span>;</span></div></div>
<p>Other than this minor discovery about ranges, Day 10 was more about getting the algorithm right than using any specialised D utilities. Since real hashes typically allow several sizes, I templated the hash functions with the total size, rounds of hashing, and chunk size, with a template constraint that the chunk size must divide the total size:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>auto</span> getHash<span>(</span><span>int</span> Size<span>=</span><span>256</span><span>,</span> <span>int</span> Rounds<span>=</span><span>64</span><span>,</span> <span>int</span> ChunkSize<span>=</span><span>16</span><span>)</span><span>(</span><span>string</span> input<span>)</span> <br />
<span>if</span><span>(</span> Size <span>%</span> ChunkSize <span>==</span> <span>0</span><span>)</span> <br />
<span>{</span> <br />
<span>// ... </span><br />
<span>}</span></div></div>
<p>Nothing new here. I just like that template constraints are so easy to write.</p>
<p><a name="day11"></a></p>
<h2>Day 11: offline hex coding</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day11/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day11/app.d">my solution</a>)</p>
<p>I did most of Day 11 on paper. It took me a while to figure out a proper hex coordinate system and what the distance function in that coordinate system should be. I had seen hex coordinates from playing <a href="http://wesnoth.org/">Battle for Wesnoth</a>, but took me a while to figure them out again. Once I had that, the actual D code is pretty simple and used no techniques I hadn’t seen before. I think this is the first time I used the <code class="codecolorer d solarized-light"><span class="d">cumulativeFold</span></code> function, but other than that, nothing to see here. An immutable global <abbr title="dict">associative array</abbr> populated at module init time like before,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>pure</span> <span>static</span> <span>this</span><span>(</span><span>)</span><span>{</span> <br />
directions <span>=</span> <span>[</span><br />
<span>"ne"</span><span>:</span> <span>[</span><span>1</span><span>,</span><span>1</span><span>]</span><span>,</span><br />
<span>"n"</span><span>:</span> <span>[</span><span>0</span><span>,</span><span>1</span><span>]</span><span>,</span><br />
<span>"nw"</span><span>:</span> <span>[</span><span>-</span><span>1</span><span>,</span><span>0</span><span>]</span><span>,</span><br />
<span>"sw"</span><span>:</span> <span>[</span><span>-</span><span>1</span><span>,-</span><span>1</span><span>]</span><span>,</span><br />
<span>"s"</span><span>:</span> <span>[</span><span>0</span><span>,-</span><span>1</span><span>]</span><span>,</span><br />
<span>"se"</span><span>:</span> <span>[</span><span>1</span><span>,</span><span>0</span><span>]</span><span>,</span><br />
<span>]</span><span>;</span> <br />
<span>}</span></div></div>
<p>and that’s it.</p>
<p><a name="day12"></a></p>
<h2>Day 12: for want of a set</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day12/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day12/app.d">my solution</a>)</p>
<p>The only new D technique for this problem was that I decided to use a set structure to keep track of which graph nodes had been visited. The only problem is that D doesn’t have a built-in set structure (yet?), but it does have a <code class="codecolorer d solarized-light"><span class="d">setDifference</span></code> function. It’s a bit clunky. It only works on ordered arrays, but that was sufficient for my purpose here, and probably not much worse than hashing with a traditional set structure would have been.</p>
<p>One further observation: D has an <code class="codecolorer d solarized-light"><span class="d"><span>in</span></span></code> keyword, which can be used to test membership, like in Python (it also has an unrelated use for defining input and output arguments to functions), but unlike Python, only for associative arrays. This makes sense, because the complexity of testing for membership for other data structures can vary widely depending on the structure and the chosen algorithm, and there isn’t a clear universal choice like there is for associative arrays.</p>
<p>If desired, however, it’s possible to define the <code class="codecolorer d solarized-light"><span class="d"><span>in</span></span></code> operator for any other class, like so:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>bool</span> opBinaryRight<span>!</span><span>(</span><span>"in"</span><span>)</span><span>(</span>T elt<span>)</span> <span>{</span> <br />
<span>// check that elt is in `this` </span><br />
<span>}</span></div></div>
<p>I would assume that’s what you could use to write a set class for D.</p>
<p><a name="day13"></a></p>
<h2>Day 13: more offline coding</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day13/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day13/app.d">my solution</a>)</p>
<p>This one is another where I did most of the solution on paper and thus managed to write a very short program. No new D techniques here, just the usual functionalish style that I seem to be developing.</p>
<p><a name="day14"></a></p>
<h2>Day 14: reusing older code as a module</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day14/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day14/app.d">my solution</a>)</p>
<p>The problem here is interesting because I’ve solved this labelling of connected components problem before in C++ for GNU Octave. I wrote <a href="https://sourceforge.net/p/octave/image/ci/1b8b83d01211/tree/src/bwlabeln.cc#l370">the initial bwlabeln implementation</a> using <a href="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">union-find</a>. I was tempted to do the same here, but I couldn’t think of a quick way to do so, and talking to others in the #lobsters channel in IRC, I realised that a simpler recursive solution would work without overflowing the stack (because the problem is small enough, not because a stack-based algorithm is clever).</p>
<p>The interesting part is reusing an earlier solution, the hashing algorithm from <a href="http://jordi.inversethought.com/feed/#day10">Day 10</a>. At first blush, this is quite simple: every D file also creates its own module, namespaced if desired by directories. It’s very reminiscent of Python’s <code class="codecolorer python solarized-light"><span class="python"><span>import</span></span></code> statement and module namespacing. The only snag is that my other file has a <code class="codecolorer d solarized-light"><span class="d"><span>void</span> main<span>(</span><span>string</span><span>[</span><span>]</span> args<span>)</span></span></code> function and so does this one. The linker won’t like that duplicate definition of symbols. For this purpose, D offers conditional compilation, which in C and C++ is usually achieved via <a href="http://www.c4learn.com/c-programming/c-ifdef-conditional-compilation-directives/">a familiar C preprocessor macro idiom.</a></p>
<p>In D, this idiom is codified into the language proper via the <code class="codecolorer d solarized-light"><span class="d"><span>version</span></span></code> kewyord, like so</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>version</span><span>(</span>standalone<span>)</span> <span>{</span><br />
<span>void</span> main<span>(</span><span>string</span><span>[</span><span>]</span> args<span>)</span><span>{</span> <br />
<span>// do main things here </span><br />
<span>}</span> <br />
<span>}</span></div></div>
<p>This instructs the compiler to compile the inside of the <code class="codecolorer d solarized-light"><span class="d"><span>version</span></span></code> block only if an option called “standalone” is passed in,</p>
<div class="codecolorer-container bash solarized-light"><div class="bash codecolorer">gdc <span>-O2</span> <span>-fversion</span>=standalone app.d <span>-o</span> day10</div></div>
<p>or, with regrettably slightly different flags,</p>
<div class="codecolorer-container bash solarized-light"><div class="bash codecolorer">ldc2 <span>-O2</span> <span>-d-version</span>=standalone app.d <span>-of</span> day10</div></div>
<p>There are other built-in arguments for <code class="codecolorer d solarized-light"><span class="d"><span>version</span></span></code>, <a href="https://dlang.org/spec/version.html#predefined-versions">such as “linux” or “OSX” to conditionally compile for a particular operating system</a>. This keyword offers quite a bit of flexibility for conditional compilation, and it’s a big improvement over C preprocessor idioms.</p>
<p><a name="day15"></a></p>
<h2>Day 15: generators, lambdas, functions, and delegates</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day15/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day15/app.d">my solution</a>)</p>
<p>This problem was an opportunity to test out a new function, <code class="codecolorer d solarized-light"><span class="d">generate</span></code>, which takes a function and iterates it repeatedly on a range. Haskell calls this one <code class="codecolorer haskell solarized-light"><span class="haskell"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:iterate"><span>iterate</span></a></span></code>, which I think is a better name. It’s also a lazy generator, so you need something like <code class="codecolorer d solarized-light"><span class="d">take</span></code> to say how much of the generator do you want to use. For example, the Haskell code</p>
<div class="codecolorer-container haskell solarized-light"><div class="haskell codecolorer">pows <span>=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:take"><span>take</span></a> <span>11</span> <span>$</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:iterate"><span>iterate</span></a> <span>(</span><span>\</span>x <span>-></span> x<span>*</span><span>2</span><span>)</span> <span>1</span></div></div>
<p>can be translated into D as</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>auto</span> x <span>=</span> <span>1</span><span>;</span><br />
<span>auto</span> pows <span>=</span> generate<span>!</span><span>(</span>x <span>=></span> x<span>*</span><span>2</span><span>)</span>.<span>take</span><span>(</span><span>11</span><span>)</span><span>;</span></div></div>
<p>There are <a href="https://dlang.org/phobos/std_range.html#generate">other examples in the documentation</a>.</p>
<p>Let also take a moment here to talk about the different anonymous functions in D. The following both declare a function that squares its input:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>function</span><span>(</span><span>int</span> a<span>)</span> <span>{</span> <span>return</span> a<span>^^</span><span>2</span><span>;</span><span>}</span><br />
<span>delegate</span><span>(</span><span>int</span> a<span>)</span> <span>{</span> <span>return</span> a<span>^^</span><span>2</span><span>;</span><span>}</span></div></div>
<p>The difference is just a question of closure. The <code class="codecolorer d solarized-light"><span class="d"><span>delegate</span></span></code> version carries a hidden pointer to its enclosing scope, so it can dynamically close over the outer scope variables. If you can’t afford to pay this runtime penalty, the <code class="codecolorer d solarized-light"><span class="d"><span>function</span></span></code> version doesn’t reference the enclosing scope (no extra pointer). So, for a generator, you typically want to use a <code class="codecolorer d solarized-light"><span class="d"><span>delegate</span></span></code>, since you want the generator to remember its scoped variables across successive calls, like what I did:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>auto</span> generator<span>(</span><span>ulong</span> val<span>,</span> <span>ulong</span> mult<span>)</span> <span>{</span><br />
<span>return</span> generate<span>!</span><span>(</span><span>delegate</span><span>(</span><span>)</span><span>{</span><br />
val <span>=</span> <span>(</span>val <span>*</span> mult<span>)</span> <span>%</span> <span>2147483647</span><span>;</span> <br />
<span>return</span> val<span>;</span><br />
<span>}</span><br />
<span>)</span><span>;</span><br />
<span>}</span></div></div>
<p>This function returns a generator range where each entry will result in a new entry of this <a href="https://en.wikipedia.org/wiki/Linear_congruential_generator">pseudorandom linear congruence generator</a>.</p>
<p>The <code class="codecolorer d solarized-light"><span class="d"><span>delegate</span></span></code>/<code class="codecolorer d solarized-light"><span class="d"><span>function</span></span></code> is part of the type, and can be omitted if it can be inferred by context (e.g. when passing a function into another function as an argument). Furthermore, there’s a lambda shorthand that I have been using all along, where the <code class="codecolorer d solarized-light"><span class="d"><span>{</span><span>return</span> foo<span>;</span><span>}</span></span></code> boilerplate can be shortened to just <code class="codecolorer d solarized-light"><span class="d"><span>=></span></span></code> like so:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> <span>(</span>a<span>)</span> <span>=></span> a<span>^^</span><span>2</span></div></div>
<p>This form is only valid where there’s enough context to infer if it’s a <code class="codecolorer d solarized-light"><span class="d"><span>delegate</span></span></code> or a <code class="codecolorer d solarized-light"><span class="d"><span>function</span></span></code>, as well as the type of <code class="codecolorer d solarized-light"><span class="d">a</span></code> itself. More details in <a href="https://dlang.org/spec/expression.html#function_literals">the language spec</a>.</p>
<p><a name="day16"></a></p>
<h2>Day 16: permutations with primitive tools</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day16/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day16/app.d">my solution</a>)</p>
<p>This permutations problem made me reach for the <code class="codecolorer d solarized-light"><span class="d">std.<span>algorithm</span></span></code> function <code class="codecolorer d solarized-light"><span class="d">bringToFront</span></code> for cyclicly permuting an array in place like so,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> bringToFront<span>(</span>progs<span>[</span>rot<span>..</span>$<span>]</span><span>,</span> progs<span>[</span><span>0</span><span>..</span><span>rot</span><span>]</span><span>)</span><span>;</span></div></div>
<p>It’s a surprisingly versatile function that can be used to perform more tricks than cyclic permutations. Its documentation is <a href="https://dlang.org/phobos/std_algorithm_mutation.html#.bringToFront">worth a read</a>.</p>
<p>I also ran into <a href="https://issues.dlang.org/show_bug.cgi?id=16959">a D bug here</a>. I had to create a character array from an immutable input string, but due to Unicode-related reasons that D has for handling characters especially, I had to cast to <code class="codecolorer d solarized-light"><span class="d"><span>ubyte</span><span>[</span><span>]</span></span></code> instead of <code class="codecolorer d solarized-light"><span class="d"><span>char</span><span>[</span><span>]</span></span></code>.</p>
<p>Besides that, for the second part where you had to realise that permutations cannot have too big of an <a href="https://en.wikipedia.org/wiki/Group_action#Orbits_and_stabilizers">orbit</a>, I also ended up using a string array with the <code class="codecolorer d solarized-light"><span class="d">canFind</span></code> from <code class="codecolorer d solarized-light"><span class="d">std.<span>algorithm</span></span></code>. I would have preferred a string set with hashing instead of linear searching, but it didn’t make a huge difference for the size of this problem.</p>
<p>I really want sets in the D standard library. Maybe I should see what I can do to make them happen.</p>
<p><a name="day17"></a></p>
<h2>Day 17: avoiding all the work with a clever observation</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day17/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day17/app.d">my solution</a>)</p>
<p>This puzzle is a variation of the <a href="https://en.wikipedia.org/wiki/Josephus_problem">Josephus problem</a>. I needed some help from #lobsters in IRC to figure out how to solve it. There aren’t any new D techniques, just some dumb array concatenation with the tilde operator for inserting elements into an array:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer">circ <span>=</span> circ<span>[</span><span>0</span><span>..</span><span>pos</span><span>]</span> <span>~</span> y <span>~</span> circ<span>[</span>pos<span>..</span>$<span>]</span><span>;</span></div></div>
<p>The second part can be solved via the simple observation that you only<br />
need to track one position, the one immediately following zero.</p>
<p><a name="day18"></a></p>
<h2>Day 18: concurrency I can finally understand and write correctly</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day18/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day18/app.d">my solution</a>)</p>
<p>This day was an exciting one for me. Discussing this problem with others, it seems many people had much difficulty solving this problem in other programming languages. Most people seemed to have to emulate their own concurrency with no help from their programming language of choice. In contrast, D absolutely shined here, because it is based on <a href="https://en.wikipedia.org/wiki/Actor_model">the actor concurrency model (message passing)</a>, which precisely fits the problem statement. (There are other concurrency primitives in case the actor concurrency model isn’t sufficient, but it was sufficient for me.)</p>
<p>The basic idea of concurrency in D is that each thread of execution localises all of its state. By default, threads share no data. In order to communicate with each other, threads pass messages. A thread can indicate at any time when it’s ready to send or receive messages. Messages can be any type, and each thread says what type it’s expecting to receive. If a thread receives a type it’s not prepared to handle, it will throw an exception.</p>
<p>There are more details, such as what happens if a thread receives too many messages but doesn’t respond to any of them. Let’s not go into that now. Basic idea: threads get spawned, threads send and receive messages.</p>
<p>Let’s spend a little bit of time looking at the relevant functions and types I used, all defined in <code class="codecolorer d solarized-light"><span class="d">std.<span>concurrency</span></span></code></p>
<dl>
<dt>spawn</dt>
<dd>
Starts a thread of execution. The first argument is a reference to the function that this thread will execute, along with any arguments that function may take. Returns a <code class="codecolorer d solarized-light"><span class="d">Tid</span></code> type, a thread ID. This is used as the address to send messages to. A thread can refer to its parent thread via the special variable <code class="codecolorer d solarized-light"><span class="d">ownerTid</span></code>.</dd></dl>
<p> Unless explicitly declared <code class="codecolorer d solarized-light"><span class="d"><span>shared</span></span></code>, the arguments of a threaded function must be immutable. This is how the compiler guarantees no race conditions when manipulating those variables. Of course, with <code class="codecolorer d solarized-light"><span class="d"><span>shared</span></span></code> variables, the programmer is signalling that they are taking over synchronisation of that data, which may require using low-level mutexes.
</p>
<dt>send</dt>
<dd>Send a message to a particular thread. The first argument is the thread id. The other arguments can be anything. It’s up to the receiving thread to handle the arguments it receives.</dd>
<dt>receiveOnly</dt>
<dd>Indicate that this thread is ready to receive a single type, and returns the value of that type. The type must of course be specified as a compile-time argument.</dd>
<dt>receive</dt>
<dd>Indicates what to do with any of several possible types. The arguments to this function are a collection of functions, whose parameters types will be dynamically type-matched with received types. I didn’t need this function, but I wanted to mention it exists.</dd>
<dt>receiveTimeout</dt>
<dd>The problem statement is designed to deadlock. Although there probably is a more elegant solution, timing out on deadlock was the solution I wrote. This function does just that: listens for a message for a set of amount of time. If a message is received in the designated time, its handler function is executed and <code class="codecolorer d solarized-light"><span class="d">receiveTimeout</span></code> returns <code class="codecolorer d solarized-light"><span class="d"><span>true</span></span></code>. If the timeout happens, it returns <code class="codecolorer d solarized-light"><span class="d"><span>false</span></span></code> instead.</dd>
<p>Armed with these tools, the solution was a breeze to write. I first spawn two threads and save their thread ids,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> <span>auto</span> tid1 <span>=</span> spawn<span>(</span><span>&</span>runProgram<span>,</span> opcodes<span>,</span> <span>0</span><span>)</span><span>;</span><br />
<span>auto</span> tid2 <span>=</span> spawn<span>(</span><span>&</span>runProgram<span>,</span> opcodes<span>,</span> <span>1</span><span>)</span><span>;</span></div></div>
<p>Each of the two threads defined by <code class="codecolorer d solarized-light"><span class="d">runProgram</span></code> then immediately stops, waiting for a thread id, to know whom to talk to,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>void</span> runProgram<span>(</span><span>immutable</span> <span>string</span><span>[</span><span>]</span> opcodes<span>,</span> <span>ulong</span> pid<span>)</span> <span>{</span><br />
<span>auto</span> otherProg <span>=</span> receiveOnly<span>!</span>Tid<span>(</span><span>)</span><span>;</span><br />
<span>// ...</span><br />
<span>}</span></div></div>
<p>The parent thread then connects the two worker threads to each other,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> send<span>(</span>tid1<span>,</span> tid2<span>)</span><span>;</span><br />
send<span>(</span>tid2<span>,</span> tid1<span>)</span><span>;</span></div></div>
<p>And off they go, the two threads run through the opcodes in the problem statement, and eventually they deadlock, which I decided to handle with a timeout like so,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> <span>case</span> <span>"rcv"</span><span>:</span><br />
<span>if</span> <span>(</span><span>!</span>receiveTimeout<span>(</span><span>100</span>.<span>msecs</span><span>,</span> <span>(</span><span>long</span> val<span>)</span> <span>{</span>regs<span>[</span>reg<span>]</span> <span>=</span> val<span>;</span><span>}</span><span>)</span><span>)</span> <span>{</span><br />
<span>goto</span> done<span>;</span><br />
<span>}</span><br />
<span>// no timeout, handle next opcode</span><br />
<span>goto</span> <span>default</span><span>;</span></div></div>
<p>After the thread has timed out, it signals to the parent thread that it’s done,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> done<span>:</span><br />
send<span>(</span>ownerTid<span>,</span> thisTid<span>,</span> sent<span>)</span><span>;</span></div></div>
<p>The parent in turn receives two tuples with thread id and computed value from each thread, and based on that decides what to output, after figuring out which thread is which,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> <span>// Wait for both children to let us know they're done.</span><br />
<span>auto</span> done1 <span>=</span> receiveOnly<span>!</span><span>(</span>Tid<span>,</span> <span>long</span><span>)</span><span>;</span><br />
<span>auto</span> done2 <span>=</span> receiveOnly<span>!</span><span>(</span>Tid<span>,</span> <span>long</span><span>)</span><span>;</span><br />
<span>if</span> <span>(</span>done1<span>[</span><span>0</span><span>]</span> <span>==</span> tid2<span>)</span> <span>{</span><br />
writeln<span>(</span>done1<span>[</span><span>1</span><span>]</span><span>)</span><span>;</span><br />
<span>}</span><br />
<span>else</span> <span>{</span><br />
writeln<span>(</span>done2<span>[</span><span>1</span><span>]</span><span>)</span><span>;</span><br />
<span>}</span></div></div>
<p>And voilà, concurrency easy-peasy.</p>
<p><a name="day19"></a></p>
<h2>Day 19: string parsing with enums and final switches</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day19/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day19/app.d">my solution</a>)</p>
<p>The only new D technique here are final switches. A <code class="codecolorer d solarized-light"><span class="d"><span>final</span> <span>switch</span></span></code> is for <code class="codecolorer d solarized-light"><span class="d"><span>enum</span></span></code> types, to make the compiler enforce you writing a <code class="codecolorer d solarized-light"><span class="d"><span>case</span></span></code> to match all of the possible values. That’s what I did here, where I wanted to make sure I matched the up, down, left, and right directions:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> <span>final</span> <span>switch</span><span>(</span>dir<span>)</span><span>{</span><br />
<span>case</span> DIR.<span>d</span><span>:</span><br />
j<span>++;</span><br />
<span>break</span><span>;</span><br />
<span>case</span> DIR.<span>u</span><span>:</span><br />
j<span>--;</span><br />
<span>break</span><span>;</span><br />
<span>case</span> DIR.<span>l</span><span>:</span><br />
i<span>--;</span><br />
<span>break</span><span>;</span><br />
<span>case</span> DIR.<span>r</span><span>:</span><br />
i<span>++;</span><br />
<span>break</span><span>;</span><br />
<span>}</span></div></div>
<p>The rest of the problem is merely some string parsing.</p>
<p><a name="day20"></a></p>
<h2>Day 20: a physics problem with vector operations</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day20/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day20/app.d">my solution</a>)</p>
<p>I have not yet done serious numerical work with D, but I can see that it has all of the necessary ingredients for it. One of the most obvious amongst these is that it has <a href="https://dlang.org/spec/arrays.html#array-operations">built-in support for writing vector instructions</a>. Given <code class="codecolorer d solarized-light"><span class="d"><span>struct</span></span></code> to model a particle in motion,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>struct</span> particle <span>{</span><br />
<span>double</span><span>[</span><span>3</span><span>]</span> pos<span>;</span><br />
<span>double</span><span>[</span><span>3</span><span>]</span> vel<span>;</span><br />
<span>double</span><span>[</span><span>3</span><span>]</span> acc<span>;</span><br />
<span>}</span></div></div>
<p>the following function return another particle where all of the vectors have been divided by its norm (i.e. normalised to 1):</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>auto</span> unit<span>(</span>particle p<span>)</span> <span>{</span><br />
<span>auto</span><br />
pos <span>=</span> p.<span>pos</span><span>,</span><br />
vel <span>=</span> p.<span>vel</span><span>,</span><br />
acc <span>=</span> p.<span>acc</span><span>;</span><br />
pos<span>[</span><span>]</span> <span>/=</span> pos.<span>norm</span><span>;</span><br />
vel<span>[</span><span>]</span> <span>/=</span> vel.<span>norm</span><span>;</span><br />
acc<span>[</span><span>]</span> <span>/=</span> acc.<span>norm</span><span>;</span><br />
particle u <span>=</span> <span>{</span>pos<span>,</span> vel<span>,</span> acc<span>}</span><span>;</span><br />
<span>return</span> u<span>;</span><br />
<span>}</span></div></div>
<p>This <code class="codecolorer d solarized-light"><span class="d">vec<span>[</span><span>]</span> <span>/=</span> scalar</span></code> notation divides all of the vector by the given scalar. But that’s not all. You can also add or multiply vectors elementwise with similar syntax,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> <span>double</span><span>[</span><span>3</span><span>]</span> diff1 <span>=</span> p.<span>pos</span><span>,</span> diff2 <span>=</span> p.<span>vel</span><span>;</span><br />
diff1<span>[</span><span>]</span> <span>-=</span> p.<span>vel</span><span>[</span><span>]</span><span>;</span><br />
diff2<span>[</span><span>]</span> <span>-=</span> p.<span>acc</span><span>[</span><span>]</span><span>;</span></div></div>
<p>Here <code class="codecolorer d solarized-light"><span class="d">diff1</span></code> and <code class="codecolorer d solarized-light"><span class="d">diff2</span></code> give the vector difference between the position and velocity, and respectively, velocity in acceleration (I use the criterion of all of three of these being mostly collinear to determine if all particles have escaped the system and thus can no longer interact with any other particle).</p>
<p>This is mostly syntactic sugar, however. Although the D compiler can sometimes turn instructions like these into native vector instructions like <a href="https://en.wikipedia.org/wiki/Advanced_Vector_Extensions">AVX</a>, real vectorisation has to be done via <a href="https://dlang.org/spec/simd.html">some standard library support</a></p>
<p><a name="day21"></a></p>
<h2>Day 21: an indexable, hashable, comparable struct</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day21/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day21/app.d">my solution</a>)</p>
<p>I was happy to recognise, via some string mixins, that I could solve this problem by considering the <a href="https://en.wikipedia.org/wiki/Dihedral_group">dihedral group</a> of the square:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>immutable</span> dihedralFun <span>=</span><br />
<span>"function(ref const Pattern p) {<br />
auto n = p.dim;<br />
auto output = new int[][](n, n);<br />
foreach(i; 0..n) {<br />
foreach(j; 0..n) {<br />
output[i][j] = p.grid[%s][%s];<br />
}<br />
}<br />
return output;<br />
}"</span><span>;</span><br />
<br />
<span>immutable</span> dihedralFourGroup <span>=</span> <span>[</span><br />
<span>mixin</span><span>(</span>format<span>(</span>dihedralFun<span>,</span> <span>"i"</span><span>,</span> <span>"j"</span><span>)</span><span>)</span><span>,</span><br />
<span>mixin</span><span>(</span>format<span>(</span>dihedralFun<span>,</span> <span>"n-i-1"</span><span>,</span> <span>"j"</span><span>)</span><span>)</span><span>,</span><br />
<span>mixin</span><span>(</span>format<span>(</span>dihedralFun<span>,</span> <span>"i"</span><span>,</span> <span>"n-j-1"</span><span>)</span><span>)</span><span>,</span><br />
<span>mixin</span><span>(</span>format<span>(</span>dihedralFun<span>,</span> <span>"n-i-1"</span><span>,</span> <span>"n-j-1"</span><span>)</span><span>)</span><span>,</span><br />
<span>mixin</span><span>(</span>format<span>(</span>dihedralFun<span>,</span> <span>"j"</span><span>,</span> <span>"i"</span><span>)</span><span>)</span><span>,</span><br />
<span>mixin</span><span>(</span>format<span>(</span>dihedralFun<span>,</span> <span>"n-j-1"</span><span>,</span> <span>"i"</span><span>)</span><span>)</span><span>,</span><br />
<span>mixin</span><span>(</span>format<span>(</span>dihedralFun<span>,</span> <span>"j"</span><span>,</span> <span>"n-i-1"</span><span>)</span><span>)</span><span>,</span><br />
<span>mixin</span><span>(</span>format<span>(</span>dihedralFun<span>,</span> <span>"n-j-1"</span><span>,</span> <span>"n-i-1"</span><span>)</span><span>)</span><span>,</span><br />
<span>]</span><span>;</span></div></div>
<p>This isn’t a new technique, but I’m really happy how it turns out. Almost like lisp macros, but without devolving into the lawless chaos of Python or Javascript <code class="codecolorer python solarized-light"><span class="python"><span>eval</span></span></code> or C preprocessor macros. As an aside, the <code class="codecolorer d solarized-light"><span class="d">format</span></code> function accepts formatted strings with <a href="https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html">POSIX syntax for positional arguments</a>, but there isn’t anything built-in as nice as Perl string interpolation or Python format strings.</p>
<p>The real meat of this problem was to implement a grid structure that could be hashed, compared, and indexed. This is is all done with a number of utility functions. For indexing and slicing, the basic idea is that for a user-defined type <code class="codecolorer d solarized-light"><span class="d">foo</span></code></p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> foo<span>[</span>bar<span>..</span><span>baz</span><span>]</span></div></div>
<p>is sugar for</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"> foo.<span>opIndex</span><span>(</span>foo.<span>opSlice</span><span>(</span>bar<span>,</span> baz<span>)</span><span>)</span></div></div>
<p>so those are the two functions you need to implement for indexing and slicing. Similarly, for equality comparison and hashing, you implement <code class="codecolorer d solarized-light"><span class="d">opEquals</span></code> and <code class="codecolorer d solarized-light"><span class="d">toHash</span></code> respectively. I relied on the dihedral functions above for comparison for this problem.</p>
<p>After implementing these functions for a struct (recall: like a class, but with value semantics and no inheritance), the rest of the problem was string parsing and a bit of logic to implement the fractal-like growth rule.</p>
<p><a name="day22"></a></p>
<h2>Day 22: more enums, final switches, and complex numbers</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day22/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day22/app.d">my solution</a>)</p>
<p>Another rectangular grid problem, which I again decided to represent via complex numbers. The posssible infection states given in the problem I turned into an <code class="codecolorer d solarized-light"><span class="d"><span>enum</span></span></code> which I then checked with a <code class="codecolorer d solarized-light"><span class="d"><span>final</span> <span>switch</span></span></code> as before. The grid is then just an associative array from complex grid positions to infection states.</p>
<p>Nothing new here. By now these are all familiar tools and writing D code is becoming habitual for me.</p>
<p><a name="day23"></a></p>
<h2>Day 23: another opcode parsing problem</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day23/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day23/app.d">my solution</a>)</p>
<p>This problem wasn’t technically difficult from a D point of view. The usual switches and string parsing techniques of <a href="http://jordi.inversethought.com/feed/#day08">days 8</a> and <a href="http://jordi.inversethought.com/feed/#day18">18</a> work just as well. In fact, I started with the code of <a href="http://jordi.inversethought.com/feed/#day18">day 18</a> and modified it slightly to fit this problem.</p>
<p>The challenge was to statically analyse the opcode program to determine that it is implementing a very inefficient primality testing algorithm. I won’t go into an analysis of that program here because <a href="https://markheath.net/post/advent-of-code-2017-day-23">others have already done a remarkable job of explaining it</a>. Once this analysis was complete, the meat of the problem then becomes to write a faster primality testing algorithm, such as dumb (but not too dumb) trial division,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>auto</span> isComposite<span>(</span><span>long</span> p<span>)</span> <span>{</span><br />
<span>return</span> iota<span>(</span><span>2</span><span>,</span> sqrt<span>(</span><span>cast</span><span>(</span><span>double</span><span>)</span> p<span>)</span><span>)</span>.<span>filter</span><span>!</span><span>(</span>x <span>=></span> p <span>%</span> x <span>==</span> <span>0</span><span>)</span>.<span>any</span><span>;</span><br />
<span>}</span></div></div>
<p>and use this test at the appropriate location.</p>
<p><a name="day24"></a></p>
<h2>Day 24: a routine graph-search problem</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day24/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day24/app.d">my solution</a>)</p>
<p>This problem required some sort of graph structure, which I implemented as an associative array from node ids to all edges incident to that node. The problem then reduces to some sort of graph traversal (I did <a href="https://en.wikipedia.org/wiki/Depth-first_search">depth-first search</a>), keeping track of edge weights.</p>
<p>No new D techniques here either, just more practice with my growing bag of tricks.</p>
<p><a name="day25"></a></p>
<h2>Day 25: formatted reads to finish off Advent of D</h2>
<p>(<a href="http://inversethought.com/hg/aoc/file/tip/2017/day25/problem">problem statement</a> / <a href="http://inversethought.com/hg/aoc/file/tip/2017/day25/app.d">my solution</a>)</p>
<p>The final problem involved parsing a slightly more verbose <abbr title="Domain-specific languge">DSL</abbr>. For this, I decided to use formatted strings for reading, like so,</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>auto</span> branchFmt <span>=</span><br />
<span>" - Write the value %d.<br />
- Move one slot to the %s.<br />
- Continue with state %s.<br />
"</span><span>;</span><br />
<br />
<span>auto</span> parseBranch<span>(</span>File f<span>)</span> <span>{</span><br />
<span>int</span> writeval<span>;</span><br />
<span>string</span> movedir<span>;</span><br />
<span>char</span> newstate<span>;</span><br />
<br />
f.<span>readf</span><span>(</span>branchFmt<span>,</span> <span>&</span>writeval<span>,</span> <span>&</span>movedir<span>,</span> <span>&</span>newstate<span>)</span><span>;</span><br />
<span>return</span> Branch<span>(</span>writeval <span>?</span> <span>true</span> <span>:</span> <span>false</span><span>,</span> movedir <span>==</span> <span>"left"</span> <span>?</span> <span>-</span><span>1</span> <span>:</span> <span>1</span><span>,</span> newstate<span>)</span><span>;</span><br />
<span>}</span></div></div>
<p>This is admittedly a bit brittle. Even the type check between the formatted string and the expected types is done at runtime (but newer D versions have <a href="https://dlang.org/phobos/std_stdio.html#.readf">a compile-time version of readf</a> for type-checking the format string). An error here can cause exceptions at runtime.</p>
<p>Other than this, the only new technique here is that I actually wrote a loop to parse the program file:</p>
<div class="codecolorer-container d solarized-light"><div class="d codecolorer"><span>auto</span> parseInstructions<span>(</span>File f<span>)</span> <span>{</span><br />
Instruction<span>[</span><span>char</span><span>]</span> instructions<span>;</span><br />
<br />
<span>while</span><span>(</span><span>!</span>f.<span>eof</span><span>)</span> <span>{</span><br />
<span>char</span> state<span>;</span><br />
f.<span>readf</span><span>(</span><span>"In state %s:<span>\n</span>"</span><span>,</span> <span>&</span>state<span>)</span><span>;</span><br />
f.<span>readln</span><span>;</span> <span>// "If the current value is 0:"</span><br />
<span>auto</span> if0 <span>=</span> f.<span>parseBranch</span><span>;</span><br />
f.<span>readln</span><span>;</span> <span>// "If the current value is 1:"</span><br />
<span>auto</span> if1 <span>=</span> f.<span>parseBranch</span><span>;</span><br />
f.<span>readln</span><span>;</span> <span>// Blank line</span><br />
instructions<span>[</span>state<span>]</span> <span>=</span> Instruction<span>(</span>if0<span>,</span> if1<span>)</span><span>;</span><br />
<span>}</span><br />
<span>return</span> instructions<span>;</span><br />
<span>}</span></div></div>
<p>A small comfort here is that checking for eof in the loop condition actually works. This is always subtly wrong in C++ and I can never remember why.</p>
<p>What’s left of the problem is absolutely routine D by now: associative arrays, <abbr title="Uniform function-calling syntax">UFCS</abbr>, foreach loops, standard library utilities for summing and iterating and so forth. A few of my favourite things.</p>
<h1>Concluding remarks</h1>
<p>The best part is that my code was also <em>fast</em>! I was comparing my solutions above with someone else who was doing their Advent of Code in C. I could routinely match his execution speed on the problems where we bothered to compare, whenever we wrote similar algorithms. I’m eager to see what D can do when faced with some real number-crunching.</p>
<p>After all this, I have come to appreciate D more, as well as seeing some of its weak points. I think I have already raved enough about how much I like its functional style, its standard library, its type-checking, and its compile-time calculation. I also ran into a few bugs and deprecated features. I have also observed some language questionable design choices. Not once did I notice having a garbage collector. It was lots of fun.</p>
<p>Merry belated Christmas!</p>Jordi Gutiérrez Hermosohttp://jordi.inversethought.comSummary of work done during GSoCtag:blogger.com,1999:blog-3202743535685562583.post-17582287293702340702017-08-29T18:23:37+00:00<span><span>GSoC17 is at the end <span lang="en">and I want to thank </span></span><span><span lang="en"><span>my mentors and the Octave community </span> for giving me the opportunity to participate in this unique experience.</span></span></span><br /><br /><span><span>During this Google Summer of Code, my goal was to implement from scratch the Convolutional Neural Networks package for GNU Octave. It will be integrated with the already existing <i>nnet</i> package. </span></span><br /><span><span><br /></span></span><span><span> This was a very interesting project and a </span><span><span class="" id="result_box" lang="en" tabindex="-1"><span class="">stimulating experience for both the implemented code and the theoretical base behind the algorithms treated. A part has been implemented in Octave and an other part in Python using the Tensorflow API. </span></span></span></span><br /><span><span><br /></span></span><br /><h3><span><span><span>Code repository</span></span></span></h3><span><span>All the code implemented during these months can be found in </span><span>my public repository: </span></span><br /><br /><b><span><span> <a href="https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/all">https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/all</a> </span></span></b><br /><br /><span>(my username: <i>citti berto</i>, bookmark <i>enrico</i>)</span><br /><span><br /></span><span><span>Since I implemented a completely new part of the package, I pushed the entire project in three commits and I wait for the community approving for preparing a PR for the official package [1].</span></span><br /><span><br /></span><br /><h3><span><span><span>Summary</span></span></span></h3><span><b>The first commit</b> <b>(</b></span><span><b><span class="changeset-hash">ade115a, [2])</span></b> contains the layers. There is a class for each layer, with a corresponding function which calls the constructor. All the layers inherit from a Layer class which lets the user create a layers concatenation, that is the network architecture. Layers have several parameters, <span class="" id="result_box" lang="en" tabindex="-1">for which I have guaranteed the compatibility with Matlab [3].</span></span><br /><br /><span><br /></span><span><b>The second commit (</b></span><span><b><span class="changeset-hash">479ecc5 </span>[4]) </b>is about the Python part, including an init file checking the Tensorflow installation. I implemented a Python module, <i>TFintefrace</i>, which includes:</span><br /><span><br /></span><ul><li><span><i>layer.py:</i> an abstract class for layers inheritance</span></li><li><span><i>layers/layers.py:</i> the layer classes that are used to add the right layer to the TF graph</span></li><li><span><i>dataset.py:</i> a class for managing the datasets input</span></li><li><span><i>trainNetwork.py:</i> the core class, which initiates the graph and the session, performs the training and the predictions</span></li><li><span><i>deepdream.py:</i> a version of [5] for deepdream implementation (it has to be completed)</span></li></ul><br /><br /><span><b>The third commit (</b></span><span><b><span class="changeset-hash">e7201d8 [6])</span> </b>includes:</span><br /><ul><li><span><i>trainingOptions</i>: All the options for the training. Up to now, the only optimizer available is the stochastic gradient descent with momentum (sgdm) implemented in the class TrainingOptionsSGDM.</span></li><li><span><i>trainNetwork</i>: passing the data, the architecture and the options, this function performs the training and returns a SeriesNetwork object</span></li><li><span><i>SeriesNetwork</i>: class that contains the trained network, including the Tensorflow graph and session. This has three methods</span><ul><li><span><i><span><i>predict: </i></span></i><span>predicting </span><span>scores for regression problems</span><i><span><i></i></span></i></span></li><li><span><i>classify: </i>predicting labels for classification problems<i><br /></i></span></li><li><span><i>activations:</i></span> <span>getting the output of a specific layer of the architecture</span></li></ul><span><i> </i></span></li></ul><h3><span><span><span> </span></span></span></h3><h4><span><span><span>Goals not met</span></span></span></h4><span><span>I did not manage to implement some features because of the lack of time due to the bug fixing in the last period. </span><span class="short_text" id="result_box" lang="en" tabindex="-1">The problem was the </span><span class="short_text" id="result_box" lang="en" tabindex="-1"><span class="short_text" id="result_box" lang="en" tabindex="-1">conspicuous time</span> spent testing the algorithms (because of the different random generators between Matlab, Octave and Python/Tensorflow). I will work in the next weeks to implement the missing features and I plan to continue to contribute to maintaining this package to keep it up to date with both Tensorflow new versions and Matlab new feature. </span></span><br /><span><br /></span><br /><table> <tbody><tr> <th><span>Function</span></th> <th><span>Missing features</span></th> </tr><tr> <td><span><span><span><i>activations</i></span></span></span></td> <td><span><span><span><span><i>OutputAs</i> (for changing output format)</span></span></span></span></td> </tr><tr> <td><span><span><span><i>imageInputLayer</i></span></span></span></td> <td><span><span><span><span><i>DataAugmentation</i> and <i>Normalization</i></span></span></span></span></td> </tr><tr> <td><span><span><span><i>trainNetwork</i></span></span></span></td> <td><span><span>Accepted inputs: <i>imds</i> or <i>tbl</i></span></span></td> </tr><tr> <td><span><span><span><i>trainNetwork</i></span></span></span></td> <td><span><span><i>.mat Checkpoints</i></span></span></td> </tr><tr> <td><span><span><span><i>trainNetwork</i></span></span></span></td> <td><span><span><i>ExecutionEnvironment: 'multi-gpu' </i>and<i> 'parallel'</i></span></span></td> </tr><tr> <td><span><span><span><i>ClassificationOutputLayer </i></span></span></span></td> <td><span><span><i><span><span>classnames</span></span></i></span></span></td> </tr><tr> <td><span><span><span><i>TrainingOptions</i></span></span></span></td> <td><span><span><span><span><i>WorkerLoad</i> and <i>OutputFcn</i></span></span></span></span></td> </tr><tr> <td><span>DeepDreamImages</span></td> <td><span><span>Generalization to any network and AlexNet example</span></span></td> </tr></tbody></table><span><br /></span><h3><span><span><span> </span></span></span></h3><h3><span><span><span>Tutorial for testing the package</span></span></span></h3><ol><li><span><span>Install Python Tensorflow API (as explained in [4]) </span></span></li><li><span><span>Install Pytave (following these instructions [5])</span></span></li><li><span><span>Install nnet package (In Octave: install [6] and load [7])</span></span></li><li><span><span>Check the package with <i>make check PYTAVE="pytave/dir/"</i> </span></span></li><li><span><span>Open Octave, add the Pytave dir the the paths and run your first network:</span></span></li></ol><span><span><br />### TRAINING ###<br /># Load the training set<br />[XTrain,TTrain] = digitTrain4DArrayData();<br /> </span></span><br /><span><span><span># Define the layers<br />layers = [imageInputLayer([28 28 1]);<br /> convolution2dLayer(5,20);<br /> reluLayer();<br /> maxPooling2dLayer(2,'Stride',2);<br /> fullyConnectedLayer(10);<br /> softmaxLayer();<br /> classificationLayer()];<br /><br /># Define the training options<br />options = trainingOptions('sgdm', 'MaxEpochs', 15, 'InitialLearnRate', 0.04);<br /><br /># Train the network<br />net = trainNetwork(XTrain,TTrain,layers,options);<br /><br /><br />### TESTING ###<br /># Load the testing set<br />[XTest,TTest]= digitTest4DArrayData();<br /><br /># Predict the new labels<br />YTestPred = classify(net,XTest);</span></span></span><br /><br /><h4><span><span><span>Future improvements</span></span></span></h4><ul><li><span><span><span>Manage the session saving</span></span></span></li><li><span><span><span>Save the checkpoints as .mat files and not as TF checkpoints </span></span></span></li><li><span><span>Optimize array passage via Pytave </span></span></li><li><span><span>Categorical variables for classification problems </span></span></li></ul><br /><h4><span><span>Links</span></span></h4><span></span><br /><span>Repo link: <a href="https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/all">https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/all</a></span><br /><span><br /></span><span>[1] <a href="https://sourceforge.net/p/octave/nnet/ci/default/tree/">https://sourceforge.net/p/octave/nnet/ci/default/tree/</a></span><br /><span>[2] <a href="https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/ade115a0ce0c80eb2f617622d32bfe3b2a729b13">https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/ade115a0ce0c80eb2f617622d32bfe3b2a729b13</a></span><br /><span><span>[3] <a href="https://it.mathworks.com/help/nnet/classeslist.html?s_cid=doc_ftr">https://it.mathworks.com/help/nnet/classeslist.html?s_cid=doc_ftr</a></span> </span><br /><span>[4] <a href="https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/479ecc5c1b81dd44c626cc5276ebff5e9f509e84">https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/479ecc5c1b81dd44c626cc5276ebff5e9f509e84</a> </span><br /><span><span>[5] <a href="https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/tutorials/deepdream">https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/tutorials/deepdream</a></span> </span><br /><span>[6] <a href="https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/e7201d8081ca3c39f335067ca2a117e7971b5087">https://bitbucket.org/cittiberto/gsoc-octave-nnet/commits/e7201d8081ca3c39f335067ca2a117e7971b5087</a> </span><br /><span><span>[7] <a href="https://www.tensorflow.org/install/">https://www.tensorflow.org/install/</a></span></span><br /><span><span>[8] <a href="https://bitbucket.org/mtmiller/pytave">https://bitbucket.org/mtmiller/pytave</a></span></span><br /><span>[9] <a href="https://www.gnu.org/software/octave/doc/interpreter/Installing-and-Removing-Packages.html">https://www.gnu.org/software/octave/doc/interpreter/Installing-and-Removing-Packages.html</a></span><br /><span>[10] <a href="https://www.gnu.org/software/octave/doc/v4.0.1/Using-Packages.html">https://www.gnu.org/software/octave/doc/v4.0.1/Using-Packages.html</a></span>Enrico Bertinonoreply@blogger.comhttps://gsocnnet.blogspot.com/Final Reporttag:blogger.com,1999:blog-3508201418641099808.post-40861644101484431092017-08-28T15:50:59+00:00This is the final report on my work with the <a href="https://octave.sourceforge.io/interval/">interval package</a> during Google Summer of Code 2017. This whole blog have been dedicated to the project and by reading all posts you can follow my work from beginning to end.<br /><br />The work has been challenging and extremely fun! I have learned a lot about interval arithmetic, the <a href="https://www.gnu.org/software/octave/">Octave</a> and <a href="https://octave.sourceforge.io/">Octave-forge</a> project, and also how to contribute to open-source in general. I have found the whole Octave community to be very helpful and especially I want to thank my mentor, Oliver Heimlich, and co-mentor, Kai Torben Ohlhus, for helping me during the project.<br /><br />Here I will give a small introduction to Octave and the interval package for new readers and a summary of how the work has gone and how you can run the code I have actually contributed with.<br /><br /><h2>Octave and the Interval Package</h2><a href="https://www.gnu.org/software/octave/">Octave</a>, or GNU Octave, is a <a href="https://en.wikipedia.org/wiki/Free_software">free</a> program for scientific computing. It is very similar to <a href="https://en.wikipedia.org/wiki/MATLAB">Matlab</a> and its syntax is largely compatible with it. Octave comes with a large set of core functionality but can also be extended with packages from <a href="https://octave.sourceforge.io/">Octave forge</a>. These add new functionality, for example image processing, fuzzy logic or more statistic functions. One of those packages is the <a href="https://octave.sourceforge.io/interval/index.html">interval package</a> which allows you to compute with <a href="https://en.wikipedia.org/wiki/Interval_arithmetic">interval arithmetic</a> in Octave.<br /><br /><h2>Summary of the Work</h2>The goal with the project was to improve the Octave-forge interval package by implementing support for creating, and working with, N-dimensional arrays of intervals.<br /><br />The work has gone very well and we have just released version 3.0.0 of the interval package incorporating all the contributions I have made during the project.<br /><br />The package now has full support for working with N-dimensional arrays in the same way you do with ordinary floating point numbers in Octave. In addition I have also fixed some bugs not directly related to N-dimensional arrays, see for example bug <a href="https://savannah.gnu.org/bugs/?51783">#51783</a> and <a href="https://savannah.gnu.org/bugs/?51283">#51283</a>.<br /><br />During the project I have made a total of 108 commits. I have made changes to 332 of the packages 666 files. Some of these changes have only been changes in coding style or (mainly) automated adding of tests. Not counting these I have, manually, made changes to 110 files.<br /><br />If you want to take a look at all the commits I have contributed with the best way is to download the <a href="https://sourceforge.net/p/octave/interval/ci/default/tree/">repository</a> after which you can see all the commits from GSoC with<br /><span><br />hg log -u joeldahne@hotmail.com -d "2017-06-01 to 2017-08-29"<br /></span><br />Unfortunately I have not found a good way of isolating commits from a specific period and author on sourceforge where the package is hosted. Instead you can find a list of all commits at the end of this blog post.<br /><br />The <a href="https://octave.sourceforge.io/interval/NEWS.html">NEWS-file</a> from the release of version 3.0.0 is also a pretty good overview of what I have done. While not all of the changes are a result of GSoC quite a lot of them are.<br /><br /><h2>Running the Code</h2>As mentioned above we have just released version 3.0.0 of the interval package. With the new release it is very easy to test the newly added functionality. If you already have Octave installed the easiest way to install the package is with the command “pkg install -forge interval”. This will install the latest release of the package, at the time of writing this is 3.0.0 but that will of course change in the future. You can also download version 3.0.0 directly from <a href="https://octave.sourceforge.io/download.php?package=interval-3.0.0.tar.gz">Octave-forge</a>.<br /><br />If you want you can also download the source code from the official <a href="https://octave.sourceforge.io/pkg-repository/interval/">repository</a> and test it with "make run" or install it with "make install". To download the repository, update to version 3.0.0 an run Octave with the package on Linux use the following<br /><span><br /> hg clone http://hg.code.sf.net/p/octave/interval octave-interval<br /> cd octave-interval<br /> hg update release-3.0.0<br /> make run</span><br /><span><br /></span><br /><h2>A Package for Taylor Arithmetic</h2>The task took less time than planned so I had time to work upon a project depending on my previous work. I started to work on a project for Taylor arithmetic, you can read my <a href="https://gsocinterval.blogspot.se/2017/07/a-package-for-taylor-arithmetic.html">blog post</a> about it. I created a proof of concept implementation as part of my application for Google Summer of Code and I have now started to turn that into a real package. The repository can be found <a href="https://github.com/Urathai/octave-taylor-POC">here</a>.<br /><br />It is still far from complete but my goal is to eventually add it as a package at Octave-Forge. How that goes depends mainly on how much time I have to spend on it the following semesters.<br /><br />If you want to run the code as it is now you can pull the repository and then run it with "make run", this requires that Octave and version 3.0.0 (or higher) of the interval package is installed.<br /><br /><h2>List of Commits</h2>Here is a list of all 108 commits I have done to the interval package<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/68eb1b3281c9">https://sourceforge.net/p/octave/interval/ci/68eb1b3281c9</a><br />summary: Added Swedish translation for package metadata<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/52d6a2565ed2">https://sourceforge.net/p/octave/interval/ci/52d6a2565ed2</a><br />summary: @infsupdec/factorial.m: Fix decoration (bug #51783)<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/cf97d56a8e2a">https://sourceforge.net/p/octave/interval/ci/cf97d56a8e2a</a><br />summary: mpfr_function_d.cc: Cast int to octave_idx_type<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/5ed7880c917f">https://sourceforge.net/p/octave/interval/ci/5ed7880c917f</a><br />summary: maint: Fix input to source<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/637c532ea650">https://sourceforge.net/p/octave/interval/ci/637c532ea650</a><br />summary: @infsupdec/dot.m: Fix decoration on empty input<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/51425fd67692">https://sourceforge.net/p/octave/interval/ci/51425fd67692</a><br />summary: @infsup/postpad.m, @infsup/prepad.m, @infsupdec/postpad.m, @infsupdec/prepad.m: Corrected identification of dimension for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/b4e7f1546e36">https://sourceforge.net/p/octave/interval/ci/b4e7f1546e36</a><br />summary: mpfr_function_d.cc, mpfr_vector_dot_d.cc: Fixed bug when broadcasting with one size equal to zero<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/02db5199932c">https://sourceforge.net/p/octave/interval/ci/02db5199932c</a><br />summary: doc: NEWS.texinfo: Info about vectorization for nthroot and pownrev<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/197d033fc878">https://sourceforge.net/p/octave/interval/ci/197d033fc878</a><br />summary: @infsup/pownrev.m, @infsupdec/pownrev.m: Support for vectorization of p<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/7f8d1945264c">https://sourceforge.net/p/octave/interval/ci/7f8d1945264c</a><br />summary: @infsup/nthroot.m, @infsupdec/nthroot.m, mpfr_function_d.cc: Support for vectorization of n<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/e841c37383d6">https://sourceforge.net/p/octave/interval/ci/e841c37383d6</a><br />summary: doc: NEWS.texinfo: Summarized recent changes from GSoC<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/bc3e9523d42a">https://sourceforge.net/p/octave/interval/ci/bc3e9523d42a</a><br />summary: mpfr_vector_dot_d.cc: Fixed bug when broadcasting with one size equal to zero<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/0160ff2c2134">https://sourceforge.net/p/octave/interval/ci/0160ff2c2134</a><br />summary: doc: examples.texinfo: Updated example for the latest Symbolic package version<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/f37e1074c3ce">https://sourceforge.net/p/octave/interval/ci/f37e1074c3ce</a><br />summary: @infsup/*.m, @infsupdec/*.m: Added missing N-dimensional versions of tests<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/eb6b9c01bf6a">https://sourceforge.net/p/octave/interval/ci/eb6b9c01bf6a</a><br />summary: @infsup/*.m, @infsupdec/*.m: N-dimensional versions of all ternary tests<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/de71e0ad0a6e">https://sourceforge.net/p/octave/interval/ci/de71e0ad0a6e</a><br />summary: @infsup/*.m, @infsupdec/*.m: N-dimensional versions of all binary tests<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/9440d748b4aa">https://sourceforge.net/p/octave/interval/ci/9440d748b4aa</a><br />summary: @infsup/*.m, @infsupdec*.m: N-dimensional version of all unary tests<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/cb5b7b824400">https://sourceforge.net/p/octave/interval/ci/cb5b7b824400</a><br />summary: @infsup/powrev2.m: Fixed bug when called with vector arguments<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/a3e8fdb85b97">https://sourceforge.net/p/octave/interval/ci/a3e8fdb85b97</a><br />summary: @infsup/pownrev.m, @infsupdec/pownrev.m: Reworked vectorization test<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/aae143789b81">https://sourceforge.net/p/octave/interval/ci/aae143789b81</a><br />summary: @infsup/pown.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/f05814665570">https://sourceforge.net/p/octave/interval/ci/f05814665570</a><br />summary: @infsup/nthroot.n: Reworked vectorization test<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/c4c27574e331">https://sourceforge.net/p/octave/interval/ci/c4c27574e331</a><br />summary: @infsup/nthroot.m, @infsupdec/nthroot.m: Clarified that N must be scalar<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/3bfd4e7e6600">https://sourceforge.net/p/octave/interval/ci/3bfd4e7e6600</a><br />summary: @infup/pow.m, @infsupdec/pow.m: Fixed bug when called with vector arguments<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/e013c55a4e2a">https://sourceforge.net/p/octave/interval/ci/e013c55a4e2a</a><br />summary: @infsup/overlap.m, @infsupdec/overlap.m: Fixed formatting of vector test.<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/d700a1ad4855">https://sourceforge.net/p/octave/interval/ci/d700a1ad4855</a><br />summary: doc: Modified a test so that it now passes<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/2404686b07fb">https://sourceforge.net/p/octave/interval/ci/2404686b07fb</a><br />summary: doc: Fixed formatting of example<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/c078807c6b32">https://sourceforge.net/p/octave/interval/ci/c078807c6b32</a><br />summary: doc: SKIP an example that always fail in the doc-test<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/598dea2b8eb8">https://sourceforge.net/p/octave/interval/ci/598dea2b8eb8</a><br />summary: doc: Fixed missed ending of example in Getting Started<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/66ca24edfba4">https://sourceforge.net/p/octave/interval/ci/66ca24edfba4</a><br />summary: Updated coding style for all infsupdec-class functions<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/4c629b9000fc">https://sourceforge.net/p/octave/interval/ci/4c629b9000fc</a><br />summary: Updated coding style for all infsup-class functions<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/3898a7ad5d93">https://sourceforge.net/p/octave/interval/ci/3898a7ad5d93</a><br />summary: Updated coding style for all non-class functions<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/f911db83df14">https://sourceforge.net/p/octave/interval/ci/f911db83df14</a><br />summary: @infsupdec/dot.m: Fixed wrong size of decoration when called with two empty matrices<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/8e6a9e37ee40">https://sourceforge.net/p/octave/interval/ci/8e6a9e37ee40</a><br />summary: Small updates to documentation and comments for a lot of function to account for the support of N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/a2ef249d54ae">https://sourceforge.net/p/octave/interval/ci/a2ef249d54ae</a><br />summary: doc: A small update to Examples, the interval Newton method can only find zeros inside the initial interval<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/76431745772f">https://sourceforge.net/p/octave/interval/ci/76431745772f</a><br />summary: doc: Updates to Getting Started, mainly how to create N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/9821eadca12b">https://sourceforge.net/p/octave/interval/ci/9821eadca12b</a><br />summary: doc: Small updates to Preface regarding N-dimensional arrays and fixed one link<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/0f1aadf5f13a">https://sourceforge.net/p/octave/interval/ci/0f1aadf5f13a</a><br />summary: ctc_intersect.m, ctc_union.m: Fixed bugs when used for vectorization and when called with 0 or 1 output arguments<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/0e01dc19dc75">https://sourceforge.net/p/octave/interval/ci/0e01dc19dc75</a><br />summary: @infsup/sumsq.m: Updated to use the new functionality of dot.m<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/2fba2056ed31">https://sourceforge.net/p/octave/interval/ci/2fba2056ed31</a><br />summary: @infsup/dot.m, @infsupdec/dot.m, mpfr_vector_dot_d.cc: Added support for N-dimensional vectors. Moved all vectorization to the oct-file. Small changes to functionality to mimic how the sum function works.<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/05fc90112ea9">https://sourceforge.net/p/octave/interval/ci/05fc90112ea9</a><br />summary: ctc_intersect.m, ctc_union.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/2a4d1e9fa43e">https://sourceforge.net/p/octave/interval/ci/2a4d1e9fa43e</a><br />summary: @infsup/fsolve.m: Added support for N-dimensional arrays. Fixed problem with the function in the example. Improved performance when creating the cell used in vectorization.<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/7a96c346225a">https://sourceforge.net/p/octave/interval/ci/7a96c346225a</a><br />summary: @infsup/disp.m: Fixed wrong enumeration of submatrices<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/933117890e45">https://sourceforge.net/p/octave/interval/ci/933117890e45</a><br />summary: Fixed typo in NEWS.texinfo<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/67734688adb1">https://sourceforge.net/p/octave/interval/ci/67734688adb1</a><br />summary: @infsup/diag.m: Added description of the previous bug fix in the NEWS file<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/07ebc81867cd">https://sourceforge.net/p/octave/interval/ci/07ebc81867cd</a><br />summary: @infsup/diag.m: Fixed error when called with more than 1 argument<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/554c34fb3246">https://sourceforge.net/p/octave/interval/ci/554c34fb3246</a><br />summary: @infsup/meshgrid.m, @infsupdec/meshgrid.m: Removed these functions, now falls back on standard implementation, also updated index<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/4bad2e7451f5">https://sourceforge.net/p/octave/interval/ci/4bad2e7451f5</a><br />summary: @infsup/plot.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/5e0100cdc25f">https://sourceforge.net/p/octave/interval/ci/5e0100cdc25f</a><br />summary: @infsup/plot3.m: Small change to allow for N-dimensional arrays as input<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/695a223ccbb7">https://sourceforge.net/p/octave/interval/ci/695a223ccbb7</a><br />summary: @infsupdec/prod.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/55f570c13f01">https://sourceforge.net/p/octave/interval/ci/55f570c13f01</a><br />summary: @infsup/prod.m: Added support for N-dimensional arrays. Removed short circuit in simple cases.<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/445d7e5150aa">https://sourceforge.net/p/octave/interval/ci/445d7e5150aa</a><br />summary: @infsup/sum.m, @infsupdec/sum.m, mpfr_vector_sum_d.cc: Added support for N-dimensional vectors. Moved all vectorization to the oct-file. Small changes to functionality to mimic Octaves standard sum function.<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/f27ad212735e">https://sourceforge.net/p/octave/interval/ci/f27ad212735e</a><br />summary: @infsup/fminsearch.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/19724b3f581e">https://sourceforge.net/p/octave/interval/ci/19724b3f581e</a><br />summary: mpfr_function_d.cc: Finalized support for N-dimensional arrays with binary functions and added support for it with ternary functions.<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/023e2788e445">https://sourceforge.net/p/octave/interval/ci/023e2788e445</a><br />summary: midrad.m: Added tests for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/617484113019">https://sourceforge.net/p/octave/interval/ci/617484113019</a><br />summary: @infsupdec/infsupdec.m: Added full support for creating N-dimensional arrays and added tests<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/f1c28a3d48b7">https://sourceforge.net/p/octave/interval/ci/f1c28a3d48b7</a><br />summary: @infsup/subset.m, @infsupdec/subset.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/8e9990e3ed13">https://sourceforge.net/p/octave/interval/ci/8e9990e3ed13</a><br />summary: @infsup/strictsubset.m, @infsupdec/strictsubset.m: Fixed coding style and updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/5ca9b26b580d">https://sourceforge.net/p/octave/interval/ci/5ca9b26b580d</a><br />summary: @infsup/strictprecedes.m, @infsupdec/strictprecedes.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/1c76721003f1">https://sourceforge.net/p/octave/interval/ci/1c76721003f1</a><br />summary: @infsup/sdist.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/e044dea7c820">https://sourceforge.net/p/octave/interval/ci/e044dea7c820</a><br />summary: @infsup/precedes.m, @infsupdec/precedes.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/d48ca9206299">https://sourceforge.net/p/octave/interval/ci/d48ca9206299</a><br />summary: @infsup/overlap.m, @infsupdec/overlap.m: Fixed coding style and updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/1ad6b47f9335">https://sourceforge.net/p/octave/interval/ci/1ad6b47f9335</a><br />summary: @infsup/issingleton.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/11dccbcfd97e">https://sourceforge.net/p/octave/interval/ci/11dccbcfd97e</a><br />summary: @infsup/ismember.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/ade5da12cf88">https://sourceforge.net/p/octave/interval/ci/ade5da12cf88</a><br />summary: @infsup/isentire.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/9fc874b71533">https://sourceforge.net/p/octave/interval/ci/9fc874b71533</a><br />summary: @infsup/isempty.m, @infsupdec/isempty.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/0c5c4eaf263b">https://sourceforge.net/p/octave/interval/ci/0c5c4eaf263b</a><br />summary: @infsup/iscommoninterval.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/c980da83b634">https://sourceforge.net/p/octave/interval/ci/c980da83b634</a><br />summary: @infsup/interior.m, @infsupdec/interior.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/f67d78651aee">https://sourceforge.net/p/octave/interval/ci/f67d78651aee</a><br />summary: @infsup/idist.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/70a389bd59f5">https://sourceforge.net/p/octave/interval/ci/70a389bd59f5</a><br />summary: @infsup/hdist.m: Fixed coding style and updated documentation.<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/e34401d2a6d6">https://sourceforge.net/p/octave/interval/ci/e34401d2a6d6</a><br />summary: @infsup/sin.m, @infsupdec/sin.m: Added workaround for bug #51283<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/fea4c6516101">https://sourceforge.net/p/octave/interval/ci/fea4c6516101</a><br />summary: @infsup/gt.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/ce973432d240">https://sourceforge.net/p/octave/interval/ci/ce973432d240</a><br />summary: @infsup/ge.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/a435986d4b0c">https://sourceforge.net/p/octave/interval/ci/a435986d4b0c</a><br />summary: @infsup/lt.m, @infsupdec/lt.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/23fa89e3c461">https://sourceforge.net/p/octave/interval/ci/23fa89e3c461</a><br />summary: @infsup/le.m, @infsupdec/le.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/730397b9e339">https://sourceforge.net/p/octave/interval/ci/730397b9e339</a><br />summary: @infsup/disjoint.m, @infsupdec/disjoint.m: Updated documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/682ad849fc98">https://sourceforge.net/p/octave/interval/ci/682ad849fc98</a><br />summary: mpfr_function_d.cc: Added support for N-dimensional arrays for unary functions. Also temporary support for binary functions.<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/9661e0256c51">https://sourceforge.net/p/octave/interval/ci/9661e0256c51</a><br />summary: crlibm_function.cc: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/0ec3d29c0779">https://sourceforge.net/p/octave/interval/ci/0ec3d29c0779</a><br />summary: @infsup/infsup.m: Fixed documentation and added missing line continuation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/ebb00e763a46">https://sourceforge.net/p/octave/interval/ci/ebb00e763a46</a><br />summary: @infsup/disp.m: Fixed documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/1ab2749da374">https://sourceforge.net/p/octave/interval/ci/1ab2749da374</a><br />summary: @infsup/size.m: Fixed documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/507ca8478b72">https://sourceforge.net/p/octave/interval/ci/507ca8478b72</a><br />summary: @infsup/size.m: Fixes to the documentation<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/667da39afece">https://sourceforge.net/p/octave/interval/ci/667da39afece</a><br />summary: nai.m: Small fix to one of the tests<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/3eb13f91065a">https://sourceforge.net/p/octave/interval/ci/3eb13f91065a</a><br />summary: hull.m: Fixes according to Olivers review<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/20d784a6605d">https://sourceforge.net/p/octave/interval/ci/20d784a6605d</a><br />summary: @infsup/display.m: Vectorized loop<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/fab7aa26410f">https://sourceforge.net/p/octave/interval/ci/fab7aa26410f</a><br />summary: @infsup/disp.m: Fixes according to Olivers review, mainly details in the output<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/4959566545db">https://sourceforge.net/p/octave/interval/ci/4959566545db</a><br />summary: @infsup/infsup.m: Updated documentation and added test for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/b25fbf0ad324">https://sourceforge.net/p/octave/interval/ci/b25fbf0ad324</a><br />summary: @infsup/infsup.m: Fixed coding style<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/486a73046d5e">https://sourceforge.net/p/octave/interval/ci/486a73046d5e</a><br />summary: @infsup/disp.m: Updated documentation and added more tests for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/b6a0435da31f">https://sourceforge.net/p/octave/interval/ci/b6a0435da31f</a><br />summary: exacttointerval.m: Uppdated documentation and added tests for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/bdad0e6da132">https://sourceforge.net/p/octave/interval/ci/bdad0e6da132</a><br />summary: @infsup/intervaltotext.m, @infsupdec/intervaltotext.m: Updated documentation and added tests for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/55a3e708aef4">https://sourceforge.net/p/octave/interval/ci/55a3e708aef4</a><br />summary: @infsup/intervaltotext.m: Fixed coding style<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/536b0c5023ee">https://sourceforge.net/p/octave/interval/ci/536b0c5023ee</a><br />summary: @infsup/subsref.m, @infsupdec/subsref.m: Added tests for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/c9654a4dcd8d">https://sourceforge.net/p/octave/interval/ci/c9654a4dcd8d</a><br />summary: @infsup/size.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/636709d06194">https://sourceforge.net/p/octave/interval/ci/636709d06194</a><br />summary: @infsup/end.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/e6451e037120">https://sourceforge.net/p/octave/interval/ci/e6451e037120</a><br />summary: nai.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/837cccf1d627">https://sourceforge.net/p/octave/interval/ci/837cccf1d627</a><br />summary: @infsup/resize.m, @infsupdec/resize.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/11cb9006b9ea">https://sourceforge.net/p/octave/interval/ci/11cb9006b9ea</a><br />summary: @infsup/reshape.m, @infsupdec/reshape.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/c276af6c42ae">https://sourceforge.net/p/octave/interval/ci/c276af6c42ae</a><br />summary: @infsup/prepad.m, @infsupdec/prepad.m: Added small parts to the documentation and tests for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/c92c829dc946">https://sourceforge.net/p/octave/interval/ci/c92c829dc946</a><br />summary: @infsup/postpad.m, @infsupdec/postpad.m: Added small parts to the documentation and tests for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/0f8f6864123e">https://sourceforge.net/p/octave/interval/ci/0f8f6864123e</a><br />summary: @infsup/meshgrid.m, @infsupdec/meshgrid.m: Added support for outputting 3-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/b7faafef6030">https://sourceforge.net/p/octave/interval/ci/b7faafef6030</a><br />summary: @infsup/cat.m, @infsupdec/cat.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/d416a17a6d3d">https://sourceforge.net/p/octave/interval/ci/d416a17a6d3d</a><br />summary: hull.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/031831f6bdfd">https://sourceforge.net/p/octave/interval/ci/031831f6bdfd</a><br />summary: empty.m, entire.m: Added support for N-dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/2816b68b83c4">https://sourceforge.net/p/octave/interval/ci/2816b68b83c4</a><br />summary: @infsup/display.m: Added support for displaying high dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/79c8dfa8ac54">https://sourceforge.net/p/octave/interval/ci/79c8dfa8ac54</a><br />summary: @infsup/disp.m: Added support for displaying high dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/cc87924e52ac">https://sourceforge.net/p/octave/interval/ci/cc87924e52ac</a><br />summary: @infsup/disp.m: Fixed coding style<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/29a6b4ecda2a">https://sourceforge.net/p/octave/interval/ci/29a6b4ecda2a</a><br />summary: @infsupdec/infsupdec.m: Temporary fix for creating high dimensional arrays<br /><br /><a href="https://sourceforge.net/p/octave/interval/ci/039abcf7623d">https://sourceforge.net/p/octave/interval/ci/039abcf7623d</a><br />summary: @infsupdec/infsupdec.m: Fixed coding styleJoel Dahnenoreply@blogger.comhttps://gsocinterval.blogspot.com/Final Resumetag:blogger.com,1999:blog-8509760576772091576.post-35480845913895779712017-08-28T04:46:00+00:00SummaryDuring the GSoC I worked on different special functions that needed to be improved or implemented from scratch. Discussing with my mentors and the community, we decided that my work should be pushed on a copy of the scource code of Octave on <a href="https://bitbucket.org/M_Ginesi/octave">my repository</a> [1] and then I should have work with different bookmarks for each function I had to work on. When different functions happened to be related (e.g. gammainc and gammaincinv), I worked on these on the same bookmark. I present now a summary and the bookmarks related to the functions.<br /><br /> <h2>Incomplete gamma function</h2> <b>bookmark</b>: gammainc <br /><b>first commit</b>: d1e03faf080b<br /><b>last commit</b>: 107dc1d24c1b <br /><b>added files</b>: /libinterp/corefcn/__gammainc_lentz__.cc, /scripts/specfun/gammainc.m, /scripts/specfun/gammaincinv.m<br /> <b>removed files</b>:/libinterp/corefcn/gammainc.cc, /liboctave/external/slatec-fn/dgami.f, /liboctave/external/slatec-fn/dgamit.f, /liboctave/external/slatec-fn/gami.f, /liboctave/external/slatec-fn/gamit.f, /liboctave/external/slatec-fn/xdgami.f, /liboctave/external/slatec-fn/xdgamit.f, /liboctave/external/slatec-fn/xgmainc.f, /liboctave/external/slatec-fn/xsgmainc.f<br /> <b>modified files</b>: NEWS, /doc/interpreter/arith.txi, /libinterp/corefcn/module.mk, /liboctave/external/slatec-fn/module.mk, /liboctave/numeric/lo-specfun.cc, /scripts/specfun/module.mk<br /> <h3>Summary of the work</h3> On this bookmark I worked on the incomplete gamma function and its inverse.<br />The incomplete gamma function gammainc had both missing features (it were missed the "scaled" options) and some problem of inaccurate result type (see <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=47800">bug # 47800</a>). Part of the work was already been done by Marco and Nir, I had to finish it. We decided to implement it as a single .m file (<tt>gammainc.m</tt>) which call (for some inputs) a subfunction written in C++ (<tt>__gammainc_lentz__.cc</tt>).<br />The inverse of the incomplete gamma function was missing in Octave (see <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=48036">bug # 48036</a>). I implemented it as a single .m file (<tt>gammaincinv.m</tt>) which uses a Newton method. <h2>Bessel functions</h2><b>bookmark</b>: bessel <br /><b>first commit</b>: aef0656026cc <br /><b>last commit</b>: e9468092daf9 <br /> <b>modified files</b>: /liboctave/external/amos/README, /liboctave/external/amos/cbesh.f, /liboctave/external/amos/cbesi.f, /liboctave/external/amos/cbesj.f, /liboctave/external/amos/cbesk.f, /liboctave/external/amos/zbesh.f, /liboctave/external/amos/zbesi.f, /liboctave/external/amos/zbesj.f, /liboctave/external/amos/zbesk.f, /liboctave/numeric/lo-specfun.cc, /scripts/specfun/bessel.m<br /> <h3>Summary of the work</h3> On this bookmark I worked on Bessel functions. <br />There was a bug reporting NaN as output when the argument $x$ was too large in magnitude (see <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=48316">bug # 48316</a>). The problem was given by Amos library, which refuses to compute the output in such cases. I started "unlocking" this library, in such a way to compute the output even when the argument was over the limit setted by the library. Then I compared the results with other libraries (e.g. <a href="http://www.netlib.org/cephes/">Cephes</a> [2], <a href="https://www.gnu.org/software/gsl/">Gnu Scientific library</a> [3] and <a href="http://en.cppreference.com/w/cpp/numeric/special_math">C++ special function library</a> [4]) and some implementations I made. In the end, I discovered that the "unlocked" Amos were the best one to use, so we decided to maintain them (in the "unlocked" form), modifying the error variable to explain the loss of accuracy. <h2>Incomplete beta function</h2> <b>bookmark</b>: betainc <br /><b>first commit</b>: 712a069d2860<br /><b>last commit</b>: e0c0dd40f096 <br /> <b>added files</b>: /libinterp/corefcn/__betainc_lentz__.cc, /scripts/specfun/betainc.m, /scripts/specfun/betaincinv.m<br /> <b>removed files</b>: /libinterp/corefcn/betainc.cc, /liboctave/external/slatec-fn/betai.f, /liboctave/external/slatec-fn/dbetai.f, /liboctave/external/slatec-fn/xbetai.f, /liboctave/external/slatec-fn/xdbetai.f<br /> <b>modified files</b>: /libinterp/corefcn/module.mk, /liboctave/external/slatec-fn/module.mk, /liboctave/numeric/lo-specfun.cc, /liboctave/numeric/lo-specfun.h, /scripts/specfun/module.mk, /scripts/statistics/distributions/betainv.m, /scripts/statistics/distributions/binocdf.m<br /> <h3>Summary of the work</h3> On this bookmark I worked on the incomplete beta function and its inverse.<br />The incomplete beta function missed the "upper" version and had reported bugs on input validation (see <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=34405">bug # 34405</a>) and inaccurate result (see <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=51157">bug # 51157</a>). We decided to rewrite it from scratch. It is now implemented ad a single .m file (<tt>betainc.m</tt>) which make the input validation part, then the output is computed using a continued fraction evaluation, done by a C++ function (<tt>__betainc_lentz__.cc</tt>).<br />The inverse was present in Octave but missed the "upper" version (since it was missing also in betainc itself). The function is now written as a single .m file (<tt>betaincinv.m</tt>) which implement a Newton method where the initial guess is computed by few steps of bisection method. <h2>Integral functions</h2><b>bookmark</b>: expint<br /><b>first commit</b>: 61d533c7d2d8<br /><b>last commit</b>: d5222cffb1a5<br /> <b>added files</b>:/libinterp/corefcn/__expint_lentz__.cc, /scripts/specfun/cosint.m, /scripts/specfun/sinint.m<br /> <b>modified files</b>: /doc/interpreter/arith.txi, /libinterp/corefcn/module.mk, /scripts/specfun/expint.m, /scripts/specfun/module.mk<br /> <h3>Summary of the work</h3> On this bookmark I worked on exponential integral, sine integral and cosine integral. I already rewrote the exponential integral before the GSoC. Here I just moved the Lentz algorithm to an external C++ function (<tt>__expint_lentz__.cc</tt>), accordingly to gammainc and betainc. I've also modified the exit criterion for the asymptotic expansion using [5] (pages 1 -- 4) as reference.<br />The functions sinint and cosint were present only in the symbolic package of Octave but was missing a numerical implementation in the core. I wrote them as .m files (<tt>sinint.m</tt> and <tt>cosint.m</tt>). Both codes use the series expansion near the origin and relations with expint for the other values.<br /><br /> <h2>To do</h2>There is still room for improvement for some of the functions I wrote. In particular, gammainc can be improved in accuracy for certain couple of values, and I would like to make a template version for the various Lentz algorithms in C++ so to avoid code duplication in the functions.<br />In October I will start a PhD in Computer Science, still here in Verona. This will permit me to remain in contact with my mentor Marco Caliari, so that we will work on these aspects. <br /><br />[1] <a href="https://bitbucket.org/M_Ginesi/octave">https://bitbucket.org/M_Ginesi/octave</a> <br />[2] <a href="http://www.netlib.org/cephes/">http://www.netlib.org/cephes/</a> <br />[3] <a href="https://www.gnu.org/software/gsl/">https://www.gnu.org/software/gsl/</a> <br />[4] <a href="http://en.cppreference.com/w/cpp/numeric/special_math">http://en.cppreference.com/w/cpp/numeric/special_math</a> <br />[5] N. Bleistein and R.A. Handelsman, "Asymptotic Expansions of Integrals", Dover Publications, 1986.Michele Ginesinoreply@blogger.comhttp://gsocspecfun.blogspot.com/Geometry Package (Octave)https://piyush-jain1.github.io//GeometryPackage2017-08-28T00:00:00+00:00<h1 id="geometry-package-implement-boolean-operations-on-polygons">Geometry package: Implement boolean operations on polygons</h1>
<p>As part of GSoC 2017 , this project is intended to implement a set of boolean operations and supporting function for acting on polygons. These include the standard set of potential operations such as union/OR, intersection/AND, difference/subtraction, and exclusiveor/XOR. Other things to be implemented are the following functions: polybool, ispolycw, poly2ccw, poly2cw, poly2fv, polyjoin, and polysplit.<br /></p>
<p>This <a href="https://github.com/piyush-jain1/GSoC17OctaveGeometry">Repository</a> is a clone(fork) of the Geometry Package which is a part of the <a href="http://octave.sourceforge.net/">Octave Forge Project</a>.<br /></p>
<p>This fork adds new functions to the official Geometry Package as part of GSoC (Google Summer of Code) 2016.</p>
<p>The official Geometry Package can be found <a href="https://sourceforge.net/p/octave/geometry/ci/default/tree/">here</a></p>
<p>Link to commits on official repo :</p>
<ul>
<li><a href="https://sourceforge.net/p/octave/geometry/ci/19a35efc16dbe645e0bbfbffe9cfaa14e5ec9c96/">19a35e</a></li>
<li><a href="https://sourceforge.net/p/octave/geometry/ci/fc3710b6cce55502e6eff4dc4251d507bc5b4ff1/">fc3710</a></li>
</ul>
<h2 id="added-files-and-functions">Added files and functions</h2>
<ol>
<li>/inst/polygons2d/clipPolygon_mrf.m</li>
<li>/inst/polygons2d/private/_<em>poly2struct_</em>.m</li>
<li>/src/martinez.cpp</li>
<li>/src/polygon.cpp</li>
<li>/src/utilities.cpp</li>
<li>/src/polybool_mrf.cc</li>
<li>/inst/polygons2d/funcAliases</li>
</ol>
<h2 id="bonding-period">Bonding Period</h2>
<p>After discussion with my mentor and keeping my proposal in mind, I tried to understand and enlist the tasks more specifically and in detail. I first tried to understand the conventions and other things about the organisation. I tried to understand the first basic thing which I will need throughout this project, i.e. how we create an oct-interface for the C++ codes to be executable in Octave.
My first goal was to explore the possibility if the already implemented mex-interface geometry package can be improved in performance by replacing it with oct-interface. So, for understanding how these oct-files work and other things , I started to implement something in oct-files and getting familiar with it.</p>
<h2 id="first-coding-phase">First Coding Phase</h2>
<p>As stated, there is an already implemented <a href="https://github.com/piyush-jain1/GSoC17OctaveGeometry">Geometry3.0 package</a>. This has mex interface for its functions. I tried to compare its performance with the oct interface version. For benchmarking, I first implemented my own function for polyUnion (using clipper library) with oct-interface <a href="https://github.com/piyush-jain1/GSoC17OctaveGeometry/tree/master/devel/MyPolyUnion">(Find it here)</a>. Then, I compared its performance over a number of different sets of polgons (parametrized over number of vertices) and recorded the elapsed times with both the interfaces. On plotting a graph of Number of vertices V/s Elapsed time (for oct and mex), following obseravtions were made : </br></p>
<ul>
<li>The oct interface had a better performance over mex.</li>
<li>For 10000 vertices, the oct interface took about 0.008 seconds while the mex interface took about 0.014 seconds. This implies oct interface took 8X10e-3 seconds / 10e4 vertices i.e. 8X10e-7 seconds per vertex. For mex, it was 14X10e-7 seconds per vertex.</li>
<li>As it can be seen from the above data, the oct interface was not more than twice as good as mex interface.</br>
From these observations, it was concluded that it is not worth to change the interface from mex to oct since there was not much improvement in performance. Thus, our next goal is now to incorporate new algorithms.</li>
</ul>
<p>After spending decent time over checking out the new algorithm and understanding its implementation, I have now started to implement the polybool function. I also tried to compare its performance with the already implemented clipPolygon in the current geometry package. The new algorithm has a better performance than the old one.</p>
<p>The implementation of boolean operations on polygons, like <strong>DIFFERENCE</strong> , <strong>INTERSECTION</strong> , <strong>XOR</strong> and <strong>UNION</strong> with the new algorithm is almost done. A little work on tests, demos and documentation is still needed and I am working on that.</p>
<h4 id="more-about-the-algorithm-by-f-martínez-aj-rueda-fr-feito">More about the algorithm by F. Martínez, A.J. Rueda, F.R. Feito</h4>
<p>The algorithm is very easy to understand, among other things because it can be seen as an extension of the classical algorithm, based on the plane sweep, for computing the intersection points between a set of segments.When a new intersection between the edges of polygons is found, the algorithm subdivides the edges at the intersection point. This produces a plane sweep algorithm with only two kind of events: left and right endpoints, making the algorithm quite simple. Furthermore, the subdivision of edges provides a simple way of processing degeneracies. </br>
Overall sketch of the approach for computing Boolean operations on polygons:</p>
<ul>
<li>Subdivide the edges of the polygons at their intersection points.</li>
<li>Select those subdivided edges that lie inside the other polygon—or that do not lie depending on the operation.</li>
<li>Join the edges selected in step 2 to form the result polygon.</br>
<h4 id="complexity">Complexity</h4>
<p>Let n be the total number of edges of all the polygons involved in the Boolean operation and k be the number of intersections of all the polygon edges. The whole algorithm runs in time <strong>O(n+k)log(n)</strong>.</br></p>
</li>
</ul>
<p>After raw testing this new algorithm on several cases, I am now adding few tests in the m-script. Other than that, a demo has also been added in the m-script. The demo can be seen by the command <code class="highlighter-rouge">demo clipPolygon_mrf</code>. The tests have also been added. The test can be seen by <code class="highlighter-rouge">test clipPolygon_mrf</code>.</p>
<h2 id="second-coding-phase">Second Coding Phase</h2>
<p>After implementing the polybool function and checking it, we are planning to include it in the next release of geometry package.
Now , to move forward, I am first importing some functions from last year GSoC’s repo and ensuring their MATLAB compatibility.
Functions like poly2ccw, poly2cw, joinpolygons, splitPolygons have been created as aliases while ensuring their compatibility with their mathworks counterparts.
Then after, there was some time invested on understanding the CGAL library and its implementation.</p>
<p>The further plan is to sync the matgeom package with the geometry package.</p>
<h2 id="third-coding-phase">Third Coding Phase</h2>
<p>Proceeding towards the next goal, the idea is to devise some way to automate the process somewhat, of syncing the matgeom and geometry package. The issue is that when a new release of geometry package is planned, there are some things which ahve been updated in matgeom but not in their geometry counterparts (if it exists). So, every time before releasing, so much time has to be invested in manually checking each edit and syncing it into the geometry.</p>
<p>To achieve this, first a workaround is implemented on a dummy repository - <a href="https://github.com/piyush-jain1/dummyMatGeom/">dummyMatGeom</a>. Its master branch is matGeom (dummy) and there is another branch (named geometry) is created which contains geometry package (dummy). To test the entire procedure, go to the dummy repository dummyMatGeom , pull both branches in different folders, say “dummyMatGeom” for master branch and “dummyGeom” for geometry branch. Then follow the given steps as explained on the <a href="http://wiki.octave.org/Geometry_package:GSoC17">wiki page</a>.</p>
<h4 id="challenges">Challenges</h4>
<ul>
<li>
<p>Clearly, the above procedure will only sync the script of the function, not it’s tests and demo, which are in separate folders in a Matlab package structure. Even if we try to concatenate their corresponding test/demo scripts with the function scripts (as it is in an octave package structure), there will be discrepancies because the notion or writing tests for octave and matlab packages are quite different. The way octave allows tests to work is unique to octave as explained here. SO, we can’t simply concatenate the Matlab test scripts with the functions.</p>
</li>
<li>
<p>Git doesn’t preserves the original version of geometry scripts and overwrites the whole file completely.
For example :</p>
</li>
</ul>
<ol>
<li>Original file at matGeom (upstream)</li>
</ol>
<pre><code class="language-octave">
% Bla bla
% bla bla bla
function z = blabla (x,y)
% Help of function
for i=1:length(x)
z(i) = x(i)*y(i);
end
</code></pre>
<ol>
<li>Ported to geometry</li>
</ol>
<pre><code class="language-octave">
# Copyright - Somebody
# Bla bla
# bla bla bla
# texinfo
# Help of function
function z = blabla (x,y)
z = x .* y;
endfunction
</code></pre>
<ol>
<li>Updated in matGeom</li>
</ol>
<pre><code class="language-octave">
% Bla bla
% bla bla bla
function z = blabla (x,y)
% Help of function
% updated to be more clear
z = zeros (size(x));
for i=1:length(x)
z(i) = x(i)*y(i);
end
</code></pre>
<ol>
<li>After syncing , the expected result is something like this :</li>
</ol>
<pre><code class="language-octave">
# Copyright - Somebody
# Bla bla
# bla bla bla
# texinfo
# Help of function
# updated to be more clear
function z = blabla (x,y)
z = zeros (size(x));
z = x .* y;
endfunction
</code></pre>
<p>But, this doesn’t happen as expected. Git just finds the files which have been modified and overwrites those files completely.
Considering the possibilities of the solutions, there are ways like <code class="highlighter-rouge">git patch</code> or <code class="highlighter-rouge">git interactive</code> which allows us to select the lines specifically which we want to be committed, but that would not serve our purpose as it would not be better than syncing it manually, file by file. Looking for a better solution to handle this !</p>
<p>Now, the further idea is to release geometry and I am getting involved into it to get a feel of how things are done.</p>
<p>Thus, as the time concludes, it’s time to say Goodbye to GSoC’17. It was overall a great learning experience.</p>Piyush Jainhttps://piyush-jain1.github.io//Integral functionstag:blogger.com,1999:blog-8509760576772091576.post-57777785700050860242017-08-19T02:32:44+00:00Integral functionsDuring the last week I made few modifications to expint.m and wrote sinint.m and cosint.m from scratch. All the work done can be found on the bookmark expint of <a href="https://bitbucket.org/M_Ginesi/octave">my repository</a>. <h2>expint</h2>As I mentioned <a href="http://gsocspecfun.blogspot.it/2017/05/expint.html">here</a> I rewrote expint.m from scratch before the GSoC. During the last week I moved the Lentz algorithm to a .cc function (in order to remain coherent with the implementations of gammainc and betainc) and added few tests. <h2>sinint</h2>The sinint function is present in the symbolic package, but is not present a numerical implementation in the core.<br />The sine integral is defined as $$ \text{Si} (z) = \int_0^z \frac{\sin(t)}{t}\,dt. $$ To compute it we use the series expansion $$ \text{Si}(z) = \sum_{n=0}^\infty \frac{(-1)^n z^{2n+1}}{(2n+1)(2n+1)!} $$ when the module of the argument is smaller than 2. For bigger values we use the following relation with the exponential integral $$ \text{Si} = \frac{1}{2i} (E_1(iz)-E_1(-iz)) + \frac{\pi}{2},\quad |\text{arg}(z)| \frac{\pi}{2}$$ and the following simmetry relations $$ \text{Si}(-z) = -\text{Si}(z), $$ $$ \text{Si}(\bar{z}) = \overline {\text{Si}(z)}. $$ The function is write as a single .m file. <h2>cosint</h2>As the sinint function, also cosint is present in the symbolic package, but there is not a numerical implementation in the core.<br />The cosine integral is defined as $$ \text{Ci} (z) = -\int_z^\infty \frac{\cos(t)}{t}\,dt. $$ An equivalent definition is $$ \text{Ci} (z) = \gamma + \log z + \int_0^z \frac{\cos t - 1}{t}\,dt. $$ To compute it we use the series expansion $$ \text{Ci}(z) = \gamma + \log z + \sum_{n=1}^\infty \frac{(-1)^n z^{2n}}{(2n)(2n)!} $$ when the module of the argument is smaller than 2. For bigger values we use the following relation with the exponential integral $$ \text{Ci} = -\frac{1}{2} (E_1(iz)+E_1(-iz)),\quad |\text{arg}(z)| \frac{\pi}{2}$$ and the following simmetry relations $$ \text{Ci}(-z) = \text{Ci}(z) -i\pi,\quad 0\text{arg}(z)\pi, $$ $$ \text{Ci}(\bar{z}) = \overline{\text{Ci}(z)} .$$ As for sinint, also cosint is written as a single .m file.Michele Ginesinoreply@blogger.comhttp://gsocspecfun.blogspot.com/The Final Polishtag:blogger.com,1999:blog-3508201418641099808.post-1539978449745527602017-08-18T17:01:11+00:00We are preparing for releasing version 3.0.0 of the interval package and this last week have mainly been about fixing minor bugs related to the release. I mention two of the more interesting bugs here.<br /><h3>Compact Format </h3>We (Oliver) recently added support for "format compact" when printing intervals. It turns out that the way to determine if compact format is enabled differs very much between different version of Octave. There are at least three different ways to get the information.<br /><br />In the older releases (< 4.2.0 I believe) you use "get (0, "FormatSpacing")" but there appear to be a bug for version < 4.0.0 for which this always return "loose".<br /><br />For the current tip of the development branch you can use "[~, spacing] = format ()" to get the spacing.<br /><br />Finally in between these two version you use "__compactformat__ ()".<br /><br />In the end Oliver, probably, found a way to handle this mess and compact format should now be fully supported for intervals. The function to do this is available here <a href="https://sourceforge.net/p/octave/interval/ci/default/tree/inst/@infsup/private/__loosespacing__.m">https://sourceforge.net/p/octave/interval/ci/default/tree/inst/@infsup/private/__loosespacing__.m</a>.<br /><h3>Dot-product of Empty Matrices</h3>When updating "dot" to support N-dimensional arrays I also modified it so that it behaves similar to Octaves standard implementation. The difference is in how it handles empty input. Previously we had<br /><span><br />> x = infsupdec (ones (0, 2));<br />> dot (x, x)<br />ans = 0×2 interval matrix<br /></span><br />but with the new version we get<br /><span><br />> dot (x, x)<br />ans = 1×2 interval vector<br /> [0]_com [0]_com<br /></span><br />which is consistent with the standard implementation.<br /><br />In the function we use "min" to compute the decoration for the result. Normally "min (x)" and "dot (x, x)" returns results of the same size (the dimension along which it is computed is set to 1), but they handle empty input differently. We have<br /><span><br />> x = ones (0, 2);<br />> dot (x, x)<br />ans =<br /> 0 0<br />> min (x)<br />ans = [](0x2)<br /></span><br />This meant that the decoration would be incorrect since the implementation assumed they always had the same size. Fortunately the solution was very simple. If the dimension along which we are computing the dot-product is zero. the decoration should always be "com". So just adding a check for that was enough.<br /><br />You could argue that "min (ones (0, 2))" should return "[inf, inf]" similarly to how many of the other reductions, like "sum" or "prod", return their unit for empty input. But this would most likely be very confusing for a lot of people. And it is not compatible with how Matlab does it either.<br /><h2>Updates on the Taylor Package</h2>I have also had some time to work on the Taylor package this week. The basic utility functions are now completed and I have started to work on functions for actually computing with Taylor expansions. At the moment there are only a limited amount of functions implemented. For example we can calculate the Taylor expansion of order 4 for the functions $\frac{e^x + \log(x)}{1 + x}$ at $x = 5$.<br /><br /><span>## Create a variable of degree 4 and with value 5 </span><br /><span>> x = taylor (infsupdec (5), 4)<br />x = [5]_com + [1]_com X + [0]_com X^2 + [0]_com X^3 + [0]_com X^4</span><br /><span>## Calculate the function </span><br /><span>> (exp (x) + log (x))./(1 + x)<br />ans = [25.003, 25.004]_com + [20.601, 20.602]_com X + [8.9308, 8.9309]_com X^2 + [2.6345, 2.6346]_com X^3 + [0.59148, 0.59149]_com X^4<br /></span><br /><br /><br />Joel Dahnenoreply@blogger.comhttps://gsocinterval.blogspot.com/betaincinvtag:blogger.com,1999:blog-8509760576772091576.post-29003933909760764402017-08-12T08:52:18+00:00betaincinvThe inverse of the incomplete beta function was present in Octave, but without the "upper" option (since it was missing in betainc itself). We decided to rewrite it from scratch using Newton method, as for gammaincinv (see <a href="http://gsocspecfun.blogspot.it/2017/06/gammaincinv.html">my post on it</a> if you are interested).<br />To make the code numerically more accurate, we decide which version ("lower" or "upper") invert depending on the inputs.<br />At first we compute the trivial values (0 and 1). Then the remaining terms are divided in two sets: those that will be inverted with the "lower" version, and those that will be inverted with the "upper" one. For both cases, we perform 10 iterations of bisection method and then we perform a Newton method.<br />The implementation (together with the new implementation of betainc) can be found on <a href="https://bitbucket.org/M_Ginesi/octave">my repository</a>, bookmark "betainc".Michele Ginesinoreply@blogger.comhttp://gsocspecfun.blogspot.com/Improving the Automatic Teststag:blogger.com,1999:blog-3508201418641099808.post-69913378885500340682017-08-11T15:04:54+00:00Oliver and I have been working on improving the test framework used for the interval package. The package shares a large number of tests with other interval packages through an interval test framework that Oliver created. Here is the <a href="https://github.com/oheim/ITF1788">repository</a>.<br /><br /><h2>Creating the Tests</h2>Previously these tests were separated from the rest of the package and you usually ran them with help of the Makefile. Now Oliver has moved them to the m-files and you can run them, together with the other tests for the function, with <i>test @infsup/function</i> in Octave. This makes it much easier to test the functions directly.<br /><br />In addition to making the tests easier to use we also wanted to extend them to not only test scalar evaluation but also vector evaluation. The test data, input ad expected output, is stored in a cell array and when performing the scalar testing we simply loop over that cell and run the function for each element. The actual code looks like this (in this case for <i>plus</i>)<br /><span><br />%!test<br />%! # Scalar evaluation<br />%! testcases = testdata.NoSignal.infsup.add;<br />%! for testcase = [testcases]'<br />%! assert (isequaln (...<br />%! plus (testcase.in{1}, testcase.in{2}), ...<br />%! testcase.out));<br />%! endfor<br /></span><br />For testing the vector evaluation we simply concatenate the cell array into a vector and give that to the function. Here is what that code looks like<br /><span><br />%! # Vector evaluation<br />%! testcases = testdata.NoSignal.infsup.add;<br />%! in1 = vertcat (vertcat (testcases.in){:, 1});<br />%! in2 = vertcat (vertcat (testcases.in){:, 2});<br />%! out = vertcat (testcases.out);<br />%! assert (isequaln (plus (in1, in2), out));<br /></span><br />Lastly we also wanted to test evaluation of N-dimensional arrays. This is done by concatenating the data into a vector and then reshape that vector into an N-dimensional array. But what size should we use for the array? Well, we want to have at least three dimensions because otherwise we are not really testing N-dimensional arrays. My solution was to completely factor the length of the vector and use that as size, <i>testsize = factor (length (in1))</i>, and if the length of the vector has two or fewer factors we add a few elements to the end until we get at least three factors. This is the code for that<br /><span><br />%!test<br />%! # N-dimensional array evaluation<br />%! testcases = testdata.NoSignal.infsup.add;<br />%! in1 = vertcat (vertcat (testcases.in){:, 1});<br />%! in2 = vertcat (vertcat (testcases.in){:, 2});<br />%! out = vertcat (testcases.out);<br />%! # Reshape data<br />%! i = -1;<br />%! do<br />%! i = i + 1;<br />%! testsize = factor (numel (in1) + i);<br />%! until (numel (testsize) > 2)<br />%! in1 = reshape ([in1; in1(1:i)], testsize);<br />%! in2 = reshape ([in2; in2(1:i)], testsize);<br />%! out = reshape ([out; out(1:i)], testsize);<br />%! assert (isequaln (plus (in1, in2), out));<br /></span><br />This works very well, except when the number of test cases is to small. If the number of test is less than four this will fail. But there are only a handful of functions with that few tests so I fixed those independently.<br /><h2>Running the tests</h2>Okay, so we have created a bunch of new tests for the package. Do we actually find any new bugs with them? Yes!<br /><br />The function <i>pow.m</i> failed on the vector test. The problem? In one place $\&\&$ was used instead of $\&$. For scalar input I believe these behave the same but they differ for vector input.<br /><br />Both the function <i>nthroot.m </i>and the function <i>pownrev.m</i> failed the vector test. Neither allowed vectorization of the integer parameter. For <i>nthroot.m</i> this is the same for standard Octave version so it should perhaps not be treated as a bug. The function <i>pownrev.m</i> uses <i>nthroot.m</i> internally so it also had the same limitation. This time I would however treat it as a bug because the function <i>pown.m</i> does allow vectorization of the integer parameter and if that supports it the reverse function should probably also do it. So I implemented support for vectorization of the integer parameter for both <i>nthroot.m and pownrev.m </i>and they now pass the test.<br /><br />No problems were found with the N-dimensional tests that the vector tests did not find. This is a good indication that the support for N-dimensional arrays is at least partly correct. Always good to know!Joel Dahnenoreply@blogger.comhttps://gsocinterval.blogspot.com/betainctag:blogger.com,1999:blog-8509760576772091576.post-5473042996657855272017-08-02T04:12:36+00:00table, th, td { border: 1px solid black; } betaincThe betainc function has two bugs reported: <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=34405">#34405</a> on the input validation and <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=51157">#51157</a> on inaccurate result. Moreover, it is missing the "upper" version, which is present in MATLAB. <h1>The function</h1>The <i>incomplete beta function ratio</i> is defined as $$I_x(a,b) = \dfrac{B_x(a,b)}{B(a,b)},\quad 0\le x \le 1,\,a>0,\,b>0,$$ where $B(a,b)$ is the classical beta function and $$B_x(a,b)=\int_0^x t^{a-1}(1-t)^{b-1}\,dt.$$ In the "upper" version the integral goes from $x$ to $1$. To compute this we will use the fact that $$\begin{array}{rcl} I_x(a,b) + I_x^U(a,b) &=& \dfrac{1}{B(a,b)}\left( \int_0^x t^{a-1}(1-t)^{b-1}\,dt + \int_x^1 t^{a-1}(1-t)^{b-1}\,dt\right)\\ &=&\dfrac{1}{B(a,b)}\int_0^1 t^{a-1}(1-t)^{b-1}\,dt\\ &=&\dfrac{B(a,b)}{B(a,b)}\\ &=&1 \end{array}$$ and the relation $$I_x(a,b) + I_{1-x}(b,a) = 1$$ so that $$I_x^U(a,b) = I_{1-x}(b,a).$$ <h1>The implementation</h1>Even if it is possible to obtain a Taylor series representation of the incomplete beta function, it seems to not be used. Indeed the MATLAB help cite only the continuous fraction representation present in "Handbook of Mathematical Functions" by Abramowitz and Stegun: $$I_x(a,b) = \dfrac{x^a(1-x)^b}{aB(a,b)}\left(\dfrac{1}{1+} \dfrac{d_1}{1+} \dfrac{d_2}{1+}\ldots\right)$$ with $$d_{2m+1} = -\dfrac{(a+m)(a+b+m)}{(a+2m)(a+2m+1)}x$$ and $$d_{2m} = \dfrac{m(b-m)}{(a+2m-1)(a+2m)}x$$ which seems to be the same strategy used by GSL. To be more precise, this continued fraction is computed directly when $$x\dfrac{a-1}{a+b-2}$$ otherwise, the computed fraction is used to compute $I_{1-x}(b,a)$ and then it is used the fact that $$I_x(a,b) = 1-I_{1-x}(b,a).$$ In my implementation I use a continued fraction present in "Handboob of Continued Fractions for Special Functions" by Cuyt, Petersen, Verdonk, Waadeland and Jones, which is more complicated but converges in fewer steps: $$\dfrac{B(a,b)I_x(a,b)}{x^a(1-x)^b} = \mathop{\huge{\text{K}}}_{m=1}^\infty \left(\dfrac{\alpha_m(x)}{\beta_m(x)}\right),$$ where $$\begin{array}{rcl} \alpha_1(x) &=&1,\\ \alpha_{m+1}(x) &=&\dfrac{(a+m-1)(a+b+m-1)(b-m)m}{(a+2m-1)^2}x^2,\quad m\geq 1,\\ \beta_{m+1}(x) &=&a + 2m + \left( \dfrac{m(b-m)}{a+2m-1} - \dfrac{(a+m)(a+b+m)}{a+2m+1} \right)x,\quad m\geq 0. \end{array}$$ This is most useful when $$x\leq\dfrac{a}{a+b},$$ thus, the continued fraction is computed directly when this condition is satisfied, while it is used to evaluate $I_{1-x}(b,a)$ otherwise.<br />The function is now written as a .m file, which check the validity of the inputs and divide the same in the values which need to be rescaled and in those wo doesn't need it. Then the continued fraction is computed by an external .c function. Finally, the .m file explicit $I_x(a,b)$. <h1>betaincinv</h1>Next step will be to write the inverse. It was already present in Octave, but is missing the upper version, so it has to be rewritten.Michele Ginesinoreply@blogger.comhttp://gsocspecfun.blogspot.com/Second period resumetag:blogger.com,1999:blog-8509760576772091576.post-67833649216937534862017-08-01T09:30:18+00:00Second period resumetd, th{ border: 1px solid } Here I present a brief resume of the work done in this second month. <h2>Bessel functions</h2>The topic of this month were Bessel functions. On the bug tracker it is reported only a problem regarding the "J" one (see <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=48316">bug 48316</a>), but the same problem is present in every type of Bessel function (they return <tt>NaN + NaNi</tt> when the argument is too big). <h3>Amos, Cephes, C++ and GSL</h3>Actually, Bessel functions in Octave are computed via the Amos library, written in Fortran. Studying the implementation I discovered that the reported bug follows from the fact that if the input is too large in module, the function <tt>zbesj.f</tt> set IERR to 4 (IERR is a variable which describe how the algorithm has terminate) and set the output to zero, then <tt>lo-specfunc.cc</tt> return NaN when IERR=4. Obviusly, the same happen for other Bessel functions.<br />What I initially did was to "unlock" these .f files in such a way to give still IERR=4, but computing anyway the output, and modify <tt>lo-specfun.cc</tt> in order to return the value even if IERR is 4. Then I tested the accuracy, together with other libraries.<br />On the bug report where suggested the <a href="http://www.netlib.org/cephes/">Cephes library</a>, so I tested also them, the <a href="http://en.cppreference.com/w/cpp/numeric/special_math">C++ Special mathematical functions library</a>, and the <a href="https://www.gnu.org/software/gsl/">GSL (Gnu Scientific library)</a>. Unfortunately, both these alternatives work worse than Amos. I also tried to study and implement some asymptotic expansions by myself to use in the cases which give inaccurate results, unfortunately without success.<br />For completeness, in the following table there are some results of the tests (ERR in Cephes refers to <tt>cos total loss of precision error</tt>): <table> <tr> <th></th> <th>1e09</th> <th>1e10</th> <th>1e11</th> <th>1e12</th> <th>1e13</th> </tr> <tr> <td>Amos</td> <td>1.6257e-16</td> <td>0.0000e+00</td> <td>0.0000e+00</td> <td>1.3379e-16</td> <td>1.1905e-16</td> </tr> <tr> <td>Cephes</td> <td>2.825060e-08</td> <td>ERR</td> <td>ERR</td> <td>ERR</td> <td>ERR</td> </tr> <tr> <td>GSL</td> <td>4.8770e-16</td> <td>2.2068e-16</td> <td>4.2553e-16</td> <td>1.3379e-16</td> <td>1.1905e-16</td> </tr> <tr> <td>C++</td> <td>2.82506e-08</td> <td>2.68591e-07</td> <td>1.55655e-05</td> <td>8.58396e-07</td> <td>0.000389545</td> </tr></table><br /><br /> <table> <tr> <th></th> <th>1e15</th> <th>1e20</th> <th>1e25</th> <th>1e30</th> </tr> <tr> <td>Amos</td> <td>1.3522e-16</td> <td>1.6256e-16</td> <td>15.22810</td> <td>2.04092</td> </tr> <tr> <td>GSL</td> <td>1.3522e-16</td> <td>0</td> <td>15.22810</td> <td>2.04092</td> </tr></table> <h3>The problem with the double precision</h3>As I explained in <a href="http://gsocspecfun.blogspot.it/2017/07/gnu-scientific-library.html">my last post</a> the problem seems to be that there are no efficient algorithms in double precision for arguments so large. In fact, the error done by Amos is quite small if compared with the value computed with SageMath (which I'm using as reference one), but only if we use the double precision also in Sage: using more digits, one can see that even the first digit change. Here the tests:<br /><tt>sage: bessel_J(1,10^40).n()<br />7.95201138653707e-21<br />sage: bessel_J(1,10^40).n(digits=16)<br />-7.522035532561300e-21<br />sage: bessel_J(1,10^40).n(digits=20)<br />-5.7641641376196142462e-21<br />sage: bessel_J(1,10^40).n(digits=25)<br />1.620655257788838811378880e-21<br />sage: bessel_J(1,10^40).n(digits=30)<br />1.42325562284462027823158499095e-21<br />sage: bessel_J(1,10^40).n(digits=35)<br />1.4232556228446202782315849909515310e-21<br />sage: bessel_J(1,10^40).n(digits=40)<br />1.423255622844620278231584990951531026335e-21<br /></tt>The value stabilizes only when we use more than 30 digits (two times the digits used in double precision). <h3>The decision</h3>Even if we are aware of the fact that the result is not always accurate, for MATLAB compatibility we decided to unlock the Amos, since they are still the most accurate and, even more important, the type of the inputs is the same as in MATLAB (while, for example, GSL doesn't accept complex $x$ value). Moreover, in Octave is possible to obtain in output the value of IERR, thing that is not possible in MATLAB.<br />You can find the work on the bookmark "bessel" of <a href="https://bitbucket.org/M_Ginesi/octave">my repository</a>. <h2>Betainc</h2>During these last days I also started to implement betainc from scratch, I think it will be ready for the first days of August. Then, it will be necessary to rewrite also betaincinv, since the actual version doesn't have the "upper" version. This should not be too difficult. I think we can use a simple Newton method (as for gammaincinv), the only problem will be, as for gammaincinv, to find good initial guesses.Michele Ginesinoreply@blogger.comhttp://gsocspecfun.blogspot.com/A Package for Taylor Arithmetictag:blogger.com,1999:blog-3508201418641099808.post-60010620882918607362017-07-28T21:56:13+00:00In the last blog post I wrote about what was left to do with implementing support for N-dimensional arrays in the interval package. There are still some things to do but I have had, and most likely will have, some time to work on other things. Before the summer I started to work on a proof of concept implementation of Taylor arithmetic in Octave and this week I have continued to work on that. This blog post will be about that.<br /><br /><h2>A Short Introduction to Taylor Arithmetic</h2>Taylor arithmetic is a way to calculate with truncated Taylor expansions of functions. The main benefit is that it can be used to calculate derivatives of arbitrary order.<br /><br />Taylor expansion or Taylor series (I will use these words interchangeably) are well known and from Wikipedia we have: The Taylor series of real or complex valued function $f(x)$ that is infinitely differentiable at a real or complex number $a$ is the power series<br />$$<br />f(a) + \frac{f'(a)}{1!}(x-a) + \frac{f''(a)}{2!}(x-a)^2 + \frac{f'''(a)}{3!}(x-a)^3 + ....<br />$$<br />From the definition it is clear that if we happen to know the coefficients of the Taylor series of $f$ at the point $a$ we can also calculate all derivatives of $f$ at that point by simply multiplying a coefficient with the corresponding factorial.<br /><br />The simplest example of Taylor arithmetic is addition of two Taylor series. If $f$ has the Taylor series $\sum_{n=0}^\infty (f)_n (x-a)^n$ and $g$ the Taylor series $\sum_{n=0}^\infty (g)_n (x-a)^n$ then $f + g$ will have the Taylor series<br />$$<br />\sum_{n=0}^\infty (f + g)_n (x-a)^n = \sum_{n=0}^\infty ((f)_n + (g)_n)(x-a)^n$<br />$$<br />If we instead consider the product, $fg$, we get<br />$$<br />\sum_{n=0}^\infty (fg)_n (x-a)^n = \sum_{n=0}^\infty \left(\sum_{i=0}^n (f)_n(g)_n\right)(x-a)^n.<br />$$<br /><br />With a bit of work you can find similar formulas for other standard functions. For example the coefficients, $(e^f)_n$, of the Taylor expansion of $\exp(f)$ is given by $(e^f)_0 = e^{(f)_0}$ and for $n > 0$<br />$$<br />(e^f)_n = \frac{1}{n}\sum_{i=0}^{n-1}(k-j)(e^f)_i(f)_{n-i}.<br />$$<br /><br />When doing the computations on a computer we consider truncated Taylor series, we choose an order and keep only coefficients up to that order. There is also nothing that stops us from using intervals as coefficients, this allows us to get rigorous enclosures of derivatives of functions.<br /><br />For a more complete introduction to Taylor arithmetic in conjunction with interval arithmetic see [1] which was my first encounter to it. For another implementation of it in code take a look at [2].<br /><h2>Current Implementation Status</h2>As mentioned in the last post my repository can be found <a href="https://github.com/Urathai/octave-taylor-POC">here</a><br /><br />When I started to write on the package, before summer, my main goal was to get something working quickly. Thus I implemented the basic functions needed to do some kind of Taylor arithmetic, a constructor, some help functions and a few functions like $\exp$ and $\sin$.<br /><br />This last week I have focused on implementing the basic utility functions, for example $size$, and rewriting the constructor. In the process I think I have broken the arithmetic functions, I will fix them later.<br /><br />You can at least create and display Taylor expansions now. For example creating a variable $x$ with value 5 of order 3<br /><span><br />> x = taylor (infsupdec (5), 3)<br />x = [5]_com + [1]_com X + [0]_com X^2 + [0]_com X^3<br /></span><br />or a matrix with 4 variables of order 2<br /><span><br />> X = taylor (infsupdec ([1, 2; 3, 4]), 2)<br />X = 2×2 Taylor matrix of order 2<br /><br />ans(:,1) =<br /><br /> [1]_com + [1]_com X + [0]_com X^2<br /> [3]_com + [1]_com X + [0]_com X^2<br /><br />ans(:,2) =<br /><br /> [2]_com + [1]_com X + [0]_com X^2<br /> [4]_com + [1]_com X + [0]_com X^2<br /></span><br />If you want you can create a Taylor expansion with explicitly given coefficients you can do that as well<br /><span><br />> f = taylor (infsupdec ([1; -2; 3, -4))<br />f = [1]_com + [-2]_com X + [3]_com X^2 + [-4]_com X^3<br /></span><br />This would represent a function $f$ with $f(a) = 1$, $f'(a) = -2$, $f''(a) = 3 \cdot 2! = 6$ and $f'''(a) = -4 \cdot 3! = -24$.<br /><h2>Creating a Package</h2>My goal is to create a full package for Taylor arithmetic along with some functions making use of it. The most important step is of course to create a working implementation but there are other things to consider as well. I have a few things I have not completely understood about it. Depending on how much time I have next week I will try to read a bit more about it probably ask some questions on the mailing list. Here are at least some of the things I have been thinking about<br /><h3>Mercurial vs Git?</h3>I have understood that most of the Octave forge packages uses Mercurial for version control. I was not familiar with Mercurial before so the natural choice for me was to use Git. Now I feel I could switch to Mercurial if needed but I would like to know the potential benefits better, I'm still new to Mercurial so I don't have the full picture. One benefit is of course that it is easier if most packages use the same system, but other than that?<br /><h3>How much work is it?</h3>If I were to manage a package for Taylor arithmetic how much work is it? This summer I have been working full time with Octave so I have had lots of time but this will of course not always be the case. I know it takes time if I want to continue to improve the package, but how much, and what, continuous work is there?<br /><h3>What is needed besides the implementation?</h3>From what I have understood there are a couple of things that should be included in a package besides the actual m-files. For example a Makefile for creating the release, an INDEX-file and a CITATION-file. I should probably also include some kind of documentation, especially since Taylor arithmetic is not that well known. Is there anything else I need to think about? <br /><h3>What is the process to get a package approved?</h3>If I were to apply (whatever that means) for the package to go to Octave forge what is the process for that? What is required before it can be approved and what is required after it is approved?<br /><br /><br />[1] W. Tucker, Validated Numerics, Princeton University Press, 2011.<br />[2] F. Blomquist, W. Hofschuster, W. Krämer, Real and complex taylor arithmetic in C-XSC, Preprint 2005/4, Bergische Universität Wuppertal.Joel Dahnenoreply@blogger.comhttps://gsocinterval.blogspot.com/Deep learning functionstag:blogger.com,1999:blog-3202743535685562583.post-42785794561545122712017-07-27T21:34:59+00:00<span>Hi there,</span><br /><span><br /></span><span>the second part of the project is finishing. This period was quite interesting because I had to dive into the theory behind Neural Networks In particular [1], [2], [3] and [4] were very useful and I will sum up some concepts here below. On the other hand,</span><span> coding became more challenging and t</span><span>he focus was on the python layer and in particular the way to structure the class in order to make everything scalable and generalizable. Summarizing the situation, in the first period I implemented all the Octave classes for the user interface. Those are Matlab compatible and they call some Python function in a seamless way. On the Python side, the TensorFlow API is used to build the graph of the Neural Network and perform training, evaluation and prediction.</span><br /><br /><span>I implemented the three core functions: trainNetwork, SeriesNetwork and trainingOptions. To do this, I used a Python class in which I initialize an object with the graph of the network and I store this object as attribute of SeriesNetwork. Doing that, I call the methods of this class from trainNetwork to perform the training and from predict/classify to perform the predictions. Since it was quite hard to have a clear vision of the situation, I used a Python wrapper (Keras) that allowed me to focus on the integration, "unpack" the problem and go forth "module" by "module". Now I am removing the dependency on the Keras library using directly the Tensorflow API. The code in my repo [5].</span><br /><br /><span>Since I have already explained in last posts how I structured the package, in this post I would like to focus on the theoretical basis of the deep learning functions used in the package. In particular I will present the available layers and the parameters that are available for the training. </span><br /><span><br /></span><br /><h2><span>Theoretical dive</span></h2><h3><span>I. Fundamentals</span></h3><div><span>I want to start with a brief explanation about the perceptron and the back propagation, two key concepts in the artificial neural networks world. </span></div><div><span><br /></span></div><b><span>Neurons</span></b><br /><span><br /></span><span>Let's start from the perceptron, that is the starting point for understanding neural networks and its components. A perceptron is simply a "node" that takes several binary inputs, <span> $ x_1, x_2, ... $, </span>and produces a single binary output:</span><br /><span><br /></span><span>The neuron's output, 0 or 1, is determined by whether the linear combination of the inputs $ \omega \cdot x = \sum_j \omega_j x_j $ is less than or greater than some threshold value. That is a simple mathematical model but is very versatile and powerful because we can combine many perceptrons and varying the weights and the threshold we can get different models. Moving the threshold to the other side of the inequality and replacing it by what's known as the perceptron's bias, b = −threshold, we can rewrite it as</span><br /><span><br /></span><br /><div><span> $ out = \bigg \{ \begin{array}{rl} 0 & \omega \cdot x + b \leq 0 \\ 1 & \omega \cdot x + b > 0 \\ \end{array} $ </span><br /><span><br /></span></div><span>Using the perceptrons like artificial neurons of a network, it turns out that we can devise learning algorithms which can automatically tune the weights and biases. This tuning happens in response to external stimuli, without direct intervention by a programmer and this enables us to have an "automatic" learning.</span><br /><span><br /></span><span>Speaking about learning algorithms, the proceedings are simple: we suppose we make a small change in some weight or bias and what see the corresponding change in the output from the network. If a small change in a weight or bias causes only a small change in output, then we could use this fact to modify the weights and biases to get our network to behave more in the manner we want. The problem is that this isn't what happens when our network contains perceptrons since a small change of any single perceptron can sometimes cause the output of that perceptron to completely flip, say from 0 to 1. We can overcome this problem by introducing an activation function. Instead of the binary output we use a function depending on weights and bias. The most common is the sigmoid function:</span><br /><div><span> $ \sigma (\omega \cdot x + b ) = \dfrac{1}{1 + e^{-(\omega \cdot x + b ) } } $ </span></div><div><span><br /></span><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="https://2.bp.blogspot.com/-V54xdcvuYKI/WXmj0GjP8pI/AAAAAAAAAoI/xDk4H26fiQ4M8bGkIET7g7vgJnLscb5fwCLcBGAs/s1600/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f382f38632f50657263657074726f6e5f6d6f6a2e706e67.png"><img border="0" height="150" src="https://2.bp.blogspot.com/-V54xdcvuYKI/WXmj0GjP8pI/AAAAAAAAAoI/xDk4H26fiQ4M8bGkIET7g7vgJnLscb5fwCLcBGAs/s400/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f382f38632f50657263657074726f6e5f6d6f6a2e706e67.png" width="400" /></a></td></tr><tr><td class="tr-caption">Figure 1. Single neuron </td></tr></tbody></table><br /></div><span>With the smoothness of the activation function $ \sigma $ we are able to analytically measure the output changes since $ \Delta out $ is a linear function of the changes $ \Delta \omega $ and $ \Delta b$ :</span><br /><div><span> $ \Delta out \approx \sum_j \dfrac{\partial out}{\partial \omega_j} \Delta \omega_j + \dfrac{\partial out}{\partial b} \Delta b $ </span></div><span><br /></span><b><span>Loss function</span></b><br /><span><br /></span><span>Let x be a training input and y(x) the desired output. What we'd like is an algorithm which lets us find weights and biases so that the output from the network approximates y(x) for all x. Most used loss function is mean squared error (MSE) :</span><br /><div><span> $ L( \omega, b) = \dfrac{1}{2n} \sum_x || Y(x) - out ||^2 $ ,</span></div><span>where n is the total number of training inputs, <i>out</i> is the vector of outputs from the network when x is input. </span><br /><span>To minimize the loss function, there are many optimizing algorithms. The one we will use is the gradient descend, of which every iteration of an epoch is defined as:</span><br /><div><span><br /></span></div><div><span> $ \omega_k \rightarrow \omega_k' = \omega_k - \dfrac{\eta}{m} \sum_j \dfrac{\partial L_{X_j}}{\partial \omega_k} $ </span></div><div><span> $ b_k \rightarrow b_k' = b_k - \dfrac{\eta}{m} \sum_j \dfrac{\partial L_{X_j}}{\partial b_k} $ </span></div><span><br /></span><span>where <i>m</i> is the size of the batch of inputs with which we feed the network and $ \eta $ is the learning rate.</span><br /><b><span><br /></span></b><b><span>Backpropagation</span></b><br /><span><br /></span><span>The last concept that I would like to emphasize is the backpropagation. Its goal is to compute the partial derivatives$ \partial L / \partial \omega $ and $ \partial L / \partial b} $ of the loss function L with respect to any weight or bias in the network. The reason is that those partial derivatives are computationally heavy and the network training would be excessively slow.</span><br /><span><br /></span><span>Let be $ z^l $ the <i>weighted input</i> to the neurons in layer <i>l</i>, that can be viewed as a linear function of the activations of the previous layer: $ z^l = \omega^l a^{l-1} + b^l $ .</span><br /><span>In the fundamental steps of backpropagation we compute:</span><br /><span><br /></span><span>1) the final error:</span><br /><div><span> $ \delta ^L = \Delta_a L \odot \sigma' (z^L) $ </span></div><div><span>The first term measures how fast the loss is changing as a function of every output activation and the second term measures how fast the activation function is changing at $ z_L $ </span></div><span><br /></span><span>2) the error of every layer <i>l:</i></span><br /><div><span> $ \delta^l = ((\omega^{l+1})^T \delta^{l+1} ) \odot \sigma' (z^l) $ </span></div><br /><div><span><br /></span></div><span>3) the partial derivative of the loss function with respect to any bias in the net</span><br /><div><span> $ \dfrac{\partial L}{\partial b^l_j} = \delta^l_j $ </span></div><br /><div><span><br /></span></div><span>4) the partial derivative of the loss function with respect to any weight in the net</span><br /><div><span> $ \dfrac{\partial L}{\partial \omega^l_{jk}} = a_k^{l-1} \delta^l_j $ </span></div><br /><div><span><br /></span></div><span>We can therefore update the weights and the biases with the gradient descent and train the network. Since inputs can be too numerous, we can use only a random sample of the inputs. Stochastic Gradient Descent (SGD) simply does away with the expectation in the update and computes the gradient of the parameters using only a single or a few training examples. In particular, we will use the SGD with momentum, that is a method that helps accelerate SGD in the relevant direction and damping oscillations. It does this by adding a fraction γ of the update vector of the past time step to the current update vector.</span><br /><span><br /></span><br /><h2><span>II. Layers</span></h2><span>Here a brief explanation of the functions that I am considering in the trainNetwork class</span><br /><span><br /></span><b><span>Convolution2DLayer</span></b><br /><span><br /></span><span>The convolution layer is the core building block of a convolutional neural network (CNN) and it does most of the computational heavy lifting. They derive their name from the “convolution” operator. The primary purpose of convolution is to extract features from the input image preserving the spatial relationship between pixels by learning image features using small squares of input data. </span><br /><span><br /></span><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="https://3.bp.blogspot.com/-1CRGQVGuooo/WXir66f-HTI/AAAAAAAAAnw/r_V3gB1hfsYsL8AhyZot9WgSB4eOfx-YgCLcBGAs/s1600/convolution_schematic.gif"><img border="0" src="https://3.bp.blogspot.com/-1CRGQVGuooo/WXir66f-HTI/AAAAAAAAAnw/r_V3gB1hfsYsL8AhyZot9WgSB4eOfx-YgCLcBGAs/s1600/convolution_schematic.gif" /></a></td></tr><tr><td class="tr-caption">Figure 2. Feature extraction with convolution (image taken form https://goo.gl/h7pXxf) </td></tr></tbody></table><span>In the example in Fig.2, the 3×3 matrix is called a 'filter' or 'kernel' and the matrix formed by sliding the filter over the image and computing the dot product is called the 'Convolved Feature' or 'Activation Map' (or the 'Feature Map'). In practice, a CNN learns the values of these filters on its own during the training process (although we still need to specify parameters such as number of filters, filter size, architecture of the network etc. before the training process). The more number of filters we have, the more image features get extracted and the better our network becomes at recognizing patterns in unseen images.</span><br /><span>The size of the Feature Map depends on three parameters: the depth (that corresponds to the number of filters we use for the convolution operation), the stride (that is the number of pixels by which we slide our filter matrix over the input matrix) and the padding (that consists in padding the input matrix with zeros around the border).</span><br /><span><b><br class="Apple-interchange-newline" />ReLULayer</b></span><br /><span><br /></span><span>ReLU stands for Rectified Linear Unit and is a non-linear operation: $ f(x)=max(0,x) $. Usually this is applied element-wise to the output of some other function, such as a matrix-vector product. It </span><span>replaces all negative pixel values in the feature map by zero with the purpose of introducing non-linearity in our network, since most of the real-world data we would want to learn would be non-linear.</span><br /><div><span><br /></span></div><span></span><span><b>FullyConnectedLayer</b></span><br /><br /><span>Neurons in a fully connected layer have full connections to all activations in the previous layer, as seen in regular Neural Networks. H</span><span>ence t</span><span>heir activations can be computed with a matrix multiplication followed by a bias offset. In our case, the purpose of the </span><span>fully-connected</span><span> layer is to use these features for classifying the input image into various classes based on the training dataset. Apart from classification, adding a fully-connected layer is also a cheap way of learning non-linear combinations of the features. </span><br /><br /><span><b>Pooling</b></span><br /><span><b><br /></b></span><span>It is common to periodically insert a pooling layer in-between successive convolution layers. </span><span>Spatial Pooling (also called subsampling or downsampling) reduces the dimensionality of each feature map but retains the most important information. </span><span>In particular, pooling</span><br /><span>- </span><span>makes the input representations (feature dimension) smaller and more manageable</span><br /><span>- </span><span>reduces the number of parameters and computations in the network, therefore, controlling overfitting</span><br /><span>- </span><span>makes the network invariant to small transformations, distortions and translations in the input image</span><br /><span>- </span><span>helps us arrive at an almost scale invariant representation of our image</span><span> </span><br /><span>Spatial Pooling can be of different types: Max, Average, Sum etc.</span><br /><span><br /></span><span><b>MaxPooling2DLayer</b></span><br /><span>In case of Max Pooling, we define a spatial neighborhood (for example, a 2×2 window) and take the largest element from the rectified feature map within that window. </span><br /><span><br /></span><span><b>AveragePooling2DLayer</b></span><br /><span>Instead of taking the largest element we could also take the average.</span><br /><br /><span><b>DropoutLayer</b></span><br /><span><br /></span><span>Dropout in deep learning works as follows: one or more neural network nodes is switched off once in a while so that it will not interact with the network. With dropout, the learned weights of the nodes become somewhat more insensitive to the weights of the other nodes and learn to decide somewhat more by their own. In general, dropout helps the network to generalize better and increase accuracy since the influence of a single node is decreased.</span><br /><div><br /></div><span><b>SoftmaxLayer</b></span><br /><span><b><br /></b></span><span>The purpose of the softmax classification layer is simply to transform all the net activations in your final output layer to a series of values that can be interpreted as probabilities. To do this, the softmax function is applied onto the net intputs.</span><br /><div><span> $ \phi_{softmax} (z^i) = \dfrac{e^{z^i}}{\sum_{j=0}^k e^{z_k^i}} $ </span></div><span><br /></span><span><br /></span> <span><b>CrossChannelNormalizationLayer</b></span><br /><span><b><br /></b></span><span>Local Response Normalization (LRN) layer implements the lateral inhibition that in neurobiology refers to the capacity of an excited neuron to subdue its neighbors.</span><span> This layer is useful when we are dealing with ReLU neurons because they have unbounded activations and we need LRN to normalize that. We want to detect high frequency features with a large response. If we normalize around the local neighborhood of the excited neuron, it becomes even more sensitive as compared to its neighbors. </span><span>At the same time, it will dampen the responses that are uniformly large in any given local neighborhood. If all the values are large, then normalizing those values will diminish all of them. So basically we want to encourage some kind of inhibition and boost the neurons with relatively larger activations.</span><br /><div><span><br /></span></div><h2>III. training options</h2><div><span>The training function takes as input a trainingOptions object that contains the parameters for the training. A brief explanation:</span><br /><span><br /></span><span><b>SolverName</b></span><br /><span>Optimizer chosen for minimize the loss function. To guarantee the Matlab compatibility, only the Stochastic Gradient Descent with Momentum ('sgdm') is allowed</span><br /><span><br /></span><span><b>Momentum</b></span><br /><span>Parameter for the <i>sgdm</i>: it corresponds to the contribution of the previous step to the current iteration</span><br /><span><br /></span><span><b>InitialLearnRate</b></span><br /><span>Initial learning rate <b>η </b>for the optimizer</span><br /><span><br /></span><span><b>LearnRateScheduleSettings</b></span><br /><span>These are the settings for regulating the learning rate. It is a struct containing three values:</span><br /><span><b>RateSchedule</b>: if it is set to '<i>piecewise', </i>the learning rate will drop of a </span><b>RateDropFactor </b><span>every a </span><b>RateDropPeriod </b><span>number of epochs.</span><i> </i><br /><br /><span><b>L2Regularization</b></span><br /><span>Regularizers allow to apply penalties on layer parameters or layer activity during optimization. This is the factor of the L2 regularization.</span><br /><span><br /></span><span><b>MaxEpochs</b></span><br /><span>Number of epochs for training</span><br /><span><br /></span><span><b>Verbose</b></span><br /><span>Display the information of the training every </span><span><b>VerboseFrequency </b>iterations</span><br /><br /><span><b>Shuffle</b></span><br /><span>Random shuffle of the data before training if set to <i>'once'</i></span><br /><span><br /></span><span><b>CheckpointPath</b></span><br />Path for saving the checkpoints<br /><br /><span><b>ExecutionEnvironment</b></span><br /><span>Chose of the hardware for the training: </span><span>'cpu', 'gpu', 'multi-gpu' or 'parallel'. the </span><span>load is divided between workers of GPUs or CPUs according to the r</span><span>elative division set by </span><b>WorkerLoad</b><br /><br /><span><b>OutputFcn</b></span><br />Custom output functions to call during training after each iteration passing a struct containing:<br />Current epoch number, Current iteration number, TimeSinceStart, TrainingLoss, BaseLearnRate, TrainingAccuracy (or TrainingRMSE for regression), State<br /><br />Peace,<br />Enrico<br /><br />[1] [Ian Goodfellow, Yoshua Bengio, Aaron Courville] Deep Learning, MIT Press, http://www.deeplearningbook.org, 2016<br />[2] http://ufldl.stanford.edu/tutorial/supervised/ConvolutionalNeuralNetwork/<br />[3] http://web.stanford.edu/class/cs20si/syllabus.html<br />[4] http://neuralnetworksanddeeplearning.com/<br />[5] https://bitbucket.org/cittiberto/octave-nnet/src</div>Enrico Bertinonoreply@blogger.comhttps://gsocnnet.blogspot.com/Ahead of the Timelinetag:blogger.com,1999:blog-3508201418641099808.post-77085844244945800762017-07-14T16:59:08+00:00One of my first posts on this blog was a <a href="https://gsocinterval.blogspot.se/2017/05/timeline.html">timeline</a> for my work during the project. Predicting the amount of time something takes is always hard to do. Often time you tend to underestimate the complexity of parts of the work. This time however I overestimated the time the work would take.<br /><br />If my timeline would have been correct I would have just started to work on Folding Functions (or reductions as they are often called). Instead I have completed the work on them and also for functions regarding plotting. In addition I have started to work on the documentation for the package as well as checking everything an extra time.<br /><br />In this blog post I will go through what I have done this week, what I think is left to do and a little bit about what I might do if I complete the work on N-dimensional arrays in good time. <br /><br /><h2>This Week</h2><h3>The Dot Function</h3>The $dot$-function was the last function left to implement support for N-dimensional arrays in. It is very similar to the $sum$-function so I already had an idea of how to do it. As with $sum$ I moved most of the handling of the vectorization from the m-files to the oct-file, the main reason being improved performance.<br /><br />The $dot$-functions for intervals is actually a bit different from the standard one. First of all it supports vectorization which the standard one does not<br /><span><br />> dot ([1, 2, 3; 4, 5, 6], 5)<br />error: dot: size of X and Y must match<br />> dot (infsupdec ([1, 2, 3; 4, 5, 6], 5)<br />ans = 1x3 interval vector<br /><br /> [25]_com [35]_com [45]_com<br /></span><br />It also treats empty arrays a little different, see <a href="https://savannah.gnu.org/bugs/?51333">bug #51333</a>,<br /><span><br />> dot ([], [])<br />ans = [](1x0)<br />> dot (infsupdec ([]), [])<br />ans = [0]_com</span><br /><span><br /></span><br /><h3>Package Documentation</h3>I have done the minimal required changes to the documentation. That is I moved support for N-dimensional arrays from Limitation to Features and added some simple examples on how to create N-dimensional arrays.<br /><br /><h3>Searching for Misses</h3>During the work I have tried to update the documentation for all functions to account for the support of N-dimensional arrays and I have also tried to update some of the comments for the code. But as always, especially when working with a lot of files, you miss things, both in the documentation and old comments.<br /><br />I did a quick grep for the words "matrix" and "matrices" since they are candidates for being changed to "array". Doing this I found 35 files where I missed things. It was mainly minor things, comments using the "matrix" which I now changed to "array", but also some documentation which I had forgotten to update.<br /><br /><h2>What is Left?</h2><h3>Package Documentation - Examples</h3>As mentioned above I have done the minimal required changes to the documentation. It would be very nice to add some more interesting example using N-dimensional arrays of intervals in a useful way. Ironically I have not been able to come up with an interesting example but I will continue to think about it. If you have an example that you think would be interesting and want to share, please let me know!<br /><br /><h3>Coding Style</h3>As I mentioned in one of the first blog posts, the coding style for the interval package was not following the standard for Octave. During my work I have adapted all files I have worked with to the coding standard for Octave. A lot of the files I have not needed to do any changes to, so they are still using the old style. It would probably be a good idea to update them as well.<br /><br /><h3>Testing - ITF1788</h3><a href="https://github.com/oheim/ITF1788">The interval framwork libary</a> developed by Oliver is used to test the correctness of many of the functions in the package. At the moment it tests evaluation of scalars but in principle it should be no problem to use it for testing vectorization or even broadcasting. Oliver has already started to work on <a href="https://github.com/oheim/ITF1788/issues/8">this</a>.<br /><br /><h2>After N-dimensional arrays?</h2>If I continue at this pace I will finish the work on N-dimensional arrays before the time of the project is over. Of course the things that are left might take longer than expected, they usually do, but there is a chance that I will have time left after everything is done. So what should I do then? There are more thing that can be done on the interval package, for example adding more examples to the documentation, however I think I would like to start working on a new package for Taylor arithmetics.<br /><br />Before GSoC I started to implement a proof of concept for Taylor arithmetics in Ocatve which can be found <a href="https://github.com/Urathai/octave-taylor-POC">here</a>. I would then start to work on implementing a proper version of it, where I would actually make use of N-dimensional interval arrays. If I want to create a package for this I would also need to learn a lot of other things, one of them being how to manage a package on octave forge.<br /><br />At the moment I will try to finish my work on N-dimensional arrays. Then I can discuss it with Oliver and see what he thinks about it.Joel Dahnenoreply@blogger.comhttps://gsocinterval.blogspot.com/Set inversion with fsolvetag:blogger.com,1999:blog-3508201418641099808.post-85256159847002398582017-07-13T10:24:52+00:00This week my work have mainly been focused on the interval version of <i>fsolve</i>. I was not sure if and how this could make use of N-dimensional arrays and to find that out I had to understand the function. In the end it turned out that the only generalization that could be done were trivial and required very few changes. However I did find some other problems with the functions that I have been able to fix. Connected to <i>fsolve</i> are the functions <i>ctc_intersect</i> and <i>ctc_union</i>. The also needed only minor changes to allow for N-dimensional input. I will start by giving an introduction to <i>fsolve, ctc_union</i> and <i>ctc_intersect</i> and then I will mention the changes I have done to them.<br /><br /><h2>Introduction to <i>fsolve</i></h2>The standard version of <i>fsolve </i>in Octave is used to solve systems of nonlinear equations<i>. </i>That is, given a functions $f$ and a starting point $x_0$ it returns a value $x$ such that $f(x)$ is close to zero. The interval version of <i>fsolve </i>does much more than this. It is used to enclose the preimage of a set $Y$ under $f$. Given a domain $X$, a set $Y$ and a function $f$ it returns an enclosure of the set<br />$$<br />f^{-1}(Y) = \{x \in X: f(x) \in Y\}.<br />$$ <br />By letting $Y = 0$ we get similar functionality as the standard <i>fsolve</i>, with the difference that the output is an enclosure of all zeros to the function (compared to one point for which $f$ returns close to zero).<br /><h3>Example: The Unit Circle</h3>Consider the function $f(x, y) = \sqrt{x^2 + y^2} - 1$ which is zero exactly on the unit circle. Plugging this in to the standard <i>fsolve</i> we get with $(0.5, 0.5)$ as a starting guess<br /><span><br />> x = fsolve (@(x) f(x(1), x(2)), [0.5, 0.5])<br />x = 0.70711 0.70711<br /></span><br />which indeed is close to a zero. But we get no information about other zeros.<br /><br />Using the interval version of <i>fsolve</i> with $X = [-3, 3] \times [-3, 3]$ as starting domain we get<br /><span><br />> [x paving] = fsolve (f, infsup ([-3, -3], [3, 3]));<br />> x<br />x ⊂ 2×1 interval vector<br /><br /> [-1.002, +1.002]<br /> [-1.0079, +1.0079]<br /></span><br />Plotting the paving we get the picture<br /><br /><div class="separator"><a href="https://4.bp.blogspot.com/-t7BsHJ-ac3M/WV9IULgbx3I/AAAAAAAAAXk/xtt9qHYkHrwjr3cGqxeuLXkgQkHIbDeZACLcBGAs/s1600/circle.png"><img border="0" height="300" src="https://4.bp.blogspot.com/-t7BsHJ-ac3M/WV9IULgbx3I/AAAAAAAAAXk/xtt9qHYkHrwjr3cGqxeuLXkgQkHIbDeZACLcBGAs/s400/circle.png" width="400" /></a></div>which indeed is a good enclosure of the unit circle.<br /><h3>How it works </h3>In its simplest form <i>fsolve</i> uses a simple bisection scheme to find the enclosure. Using interval methods we can find enclosure to images of sets. Given a set $X_0 \subset X$ we have three different possibilities<br /><ul><li>$f(X_0) \subset Y$ in which case we add $X_0$ to the paving</li><li>$f(X_0) \cap Y = \emptyset$ in which case we discard $X_0$</li><li>Otherwise we bisect $X_0$ and continue on the parts</li></ul>By setting a tolerance of when to stop bisecting boxes we get the algorithm to terminate in a finite number of steps.<br /><h3>Contractors</h3>Using bisection is not always very efficient, especially when the domain has many dimensions. One way to speed up the convergence is with what's called contractors. In short a contractor is a function that can take the set $X_0$ and returns a set $X_0' \subset X_0$ with the property that $f(X_0 \setminus X_0') \cap Y = \emptyset$. It's a way of making $X_0$ smaller without having to bisect it that many times.<br /><br />When you construct a contractor you use the reverse operations definer on intervals. I will not go into how this works, if you are interested you can find more information in the package documentation [1] and in these youtube videos about Set Inversion Via Interval Analysis (SIVIA) [2].<br /><br />The functions <i>ctc_union</i> and <i>ctc_intersect</i> are used to combine contractors on sets into contractors on unions or intersections of these sets.<br /><h2>Generalization to N-dimensional arrays</h2>How can <i>fsolve</i> be generalized to N-dimensional arrays? The only natural thing to do is to allow for the input and output of $f$ to be N-dimensional arrays. This also is no problem to do. While you mathematically probably would say that <i>fsolve</i> is used to do set inversion for functions $f: \mathbb{R}^n \to \mathbb{R}^m$ it can of course also be used for example on functions $f: \mathbb{R}^{n_1}\times \mathbb{R}^{n_2} \to \mathbb{R}^{m_1}\times \mathbb{R}^{m_2}$.<br /><br />This is however a bit different when using vectorization. When not using vectorization (and not using contractions) <i>fsolve</i> expects that the functions takes one argument which is an array with each element corresponding to a variable. If vectorization is used it instead assumes that the functions takes one argument for each variable. Every argument is then given as a vector with each element corresponding to one value of the variable for which to compute the function. Here we have no use of N-dimensional arrays.<br /><h2>Modifications</h2>The only change in functionality that I have done to the functions is to allow for N-dimensional arrays as input and output when vectorization is not used. This required only minor changes, essentially changing expressions like <span><br />max (max (wid (interval))) </span><br />to <span><br />max (wid (interval)(:)) </span><br />It was also enough to do these changes in <i>ctc_union</i> and <i>ctc_intersect</i> to have these support N-dimensional arrays.<br /><br />I have made no functional changes when vectorization is used. I have however made an optimization in the construction of the arguments to the function. The arguments are stored in an array but before being given to the function they need to be split up into the different variables. This is done by creating a cell array with each element being a vector with the values of one of the variables. Previously the construction of this cell array was very inefficient, it split the interval into its lower and upper part and then called the constructor to create an interval again. Now it copies the intervals into the cell without having to call the constructor. This actually seems have been quite a big improvement, using the old version the example with the unit circle from above took around 0.129 seconds and with the new version it takes about 0.092 seconds. This is of course only one benchmark, but a speed up of about 40% for this test is promising!<br /><br />Lastly I noticed a problem in the example used in the documentation of the function. The function used is<br /><span><br /># Solve x1 ^ 2 + x2 ^ 2 = 1 for -3 ≤ x1, x2 ≤ 3 again,<br /># but now contractions speed up the algorithm.<br />function [fval, cx1, cx2] = f (y, x1, x2)<br /> # Forward evaluation<br /> x1_sqr = x1 .^ 2;<br /> x2_sqr = x2 .^ 2;<br /> fval = hypot (x1, x2);<br /> # Reverse evaluation and contraction<br /> y = intersect (y, fval);<br /> # Contract the squares<br /> x1_sqr = intersect (x1_sqr, y - x2_sqr);<br /> x2_sqr = intersect (x2_sqr, y - x1_sqr);<br /> # Contract the parameters<br /> cx1 = sqrrev (x1_sqr, x1);<br /> cx2 = sqrrev (x2_sqr, x2);<br />endfunction<br /></span><br />Do you see the problem? I think it took me more than a day to realize that the problems I was having was not because of a bug in <i>fsolve</i> but because this function computes the wrong thing. The function is supposed to be $f(x_1, x_2) = x_1^2 + x_2^2$ but when calculating the value it calls hypot which is given by $hypot(x_1, x_2) = \sqrt{x_1^2 + x_2^2}$. For $f(x_1, x_2) = 1$, which is used in the example, it gives the same result, but otherwise it will of course not work.<br /><br />[1] <a href="https://octave.sourceforge.io/interval/package_doc/Parameter-Estimation.html#Parameter-Estimation">https://octave.sourceforge.io/interval/package_doc/Parameter-Estimation.html#Parameter-Estimation</a><br />[2] <a href="https://www.youtube.com/watch?v=kxYh2cXHdNQ">https://www.youtube.com/watch?v=kxYh2cXHdNQ</a><br /><br /><br />Joel Dahnenoreply@blogger.comhttps://gsocinterval.blogspot.com/Gnu Scientific Librarytag:blogger.com,1999:blog-8509760576772091576.post-84601096687673365162017-07-11T09:01:18+00:00<h2>Bessel functions</h2>During the second part of GSoC I have to work on Bessel functions. The bug is related in particular on the <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=48316">Bessel function of first kind</a> and regard the fact that the function is not computed if the $x$ argument is too big.<br />During this week I studied the actual implementation i.e. the Amos library, written in Fortran. The problem is related to the fact that zbesj.f simply refuse to compute the result when the input argument is too large (the same problem happens for all bessel functions, both for real and complex arguments). What I did was to "unlock" the amos in such a way to compute the value in any case (which seems to be the strategy used by MATLAB). Then I compared the relative errors with the relative errors done by the Gnu Scientific Library (GSL).<br />At first, I would precise some limitation present in GSL: <ul> <li> The parameter $x$ must be real, while it can be complex in Amos and MATLAB. The same holds for the parameter $\alpha$. </li> <li> The class of the output does not adapt to the class of the input, returning <b>always</b> a double. </li></ul>Doing some tests, it seems that the amos work better in terms of accuracy (even if we are talking about errors which do not differ in the order). I concentrated on values in which Amos usually refuse to compute, since in every other zone of the $x-\alpha$ plane it is known the error is in the order of 1e-15. For $\alpha\in\{-1,0,1\}$ they return the same result, while for other values of $\alpha$, Amos are in general more accurate.<br />Anyway, I would remark the fact that there are not, as far as I know, accurate algorithms in double precision for very large magnitude. In fact, for such arguments, both Amos and GSL make a relative error of the order of the unity. This problem is evident when using SageMath to compute accurate values, e.g.<br /><tt>sage: bessel_J(1,10^40).n()<br />7.95201138653707e-21<br />sage: bessel_J(1,10^40).n(digits=16)<br />-7.522035532561300e-21<br />sage: bessel_J(1,10^40).n(digits=20)<br />-5.7641641376196142462e-21<br />sage: bessel_J(1,10^40).n(digits=25)<br />1.620655257788838811378880e-21<br />sage: bessel_J(1,10^40).n(digits=30)<br />1.42325562284462027823158499095e-21<br />sage: bessel_J(1,10^40).n(digits=35)<br />1.4232556228446202782315849909515310e-21<br />sage: bessel_J(1,10^40).n(digits=40)<br />1.423255622844620278231584990951531026335e-21<br /></tt>The values "stabilize" only when the number of digits is bigger than 30, far away from double precision. <h2>Incomplete gamma function</h2>I also gave a look on how to use GSL to eventually improve the incomplete gamma function. It is not possible, however, to use only GSL functions gsl_sf_gamma_inc_P and gsl_sf_gamma_inc_Q due to their limitations: <ul> <li> There is no the "scaled" option. </li> <li> The value of $x$ must be real. This may be not a problem since even MATLAB does not accept complex value (while the version I worked on does). </li> <li> The parameter $x$ must be positive. This is actually a problem of MATLAB compatibility. </li> <li> The class of the output does not adapt to the class of the input, returning <b>always</b> a double. </li></ul>I tested the accuracy of the GSL and they work better when $a1$ and $x\ll1$ so I think I will fix gammainc.m using the algorithm of gsl_sf_gamma_inc_P and gsl_sf_gamma_inc_Q for that values of the input arguments. <h2>Incomplete Beta function</h2>The actual incomplete beta function needs to be replaced. I've already studied the continued fraction exapnsion (which seems to be the best one to use). In GSL is implemented in a good way but still present two limitations: <ul> <li> Does not adapt to the input class (it always work in double precision). </li> <li> There is no "upper" version. This is missing also in the current betainc function, but it is present in MATLAB. Unfortunately, it is not sufficient to compute it as $1 - I_x(a,b)$, it is necessary to find an accurate way to compute directly it. </li></ul>So I will take inspiration to GSL version of the function but I think I will write beatinc as a single .m file.Michele Ginesinoreply@blogger.comhttp://gsocspecfun.blogspot.com/First period resumetag:blogger.com,1999:blog-8509760576772091576.post-11161719239415148922017-07-01T07:58:38+00:00First period resume<h1>First period resume</h1>Here I present a brief resume of the work done in this first month. <h2>1st week: Gammainc</h2>The incomplete gamma function presented a series of inaccurate results in the previous implementation, so it has been decided to rewrite it from scratch. A big part of the work was done by Marco and Nir (<a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=47800">here</a> the discussion). I gave my contribution by fixing some problems in the implementation and by making a functioning commit (thanks to the suggestions given by Carne during the OctConf in Geneve). <h2>2nd and 3rd week: Gammaincinv</h2>The inverse of the incomplete gamma function was completely missing in Octave (and this was a problem of compatibility with Matlab). Now the function is present, written as a single .m file. The implementation consist in a simple, but efficient, Newton's method. <h2>Last week: Betainc</h2>When I first submitted my timeline, there was only a bug related to betainc, involving the input validation. During the first period of GSoC emerged a new bug of "incorrect result" type. From this, me and my mentor decided that it is necessary to rewrite the function, so I used this last week to study efficient algorithms to evaluate it. In particular, seems that the most efficient way is to use continude fractions, maybe after a rescale of the function. I'm already working on it, but I will complete it during the first week of august, after finishing the work on Bessel functions.Michele Ginesinoreply@blogger.comhttp://gsocspecfun.blogspot.com/One Month Intag:blogger.com,1999:blog-3508201418641099808.post-88968232709948897392017-06-30T16:38:02+00:00Now one month of GSoC has passed and so far everything has gone much better than I expected! According to my <a href="https://gsocinterval.blogspot.se/2017/05/timeline.html">timeline</a> this week would have been the first of two were I work on vectorization. Instead I have already mostly finished the vectorization and have started to work on other things. In this blog post I'll give a summary of what work I have completed and what I have left to do. I'll structure it according to where the functions are listed in the $INDEX$-file [1]. The number after the heading is the number of functions in that category.<br /><br />Since this will mainly be a list of which files have been modified and which are left to do this might not be very interesting if you are not familiar with the structure of the interval package.<br /><h3>Interval constant (3)</h3>All of these have been modified to support N-dimensional arrays.<br /><h3>Interval constructor (5)</h3>All of these have been modified to support N-dimensional arrays.<br /><h3>Interval function (most with tightest accuracy) (63)</h3>Almost all of these functions worked out of the box! At least after the API functions to the MPFR and crlibm libraries were fixed, they are further down in the list.<br /><br />The only function that did not work immediately were $linspace$. Even though this function could be generalized to N-dimensinal arrays the standard Octave function only works for matrices (I think the Matlab version only allows scalars). This means that adding support for N-dimensional vectors for the interval version is not a priority. I might do it later on but it is not necessary. <br /><h3>Interval matrix operation (16)</h3>Most of the matrix functions does not make sense for N-dimensional arrays. For example matrix multiplication and matrix inversion only makes sense for matrices. However all of the reduction functions are also here, they include $dot$, $prod$, $sum$, $sumabs$ and $sumsq$.<br /><br />At the moment I have implemented support for N-dimensional arrays for $sum$, $sumabs$ and $prod$. The functions $dot$ and $sumsq$ are not ready, I'm waiting to see what happens with bug #51333 [2] before I continue with that work. Depending on the bug I might also have to modify the behaviour of $sum$, $sumabs$ and $prod$ slightly.<br /><h3>Interval comparison (19)</h3>All of these have been modified to support N-dimensional arrays.<br /><h3>Set operation (7)</h3>All of these functions have been modified to support N-dimensional arrays except one, $mince$. The function $mince$ is an interval version of $linspace$ and reasoning here is the same as that for $linspace$ above.<br /><h3>Interval reverse operation (12)</h3>Like the interval functions above, all of the functions worked out of the box!<br /><h3>Interval numeric function (11)</h3>Also these functions worked out of the box, with some small modifications to the documentation for some of them.<br /><h3>Interval input and output (9)</h3>Here there are some functions which require some comments, the ones I do not comment about have all gotten support for N-dimensional arrays.<br /><br />$interval\_bitpack$<br />I think that this function does not make sense to generalize to N-dimensions. It could perhaps take an N-dimensional arrays as input, but it will always return a row vector. I have left it as it is for now at least.<br /><br />$disp$ and $display$<br />These are functions that might be subject to change later on. At the moment it prints N-dimensional arrays of intervals in the same way Octave does for normal arrays. It's however not clear how to handle the $\subset$ symbol and we might decide to change it.<br /><h3>Interval solver or optimizer (5)</h3>The functions $gauss$ and $polyval$ are not generalizable to N-dimensional vectors. I don't think that $fzero$ can be generalized either, for it to work the functions must be real-valued.<br /><br />The function $fsolve$ can perhaps be modified to support N-dimensional vectors. It uses the SIVIA algorithm [3] and I have to dive deeper into how it works to see if it can be done.<br /><br />For $fminsearch$ nothing needed to be done, it worked for N-dimensional arrays directly. <br /><h3>Interval contractor arithmetic (2)</h3>Both of these functions are used together with $fsolve$ so they also depend on if SIVIA can be generalized or not.<br /><h3>Verified solver or optimizer (6)</h3>All of these functions work on matrices and cannot be generalized.<br /><h3>Utility function (29)</h3>All of these for which it made sense have been modified to support N-dimensional arrays. Some of them only works for matrices, these are $ctranspose$, $diag$, $transpose$, $tril$ and $triu$. I have left them as they were, though I fixed a bug in $diag$.<br /><h3>API function to the MPFR and crlibm libraries (8)</h3>These are the functions that in general required most work. The ones I have added full support for N-dimensional arrays in are $crlibm\_function$, $mpfr\_function\_d$ and $mpfr\_vector\_sum\_d$. Some of them cannot be generalized, these are $mpfr\_matrix\_mul_d$, $mpfr\_matrix\_sqr\_d$ and $mpfr\_to\_string\_d$. The functions $mpfr\_linspace\_d$ and $mpfr\_vector\_dot\_d$ are related to what I mentioned above for $linspace$ and $dot$.<br /><h3>Summary</h3>So summing up the functions that still require some work are<br /><ul><li>Functions related to $fsolve$</li><li>The functions $dot$ and $sumsq$</li><li>The functions $linspace$ and $mince$</li></ul>Especially the functions related to $fsolve$ might take some time to handle. My goal is to dive deeper into this next week.<br /><br />Apart from this there are also some more things that needs to be considered. The documentation for the package will need to be updated. This includes adding some examples which make use of the new functionality.<br /><br />The interval package also did not follow the coding style for Octave. All the functions which I have made changes to have been updated with the correct coding style, but many of the functions that worked out of the box still use the old style. It might be that we want to unify the coding standard for all files before the next release. <br /><br />[1] The $INDEX$ file <a href="https://sourceforge.net/u/urathai/octave/ci/default/tree/INDEX">https://sourceforge.net/u/urathai/octave/ci/default/tree/INDEX</a><br />[2] Bug #51333 <a href="https://savannah.gnu.org/bugs/index.php?51333">https://savannah.gnu.org/bugs/index.php?51333</a><br />[3] The SIVIA algorithm <a href="https://www.youtube.com/watch?v=kxYh2cXHdNQ">https://www.youtube.com/watch?v=kxYh2cXHdNQ</a>Joel Dahnenoreply@blogger.comhttps://gsocinterval.blogspot.com/End of the first work periodtag:blogger.com,1999:blog-3202743535685562583.post-81741917703560258972017-06-30T09:32:16+00:00Hi all,<br /><br />this is the end of this first period of GSoC! It was a challenging but very interesting period and I am very excited about the next two months. It is the first time where I have the opportunity to make something that has a real value, albeit small, on someone else's work. Even when I have to do small tasks, like structure the package or learn Tensorflow APIs, I do it with enthusiasm because I have very clear in mind the ultimate goal and the value that my efforts would bring. It may seem trivial, but for a student this is not the daily bread :) I really have fun coding for this project and I hope this will last until the end!<br /><br />Speaking about the project, I've spent some time wondering which was the best solution to test the correct installation of the Tensorflow Python APIs on the machine. The last solution was putting the test in a function __nnet_init__ and calling it in the PKG_ADD (code in <i>inst/__nnet_init__ </i>in my repo [1]).<br /><br />Regarding the code, in this last days I tried to connect the dots, calling a Tensorflow network from Octave in a "Matlab compatible" way. In particular, I use the classes that I made two weeks ago in order to implement a basic version of trainNetwork, that is the core function of this package. As I explained in my post of June 12, trainNetwork takes as input the data and two objects: the layers and the options. I had some some difficulty during the implementation of the Layer class due to the inheritance and the overloading. Eventually, I decided to store the layers in a cell array as attribute of the Layer class. Overloading the subsref, I let the user call a specific layer with the '()' access, like a classic array. With this kind of overloading I managed to solve the main problem of this structure, that is the possibility to get a property of a layer doing for example <span>layers(1).Name</span><br /><br /><span>classdef Layer < handle</span><br /><span> properties (Access = private)</span><br /><span> layers = {};</span><br /><span> endproperties</span><br /><span><br /></span><span> methods (Hidden, Access = {?Layers})</span><br /><span> function this = Layer (varargin)</span><br /><span> nargin = numel(varargin);</span><br /><span> this.layers = cell(1, nargin);</span><br /><span> for i = 1:nargin</span><br /><span> this.layers{i} = varargin{i};</span><br /><span> end</span><br /><span> endfunction</span><br /><span> endmethods</span><br /><span><br /></span><span> methods (Hidden)</span><br /><span> function obj = subsref(this, idx)</span><br /><span> switch idx(1).type</span><br /><span> case '()'</span><br /><span> idx(1).type = '{}';</span><br /><span> obj = builtin('subsref',this.layers,idx);</span><br /><span> case '{}'</span><br /><span> error('{} indexing not supported');</span><br /><span> case '.'</span><br /><span> obj = builtin('subsref',this,idx);</span><br /><span> endswitch</span><br /><span> endfunction</span><br /><span><br /></span><span> function obj = numel(this)</span><br /><span> obj = builtin('numel',this.layers);</span><br /><span> endfunction</span><br /><span><br /></span><span> function obj = size(this)</span><br /><span> obj = builtin('size',this.layers);</span><br /><span> endfunction</span><br /><div><span>endmethods</span></div><div><div><span>endclassdef</span></div></div><div><br /></div><div><br /></div><div>Therefore, I implemented the same example of my last post in a proper way. In <i>tests/script </i>you can find the function <i>cnn_linear_model</i> which consists simply in:</div><div><br /></div>1. Loading the datasets<br /><span> load('tests/examples/cnn_linear_model/train_70.mat')<br /> load('tests/examples/cnn_linear_model/test_70.mat')</span><br /><br /><div>2. Defining layers and options<br /><span> layers = [ ...<br /> imageInputLayer([28 28 1])<br /> convolution2dLayer(12,25)<br /> reluLayer<br /> fullyConnectedLayer(1)<br /> regressionLayer];<br /> options = trainingOptions('sgdm', 'MaxEpochs', 1);</span><br /><br />3. Training<br /><span>net = trainNetwork(trainImages, trainAngles, layers, options);</span><br />4. Prediction <br /><span>acc = net.predict(testImages, testAngles) </span><br /><div><span><br /></span><div><i>TrainNetwork</i> is a draft and I have not yet implemented the classe <i>seriesNetwork</i>, but I think it's a good start :) In next weeks I will focus on the Tensorflow backend of the above mentioned functions, with the goal of having a working version at the end of the second period!</div><div><br /></div><div>Peace,</div><div>Enrico</div><div><br /></div><div>[1] https://bitbucket.org/cittiberto/octave-nnet/src</div></div></div>Enrico Bertinonoreply@blogger.comhttps://gsocnnet.blogspot.com/Package structuretag:blogger.com,1999:blog-3202743535685562583.post-57143538901010072032017-06-24T20:55:31+00:00Hello! During the first period of GSoC I have worked mostly on analyzing the Matlab structure of the net package in order to guarantee the compatibility throughout the whole project. The focus of the project is on the convolutional neural networks, about which I will write the next post.<br /><br />Regarding the package structure, the core will be composed by three parts: <br /><br /><ol><li><b>Layers</b>:<b> </b>there are 11 types of layers<b> </b>that I defined as Octave classes, using <i>classdef</i>. These layers can be concatenated in order to create a Layer object defining the architecture of the network. This will be the input for the training function. </li><li><b>Training</b>: the core of the project is the training function, which takes as input the data, the layers and some options and returns the network as output. </li><li><b>Network</b>:<b> </b>the network object has three methods (activations, classify and predict) that let the user compute the final classification and prediction. </li></ol><div><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="http://1.bp.blogspot.com/-ORu9UBCTgds/WT6aJVrPqMI/AAAAAAAAAYA/zv7BCHiKyFU9Z3qA_BtkjsInxBVzi8bRACK4B/s1600/structure.png"><img border="0" height="400" src="https://1.bp.blogspot.com/-ORu9UBCTgds/WT6aJVrPqMI/AAAAAAAAAYA/zv7BCHiKyFU9Z3qA_BtkjsInxBVzi8bRACK4B/s400/structure.png" width="380" /></a></td></tr><tr><td class="tr-caption">Figure 1: conv nnet flowchart </td></tr></tbody></table><div><br /></div><div><br /></div><div>I have already implemented a draft for the first point, the layers classes [1]. Every layer type inherits some attributes and methods from the parent class <i>Layers</i>. This is useful for creating the <i>Layer</i> object: the concatenation of different layers is always a Layer object that will be used as input for the training function. For this purpose, I overloaded the cat, horzcat and vertcat operators for <i>Layers</i> and subsref for <i>Layer</i>. I need to finalize some details for the disp methods of these classes.</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="http://1.bp.blogspot.com/-NWlLJjVz9ZM/WT8E2gwlp9I/AAAAAAAAAYo/3dGVBOhyCHEsxChBkz_A-VafTHcPIt72gCK4B/s1600/Schermata%2B2017-06-12%2Balle%2B23.16.39.png"><img border="0" height="396" src="https://1.bp.blogspot.com/-NWlLJjVz9ZM/WT8E2gwlp9I/AAAAAAAAAYo/3dGVBOhyCHEsxChBkz_A-VafTHcPIt72gCK4B/s640/Schermata%2B2017-06-12%2Balle%2B23.16.39.png" width="640" /></a></td></tr><tr><td class="tr-caption"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td class="tr-caption">Figure 2: Layers classes definitions </td></tr></tbody></table></td></tr></tbody></table><i><br />InputParser</i> is used in every class for the parameter management and the attributes setting.</div><div><br /></div><div>The objects of these classes can be instantiated with a corresponding function, implemented in the directory <i>inst/</i>. Here an example for creating a Layer object </div><div><br /></div><div><span><br /></span></div><span>> # TEST LAYERS<br />> a = imageInputLayer([2,2,3]); # first layer<br />> b = convolution2dLayer(1,1); # second layer<br />> c = dropoutLayer(1); # third layer<br />> layers = [a b c]; # Layer object from layers concat <br />> drop = layers(3); # Layer element access<br />> drop.Probability # Access layer attribute<br />ans = 0.50000</span><br /><div><br /><div>All functions can be tested with the <i>make check</i> of the package.<br /><br /><br />The next step is a focus on the Tensorflow integration, with Pytave, writing a complete test for a regression of images angles and comparing the precision and the computational time with Matlab.<br /><br />[1] <a href="https://bitbucket.org/cittiberto/octave-nnet/src/35e4df2a6f887582216fc266fc75976a816f04fc/inst/classes/?at=default">https://bitbucket.org/cittiberto/octave-nnet/src/35e4df2a6f887582216fc266fc75976a816f04fc/inst/classes/?at=default</a></div><div><br /></div><div><br /></div>p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Monaco; color: #f4f4f4; background-color: #000000; background-color: rgba(0, 0, 0, 0.95)} span.s1 {font-variant-ligatures: no-common-ligatures} p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Monaco; color: #f4f4f4; background-color: #000000; background-color: rgba(0, 0, 0, 0.95)} span.s1 {font-variant-ligatures: no-common-ligatures} </div>Enrico Bertinonoreply@blogger.comhttps://gsocnnet.blogspot.com/Train a Convolutional Neural Network for Regressiontag:blogger.com,1999:blog-3202743535685562583.post-71344106571759305752017-06-24T14:36:53+00:00Hello,<br /><br />I spent the last period working mostly on Tensorflow, studying the APIs and writing some examples in order to explore the possible implementations of neural networks. For this goal, I chose an interesting example proposed in the Matlab examples at [1]. The dataset is composed by 5000 images, rotated by an angle α, and a corresponding integer label (the rotation angle α). The goal is to make a regression to predict the angle of a rotated image and straighten it up.<br />All files can be found in <i>tests/examples/cnn_linear_model</i> in my repo [2].<br /><div><br /></div>I have kept the structure as in the Matlab example, but I generated a new dataset starting from LeCun's MNIST digits (datasets at [3]). Each image was rotated by a random angle between 0° and 70°, in order to keep the right orientation of the digits (code in <i>dataset_generation.m</i>). In Fig. 1 some rotated digits with the corresponding original digits.<br /><div class="separator"><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="https://4.bp.blogspot.com/-13SixYY4WOw/WU13nxmpXrI/AAAAAAAAAac/LaomtxB_lFAaD5MjxbIHDshqJFRy60ePgCEwYBhgL/s1600/test.png"><img border="0" height="301" src="https://4.bp.blogspot.com/-13SixYY4WOw/WU13nxmpXrI/AAAAAAAAAac/LaomtxB_lFAaD5MjxbIHDshqJFRy60ePgCEwYBhgL/s320/test.png" width="320" /></a></td></tr><tr><td class="tr-caption"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td class="tr-caption">Figure 1. rotated images in columns 1,3,5 and originals in columns 2,4,6</td></tr></tbody></table></td></tr></tbody></table><div><br />The implemented linear model is:</div><div>$ \hat{Y} = \omega X + b $,</div><div>where the weights $\omega$ and the bias $b$ will be optimized during the training minimizing a loss function. As loss function, I used the mean square error (MSE):</div><div><div>$ \dfrac{1}{n} \sum_{i=1}^n (\hat{Y_i} - Y_i)^2 $,</div><div>where the $Y_i$ are the training labels. </div></div><div><br /></div><div>In order to show the effective improvement given by a Neural Network, I started to make a simple regression feeding the X variable of the model directly with the 28x28 images. Even if for the MSE minimization a close form exists, I implemented an iterative method for discovering some Tensorflow features (code in <i>regression.py</i>). For evaluate the accuracy of the regression, I consider a correct regression if the difference between angles is less than 20°. After 20 epochs, the convergence was almost reached, giving an accuracy of $0.6146$.</div><div><br /><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="https://2.bp.blogspot.com/-knkDf4WvOP0/WU13zm1aBnI/AAAAAAAAAag/tr95xOU3ETsb2kxOCOMQehx77o1JcWFtgCLcBGAs/s1600/regr.png"><img border="0" height="310" src="https://2.bp.blogspot.com/-knkDf4WvOP0/WU13zm1aBnI/AAAAAAAAAag/tr95xOU3ETsb2kxOCOMQehx77o1JcWFtgCLcBGAs/s320/regr.png" width="320" /></a></td></tr><tr><td class="tr-caption">Figure 2. rotated images in columns 1,3,5 and after the regression in columns 2,4,6</td></tr></tbody></table><br />I want to analyze now the improvement given by a feature extraction performed with a convolutional neural network (CNN). As in the Matlab example, I used a basic CNN since the input images are quite simple (only numbers with monochromatic background) and consequently the features to extract are few.</div><div></div><div><ul><li>INPUT [28x28x1] will hold the raw pixel values of the image, in this case an image of width 28, height 28</li><li>CONV layer will compute the output of neurons that are connected to local regions in the input, each computing a dot product between their weights and a small region they are connected to in the input volume. This results in volume such as [12x12x25]: 25 filters of size 12x12</li><li>RELU layer will apply an element-wise activation function, such as the $max(0,x)$ thresholding at zero. This leaves the size of the volume unchanged ([12x12x25]).</li><li>FC (i.e. fully-connected) layer will compute the class scores, resulting in volume of size [1x1x1], which corresponds to the rotation angle. As with ordinary Neural Networks, each neuron in this layer will be connected to all the numbers in the previous volume.</li></ul></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="https://3.bp.blogspot.com/-d_-ilTzooso/WUrVnkRO9JI/AAAAAAAAAZ0/4-K68HW0imkQ_W-olPIKr9FKoi4zRBGgACLcBGAs/s1600/regression_scheme.png"><img border="0" height="320" src="https://3.bp.blogspot.com/-d_-ilTzooso/WUrVnkRO9JI/AAAAAAAAAZ0/4-K68HW0imkQ_W-olPIKr9FKoi4zRBGgACLcBGAs/s640/regression_scheme.png" width="640" /></a></td></tr><tr><td class="tr-caption">Figure 3. CNN linear model architecture</td></tr></tbody></table><div><br />We can visualize the architecture with Tensorboard where the graph of the model is represented.<br /><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="https://4.bp.blogspot.com/-H6ZcTGQpaP4/WU2JQX24gXI/AAAAAAAAAbA/ZWEh2_d4gxoO4-MWaV3Pflk67nBxhdrzACLcBGAs/s1600/tensorboard.png"><img border="0" height="510" src="https://4.bp.blogspot.com/-H6ZcTGQpaP4/WU2JQX24gXI/AAAAAAAAAbA/ZWEh2_d4gxoO4-MWaV3Pflk67nBxhdrzACLcBGAs/s640/tensorboard.png" width="640" /></a></td></tr><tr><td class="tr-caption">Figure 4. Model graph generated with Tensorboard</td></tr></tbody></table><br /></div><div>With the implementation in <i>regression_w_CNN.py</i>, the results are quite satisfying: after 15 epochs, it reached an accuracy of $0.75$ (205 seconds overall). One can see in Fig. 4 the marked improvement of the regression.</div><div><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td><a href="https://4.bp.blogspot.com/-MylUgRZvGQM/WU13_Rsm-VI/AAAAAAAAAak/jo6aUeXJ1ik3dYgpVvjn6E3iq0TdxmsxQCLcBGAs/s1600/conv.png"><img border="0" height="298" src="https://4.bp.blogspot.com/-MylUgRZvGQM/WU13_Rsm-VI/AAAAAAAAAak/jo6aUeXJ1ik3dYgpVvjn6E3iq0TdxmsxQCLcBGAs/s320/conv.png" width="320" /></a></td></tr><tr><td class="tr-caption"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container"><tbody><tr><td class="tr-caption">Figure 5. <span>rotated images in columns 1,3,5 and after the CNN regression in columns 2,4,6</span><br /><div><span><br /></span></div></td></tr></tbody></table></td></tr></tbody></table>With the same parameters, Matlab reached an accuracy of $0.76$ in 370 seconds (code in <i>regression_Matlab_nnet.m</i>), so the performances are quite promising<br /><br />In the next post (in few days), I will integrate the work done up to now, calling the Python class within Octave and making a function that simulates the behavior of Matlab. Leveraging the layers classes that I made 2 weeks ago, I will implement a draft of the functions <i>trainNetwork</i> and <i>predict</i> making the Matlab script callable also in Octave.<br /><br />I will also care about the dependencies of the package: I will add the dependency from Pytave in the package description and write a test as PKG_ADD in order to verify the version of Tensorflow during the installation of the package. <br /><br />Peace,<br />Enrico</div><div><br />[1] <a href="https://it.mathworks.com/help/nnet/examples/train-a-convolutional-neural-network-for-regression.html" target="_blank">https://it.mathworks.com/help/nnet/examples/train-a-convolutional-neural-network-for-regression.html</a><br />[2] <a href="https://bitbucket.org/cittiberto/octave-nnet/src/35e4df2a6f887582216fc266fc75976a816f04fc/tests/examples/cnn_linear_model/?at=default" target="_blank">https://bitbucket.org/cittiberto/octave-nnet/src/35e4df2a6f887582216fc266fc75976a816f04fc/tests/examples/cnn_linear_model/?at=default</a></div>[3] <a href="http://yann.lecun.com/exdb/mnist/" target="_blank">http://yann.lecun.com/exdb/mnist/</a><br /><br />Enrico Bertinonoreply@blogger.comhttps://gsocnnet.blogspot.com/Vectorization and broadcastingtag:blogger.com,1999:blog-3508201418641099808.post-30092066601123350102017-06-22T17:12:44+00:00At the moment I'm actually ahead of my <a href="https://gsocinterval.blogspot.se/2017/05/timeline.html">schedule</a> and this week I started to work on support for vectorization on N-dimensional arrays. The by far biggest challenge was to implement proper broadcasting and most of this post will be devoted to going through that. At the end I also mention some of the other things I have done during the week.<br /><br /><h2>Broadcasting arrays</h2>At the moment I have implement support for broadcasting on all binary functions. Since all binary functions behave similarly in respect to broadcasting I will use $+$ in all my example below, but this could in principle be any binary function working on intervals.<br /><br />When adding to arrays, $A, B$, of the same size the result is just an arrays of the same size with each entry containing the sum of the corresponding entries in $A$ and $B$. If $A$ and $B$ does not have the same size then we try to perform broadcasting. The simplest form of broadcasting is when $A$ is an arrays and $B$ is a scalar. Then we just take the value of $B$ and add to every element in $A$. For example<br /><span><br />> A = infsupdec ([1, 2; 3, 4])<br />A = 2×2 interval matrix<br /> [1]_com [2]_com<br /> [3]_com [4]_com<br />> B = infsupdec (5)<br />B = [5]_com<br />> A + B<br />ans = 2×2 interval matrix<br /> [6]_com [7]_com<br /> [8]_com [9]_com<br /></span><br />However it is not only when one of the inputs is a scalar that broadcasting can be performed. Broadcasting is performed separately for each dimension of the input. We require either that the dimensions are equal, and no broadcasting is performed, or that one of the inputs have that dimension equal to $1$, we then concatenate this input along that dimension until they are of equal size. If for example $A$ has dimension $4\times4\times4$ and $B$ dimension $4\times4\times1$ we concatenate $B$ with itself along the third dimension four times to get two arrays of the same size. Since a scalar has all dimensions equal to 1 we see that it can be broadcasted to any size. Both $A$ and $B$ can also be broadcasted at the same time, along different dimensions, for example<br /><span><br />> A = infsupdec (ones (1, 5, 2))<br />A = 1×5×2 interval array<br />ans(:,:,1) =<br /> [1]_com [1]_com [1]_com [1]_com [1]_com<br />ans(:,:,2) =<br /> [1]_com [1]_com [1]_com [1]_com [1]_com<br />> B = infsupdec ([1, 2, 3, 4, 5; 6, 7, 8, 9, 10])<br />B = 2×5 interval matrix<br /> [1]_com [2]_com [3]_com [4]_com [5]_com<br /> [6]_com [7]_com [8]_com [9]_com [10]_com<br />> A + B<br />ans = 2×5×2 interval array<br />ans(:,:,1) =<br /> [2]_com [3]_com [4]_com [5]_com [6]_com<br /> [7]_com [8]_com [9]_com [10]_com [11]_com<br />ans(:,:,2) =<br /> [2]_com [3]_com [4]_com [5]_com [6]_com<br /> [7]_com [8]_com [9]_com [10]_com [11]_com<br /></span><br /><h3>The implementation</h3>I'll go through a little bit about my implementation. I warn you that I'm not that familiar with the internals of Octave so some things I say might be wrong, or at least not totally correct.<br /><br />Internally all, numerical, arrays are stored as a linear vector and the dimensions are only metadata. This means that the most efficient way to walk through an array is with a linearly increasing index. When $A$ and $B$ have the same size the most efficient way to sum them is to linearly go through the arrays. In pseudo code<br /><span><br />// Calculate C = A + B<br />for (int i = 0; i < numel (A); i++) {<br /> C(i) = A(i) + B(i);<br />}<br /></span><br />This works fine, and apart from unrolling the loop or doing optimizations like that it is probably the most efficient way to do it.<br /><br />If $A$ and $B$ are not of the same size then one way to do it would be to simply extend $A$ or/and $B$ along the needed dimensions. This would however require coping a lot of data, something we want to avoid (memory access is expensive). Instead we try to be smart with our indexing to access the right data from both $A$ and $B$.<br /><br />After asking on the IRC-channel I got pointed to <a href="http://hg.savannah.gnu.org/hgweb/octave/file/be69ea3de7a3/liboctave/numeric/bsxfun-defs.cc#l37">this</a> Octave function which performs broadcasting. My implementation, which can be found <a href="https://sourceforge.net/u/urathai/octave/ci/default/tree/src/mpfr_function_d.cc#l63">here</a>, is heavily inspired by that function.<br /><h3>Performance</h3>Here I compare the performance of the new implementation with the old one. Since the old one could only handle matrices we are limited by that. We can measure the time it takes to add two matrices $A$, $B$ with the code<br /><span><br />tic; A + B; toc;<br /></span><br />We do 10 runs for each test and all times are in seconds. <br /><h4>Addition of large matrices</h4>Case 1: A = B = infsupdec (ones (1000, 1000));<br /> Old New<br /> 0.324722 0.277179<br /> 0.320914 0.276116<br /> 0.322018 0.276075<br /> 0.318713 0.279258<br /> 0.332041 0.279593<br /> 0.318429 0.279987<br /> 0.323752 0.279089<br /> 0.317823 0.276036<br /> 0.320509 0.280964<br /> 0.320610 0.281123<br />Mean: 0.32195 0.27854<br />Case 2: A = B = infsupdec (ones (10, 100000));<br /> Old New<br /> 0.299321 0.272691<br /> 0.297020 0.282591<br /> 0.296460 0.274298<br /> 0.294541 0.279661<br /> 0.298306 0.277274<br /> 0.301532 0.275531<br /> 0.298163 0.278576<br /> 0.298954 0.279868<br /> 0.302849 0.275991<br /> 0.297765 0.278806<br />Mean: 0.29849 0.27753<br /><br />Case 3: A = B = infsupdec (ones (100000, 10));<br /> Old New<br /> 0.286433 0.279107<br /> 0.289503 0.278251<br /> 0.297562 0.279579<br /> 0.292759 0.283311<br /> 0.292983 0.281306<br /> 0.290947 0.282310<br /> 0.293025 0.286172<br /> 0.294153 0.278886<br /> 0.293457 0.278625<br /> 0.296661 0.280804<br />Mean: 0.29275 0.28084 <br /><h4>Broadcasting scalars</h4>Case 4: A = infsupdec (ones (1000, 1000));<br /> B = infsupdec (1);<br /> Old New<br /> 0.298695 0.292419<br /> 0.298158 0.292274<br /> 0.305242 0.296036<br /> 0.295867 0.291311<br /> 0.296971 0.297255<br /> 0.304297 0.292871<br /> 0.298172 0.300329<br /> 0.297251 0.291668<br /> 0.299236 0.294128<br /> 0.300457 0.298005<br />Mean; 0.29943 0.29463 <br /><br />Case 5: A = infsupdec (1);<br /> B = infsupdec (ones (1000, 1000));<br /> Old New<br /> 0.317276 0.291100<br /> 0.316858 0.296519<br /> 0.316617 0.292958<br /> 0.316159 0.299662<br /> 0.317939 0.301558<br /> 0.322162 0.295338<br /> 0.321277 0.293561<br /> 0.314640 0.291500<br /> 0.317211 0.295487<br /> 0.317177 0.294376<br />Mean: 0.31773 0.29521<br /><h4>Broadcasting vectors</h4>Case 6: A = infsupdec (ones (1000, 1000));<br /> B = infsupdec (ones (1000, 1));<br /> Old New<br /> 0.299546 0.284229<br /> 0.301177 0.284458<br /> 0.300725 0.276269<br /> 0.299368 0.276957<br /> 0.303953 0.278034<br /> 0.300894 0.275058<br /> 0.301776 0.276692<br /> 0.302462 0.282946<br /> 0.304010 0.275573<br /> 0.301196 0.273109<br />Mean: 0.30151 0.27833 <br /><br />Case 7: A = infsupdec (ones (1000, 1000));<br /> B = infsupdec (ones (1, 1000)); <br /> Old New<br /> 0.300554 0.295892<br /> 0.301361 0.294287<br /> 0.302575 0.299116<br /> 0.304808 0.294184<br /> 0.306700 0.291606<br /> 0.301233 0.298059<br /> 0.301591 0.292777<br /> 0.302998 0.290288<br /> 0.300452 0.291975<br /> 0.305531 0.290178<br />Mean: 0.30278 0.29384<br /><br />We see that in all cases the new version is faster or at least equally fast as the old version. In the old version the order of the input made a slight difference in performance (case 4 vs case 5). In the new version both inputs are treated in exactly the same way so we no longer see that difference.<br /><h3>Possible improvements</h3>In theory the cases when we broadcast a scalar could be the fastest ones. If $B$ is a scalar we could, in pseudo code, do something similar to<br /><span>// Calculate C = A + B with B scalar<br />for (int i = 0; i < numel (A); i++) {<br /> C(i) = A(i) + B;<br />} </span><br />This is however not implemented at the moment. Instead we use the ordinary routine to calculate the index for $B$ (since it is a scalar it will always evaluate to $1$). If we would like to optimize more for this case we could add a check for if $A$ or $B$ are scalars and then optimize for that. Of course this would also make the code more complicated, something to watch out for. At the moment I leave it like this but if we later want to optimize for that case it could be done.<br /><h2>Other work</h2>Apart from the work to fix the broadcasting for binary functions there were very little to do for many of the functions. All binary functions that use this code, and all unary functions using an even simpler code, worked directly after fixing the oct-files. Some of them required small changes to the documentation but other than that the octave-scripts were fine. So mainly it has been a matter of actually going through all files and check that they actually did work.<br /><h3>Bug #51283</h3>When going through all the functions I noticed a bug in the interval version of $\sin$,<br /><span><br /> > sin (infsupdec (0))<br />ans = [0]_com<br />> sin (infsupdec ([0, 0]))<br />ans = 1×2 interval vector<br /> [0, -0]_com [0, -0]_com<br /></span><br />The second version here is wrong, $-0$ should never be allowed as a value for the supremum of an interval. I was able to track this down to how Octaves $\max$ function works, see <a href="https://savannah.gnu.org/bugs/index.php?51283">bug #51283</a>. As Oliver writes there the exact behaviour of the $\max$-function is not specified in <span id="hidsubpartcontentdiscussion">IEEE Std 754-2008 so we cannot rely on that. To solve this I have added a line to manually set all $-0$ to $+0$ in the supremum of the interval.</span><br /><h3> </h3>Joel Dahnenoreply@blogger.comhttps://gsocinterval.blogspot.com/Timetable: modificationtag:blogger.com,1999:blog-8509760576772091576.post-70864628587510616652017-06-20T07:01:37+00:00Timetable: modification <h1>Timetable: modification</h1>According to my timetable (that you can find <a href="http://gsocspecfun.blogspot.it/2017/05/mathjax.html">here</a>), during this last week of June, I should've work on <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=34405">the input validation of betainc</a>. Since a <a href="https://savannah.gnu.org/bugs/?func=detailitem&item_id=51157">new bug</a> related to this function has been found and, moreover, the actual implementation doesn't accept the "lower" or "upper" tail (as MATLAB do), me and my mentor decided to use this week to start studying how to rewrite betainc (main references will be [1] and [2]) and to use the last part fo the GSoC to actually implement it. In this way, my timetable remain almost identical (I will use July to work on Bessel functions) and I will be able to fix also this problem. <br /><br />[1] Abramowitz, Stegun "Handbook of Mathematical Functions"<br />[2] Cuyt, Brevik Petersen, Vendonk, Waadeland "Handbook of Continued Fractions for Special Functions"Michele Ginesinoreply@blogger.comhttp://gsocspecfun.blogspot.com/