<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Blog posts on Tamás K. Papp&#39;s website</title>
  <link href="https://tamaspapp.eu/index.xml" rel="self"/>
  <link href="https://tamaspapp.eu/post/"/>
  <updated>2017-06-11T14:48:06+02:00</updated>
  
  <id>https://tamaspapp.eu/post/</id>
  <author>
    <name>Tamás K. Papp</name>
  </author>
  <generator>Hugo -- gohugo.io</generator>
  
  <entry>
    <title type="html">Julia and batteries</title>
    <link href="https://tamaspapp.eu/post/2019-12-21-julia-batteries/"/>
    <id>https://tamaspapp.eu/post/2019-12-21-julia-batteries/</id>
    <published>2019-12-21T16:33:38+01:00</published>
    <updated>2019-12-21T16:33:38+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/2019-12-21-julia-batteries/">&lt;p&gt;New Julia users frequently suggest that some features should be included in &lt;code&gt;Base&lt;/code&gt; (the part that is available directly without &lt;code&gt;using&lt;/code&gt; any packages) or the standard libraries. The colloquial phrase is that &lt;em&gt;“Julia should come with batteries included”&lt;/em&gt;, hence the title of this post.&lt;/p&gt;
&lt;p&gt;In this blog post, I explain why doing this is unlikely to improve anything, likely to make some things &lt;em&gt;worse&lt;/em&gt;, and thus often meets with resistance from developers. Most of these points are well-known, and repeated in various discussions. I thought it would be nice to have them in one place.&lt;/p&gt;
&lt;h1 id=&#34;about-the-standard-libraries&#34;&gt;About the standard libraries&lt;/h1&gt;
&lt;p&gt;Before the 0.7/1.0 release of Julia, a lot of functionality now in the standard libraries was part of &lt;code&gt;Base&lt;/code&gt;. As the codebase grew, this was causing practical problems, so modularizing the code was on the agenda from &lt;a href=&#34;https://github.com/JuliaLang/julia/issues/5155&#34;&gt;the very beginning&lt;/a&gt;, with the understanding that this would make things load faster, encapsulate implementation details better, and the code would be easier to maintain. The &lt;a href=&#34;https://github.com/JuliaLang/julia/issues?utf8=%E2%9C%93&amp;amp;q=label%3Aexcision+&#34;&gt;excision&lt;/a&gt; was completed for 0.7, and “standard libraries” as we know them now were born.&lt;/p&gt;
&lt;p&gt;One very neat thing about Julia is that conceptually, &lt;em&gt;standard libraries are like any other package&lt;/em&gt;. There is no “secret sauce” that makes them special: some things like precompilation are enabled by default, but you can do the same for any package.&lt;/p&gt;
&lt;p&gt;What &lt;em&gt;is&lt;/em&gt; different about standard libraries is an &lt;a href=&#34;https://github.com/JuliaLang/julia/issues/27197&#34;&gt;implicit guarantee&lt;/a&gt; for code quality and support: they are officially endorsed, and the Julia maintainers fix issues relating to these packages.&lt;/p&gt;
&lt;p&gt;When users suggest that other packages they find useful are included in the standard libraries, they usually expect that the same kind of code quality and support guarantees would extend &lt;em&gt;automatically&lt;/em&gt; to these packages.&lt;/p&gt;
&lt;p&gt;Unfortunately, since developer time is a scarce resource, this would only mean that &lt;em&gt;the same number of people would now have to maintain more code&lt;/em&gt;. This would most likely result in longer delays for releases, and is not necessarily a guarantee of better support: some standard libraries have (minor) issues that have been outstanding for a long time.&lt;/p&gt;
&lt;h1 id=&#34;the-benefits-of-third-party-packages&#34;&gt;The benefits of (third party) packages&lt;/h1&gt;
&lt;p&gt;Below, I list some major advantages of having code in third party packages (what we normally think of as “packages”, usually registered) that are maintained outside the Julia repository.&lt;/p&gt;
&lt;h2 id=&#34;separate-versioning-more-frequent-releases&#34;&gt;Separate versioning, more frequent releases&lt;/h2&gt;
&lt;p&gt;Standard libraries, not being versioned separately, maintain the same &lt;a href=&#34;https://semver.org/&#34;&gt;SemVer&lt;/a&gt; compatibility guarantees as the rest of Julia. This means that no incompatible changes are allowed without changing the major version &amp;mdash; in other words, anything that ends up there would have to be supported &lt;em&gt;without breaking changes&lt;/em&gt; for the rest of the 1.x life cycle.&lt;/p&gt;
&lt;p&gt;Since nontrivial interfaces usually require a few iterations to become polished, this would mean that the authors would need to get it right without a lot of community testing, or keep legacy methods around for the rest of 1.x.&lt;/p&gt;
&lt;p&gt;Third party packages have their own version. This means that they can release as often they like, experiment with new ways of doing things and deprecate old APIs, and add and reorganize features without the implicit cost of having to support them for a long time. Because of this, it is not uncommon for actively maintained packages to have minor releases with new features every month or so, and bugfix releases within a day.&lt;/p&gt;
&lt;h2 id=&#34;easier-contribution&#34;&gt;Easier contribution&lt;/h2&gt;
&lt;p&gt;Contributing to standard libraries is usually a more involved process than making a PR to third party packages. Unit tests take longer to run (since the whole of Julia is tested), ramifications of changes have to be considered in wider context, and contributors have to be much more cautious with experimentation since anything that ends up there would need to be supported for a long time.&lt;/p&gt;
&lt;p&gt;The changes will need to be reviewed by people who may be very busy working on some other part of Julia, and may take a longer time; decisions frequently need a wider consensus and some PRs just languish unresolved for months. This naturally raises the barrier to entry, and can be quite frustrating to contributors.&lt;/p&gt;
&lt;p&gt;In contrast, many packages have a single or a few authors, who have a clear vision of where they want to take their package, and are usually able to make decisions quicker.&lt;/p&gt;
&lt;h2 id=&#34;separate-documentation-and-issue-tracker&#34;&gt;Separate documentation and issue tracker&lt;/h2&gt;
&lt;p&gt;The Julia repository has a total of 17k issues (!), 14k of them closed, a similar number of open pull requests, and a manual that has 400 pages on the standard libraries (in PDF format). It is occasionally challenging to find an earlier issue, discussion, or documentation for something.&lt;/p&gt;
&lt;p&gt;For third party packages, having a separate issue tracker and documentation makes it much easier to find what you are looking for.&lt;/p&gt;
&lt;h1 id=&#34;development-happens-in-packages&#34;&gt;Development happens in packages&lt;/h1&gt;
&lt;p&gt;If you would like Julia to support something that is experimental or not fully specified (and most software isn&amp;rsquo;t), it is unlikely that adding it to &lt;code&gt;Base&lt;/code&gt; or the standard libraries is the right solution.&lt;/p&gt;
&lt;p&gt;Instead, it is usually recommended that you put it in a package and work out the details, improving the code based on experience and feedback. There is no downside to this in most cases, just the benefits mentioned above.&lt;/p&gt;
&lt;p&gt;If the experiment pans out, great: you have created a nice package! If it doesn&amp;rsquo;t, it can be retired and archived, without having to commit to continued support.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Comments reenabled</title>
    <link href="https://tamaspapp.eu/post/2019-10-10-comments_reenabled/"/>
    <id>https://tamaspapp.eu/post/2019-10-10-comments_reenabled/</id>
    <published>2019-10-10T17:40:39+02:00</published>
    <updated>2019-10-10T17:40:39+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/2019-10-10-comments_reenabled/">&lt;p&gt;I have re-enabled comments using &lt;a href=&#34;https://utteranc.es/&#34;&gt;utterances&lt;/a&gt;, which uses Github issues to record and render comments. You need to login via Github to comment.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">How my Julia coding style changed</title>
    <link href="https://tamaspapp.eu/post/2019-09-07-coding_style_retrospective/"/>
    <id>https://tamaspapp.eu/post/2019-09-07-coding_style_retrospective/</id>
    <published>2019-09-07T08:01:57+02:00</published>
    <updated>2019-09-07T08:01:57+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/2019-09-07-coding_style_retrospective/">&lt;p&gt;The &lt;a href=&#34;https://tamaspapp.eu/post/2019-08-29-dynamichmc2/&#34;&gt;recent redesign&lt;/a&gt; of &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl&#34;&gt;DynamicHMC.jl&lt;/a&gt; provides an opportunity to reflect on how my Julia coding style changed. I started this package two years ago, and did not do any major refactoring after it became usable, mostly because I did not have a good comprehensive test suite or a solid conceptual understanding of &lt;em&gt;all&lt;/em&gt; the ramifications of the algorithm, especially the adaptation, and I was afraid of breaking something that I just got working. Consequently, the code before the redesign largely reflected the coding style I developed for Julia 0.5 and then partly 0.6.&lt;/p&gt;

&lt;p&gt;I am one of those people who recognize the benefits of reflecting on the past from time to time, but are too &lt;del&gt;busy&lt;/del&gt; lazy to keep a diary. But code under version control is effectively a diary about the life of software, and I find it interesting to think about how my Julia coding style has changed in the past to years.&lt;/p&gt;

&lt;p&gt;It is important to emphasize that this writeup reflects how &lt;em&gt;I&lt;/em&gt; code &lt;em&gt;at the moment&lt;/em&gt;. I recognize that other coding styles in Julia can be perfectly legitimate, and when I contribute to packages, I do my best to follow existing style. Also, it is very likely that my own coding style will change as the language evolves. In this blog post, I won&#39;t address details of coding style about which there is a more or less general agreement --- see &lt;a href=&#34;https://docs.julialang.org/en/v1.4-dev/manual/style-guide/&#34;&gt;the Style Guide in the manual&lt;/a&gt; and &lt;a href=&#34;https://github.com/jrevels/YASGuide&#34;&gt;YASGuide&lt;/a&gt; for useful summaries. Finally, some examples are stylized adaptations of real code for simpler exposition.&lt;/p&gt;

&lt;h1 id=&#34;randomness&#34;&gt;Randomness&lt;/h1&gt;

&lt;p&gt;Random numbers are very important for scientific computing, but at the same time present an important challenge for writing bug-free parallel code and unit testing. A lot of code in &lt;code&gt;Random&lt;/code&gt; and &lt;code&gt;Base&lt;/code&gt; follows the interface conventions&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;rand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rng&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;making the random number generator an &lt;em&gt;optional&lt;/em&gt; first argument, and defaulting to the global one.&lt;/p&gt;

&lt;p&gt;While this can be convenient for &lt;em&gt;user code&lt;/em&gt;, in &lt;em&gt;packages&lt;/em&gt; I find that it is better to keep the random number generator as an &lt;em&gt;explicit&lt;/em&gt; argument to almost all methods. This paves the way for making the code work nicely with &lt;a href=&#34;https://julialang.org/blog/2019/07/multithreading&#34;&gt;composable multi-threading&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;If random and deterministic parts of the algorithm can be separated, it should be done, as it usually makes the code cleaner, and unit testing much easier. An example of this is factoring out the &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl/blob/20665c2010f76f8b048477491018d02a51b3b35d/src/trees.jl#L19&#34;&gt;random directions for tree doubling&lt;/a&gt; in NUTS: drawing a single set of bit flags &lt;em&gt;once&lt;/em&gt; and providing this to the tree building algorithm, the latter can treat the doubling directions as predetermined. This also made it much easier to verify detailed balance in the unit tests.&lt;/p&gt;

&lt;h1 id=&#34;named-tuples&#34;&gt;Named tuples&lt;/h1&gt;

&lt;p&gt;Named tuples are extremely useful for organizing multiple values as inputs and outputs when a composite type (&lt;code&gt;struct&lt;/code&gt;) is not warranted or needed. If a function returns multiple values, especially more than two, I now always default to using named tuples, ie&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;then use &lt;code&gt;@unpack&lt;/code&gt; from &lt;a href=&#34;https://github.com/mauro3/Parameters.jl&#34;&gt;Parameters.jl&lt;/a&gt; for destructuring:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@unpack&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# I don&amp;#39;t need c here&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is costless and makes the interfaces more flexible: for example, I can add extra fields, or eventually make the returned value a composite type later, without changing anything in the callers.&lt;/p&gt;

&lt;h1 id=&#34;multiliners-as-opposed-to-oneliners&#34;&gt;Multi-liners as opposed to one-liners&lt;/h1&gt;

&lt;p&gt;Almost all the “clever” one liners are now expunged from the code. Compare&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;EBFMI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;πs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;π&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;abs2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;πs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;πs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EBFMI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tree_statistics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;πs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;π&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tree_statistics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;abs2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;diff&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;πs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;πs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first one is kind of crammed, and difficult to read, while the second one makes it clear that an interim value is obtained for the calculation.&lt;/p&gt;

&lt;p&gt;When a function returns multiple values, I find it nice to assign each to a variable first, ie&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;h&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;as opposed to&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;h&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This makes the returned structure much more readable when I need to look at some code later.&lt;/p&gt;

&lt;p&gt;That said, I still have a strong preference for writing small functions that “do one thing”. This again is frequently an optimal strategy for Julia, as the compiler is very good about inlining decisions (and when not, can be nudged with &lt;code&gt;@inline&lt;/code&gt;).&lt;/p&gt;

&lt;h1 id=&#34;abstract-types-can-be-an-implementation-detail&#34;&gt;Abstract types can be an implementation detail&lt;/h1&gt;

&lt;p&gt;Abstract types can be very useful for organizing method dispatch: code like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;abstract type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SomeAbstractType&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SomeAbstractType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;do_something&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ThatSubType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SomeAbstractType&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ThatSubType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;do_something_else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;can help avoid repetition.&lt;/p&gt;

&lt;p&gt;But abstract types are just &lt;em&gt;one&lt;/em&gt; convenient tool for this, and building a type tree is a tool, not an end in itself. When they are no longer adequate, other solutions such as &lt;a href=&#34;https://docs.julialang.org/en/v1.4-dev/manual/methods/#Trait-based-dispatch-1&#34;&gt;traits&lt;/a&gt; should be used instead.&lt;/p&gt;

&lt;p&gt;Consequently, these days I mostly consider type hierarchies an implementation detail and I am wary of exposing them in the API of a package. This is especially important if some functionality requires that the &lt;em&gt;user&lt;/em&gt; of a package implements their own custom types, e.g. for a model. Requiring that&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;UserDefinedModel&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SomePackage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ModelType&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to work with some API is usually &lt;em&gt;unnecessary&lt;/em&gt;, and can cause unnecessary complications when the user would want &lt;code&gt;UserDefinedModel&lt;/code&gt; to implement some &lt;em&gt;other&lt;/em&gt; API. Either &lt;a href=&#34;https://en.wikipedia.org/wiki/Duck_typing&#34;&gt;duck typing&lt;/a&gt;, or an explicit interface check like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;implements_model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Any&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;implements_model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UserDefinedModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;can work better (returning types when that is necessary, eg for further dispatch — see &lt;code&gt;Base.IteratorSize&lt;/code&gt; for an example).&lt;/p&gt;

&lt;h1 id=&#34;small-type-unions&#34;&gt;Small type unions&lt;/h1&gt;

&lt;p&gt;The ability of the compiler create efficient code for &lt;a href=&#34;https://julialang.org/blog/2018/08/union-splitting&#34;&gt;small type unions&lt;/a&gt; made code organization much easier for me. For example, &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl/blob/20665c2010f76f8b048477491018d02a51b3b35d/src/trees.jl#L197&#34;&gt;&lt;code&gt;DynamicHMC.adjacent_tree&lt;/code&gt;&lt;/a&gt; attempts to build a tree next to some position, but this can fail because of divergence or turning in the leapfrog integrator, in which case it is useful to bail out early and return information about the reason. Consequently, this function either returns a tree, or an &lt;code&gt;InvalidTree&lt;/code&gt;, which is a container with the aforementioned diagnostic information. The compiler recognizes this and generates fast code.&lt;/p&gt;

&lt;p&gt;Some attention should be paid to avoid combinatoric type explosions, but when used well, small type unions can make code much simpler at little or no extra cost.&lt;/p&gt;

&lt;h1 id=&#34;functional-is-often-the-best-solution&#34;&gt;Functional is often the best solution&lt;/h1&gt;

&lt;p&gt;Preallocating containers for outputs &lt;a href=&#34;https://docs.julialang.org/en/v1.4-dev/manual/performance-tips/#Pre-allocating-outputs-1&#34;&gt;can make code faster&lt;/a&gt;, but at the cost of extra complexity, especially that of having to figure out type parameters for said containers.&lt;/p&gt;

&lt;p&gt;My general strategy is to write code in a &lt;a href=&#34;https://en.wikipedia.org/wiki/Functional_programming&#34;&gt;functional&lt;/a&gt;, side-effect-free style until I am really convinced that preallocation would help, and then confine it to carefully compartmentalized parts of the code. This is of course ideal only for &lt;em&gt;some&lt;/em&gt; kinds of code — when &lt;a href=&#34;http://www.stochasticlifestyle.com/when-do-micro-optimizations-matter-in-scientific-computing/&#34;&gt;allocations dominate&lt;/a&gt;, a functional style is not optimal.&lt;/p&gt;

&lt;p&gt;That said, Julia&#39;s compiler is getting more and more clever about optimizing allocations, so I frequently find that I never rewrite code with preallocated containers, and occasionally even revert from preallocated code to a functional style without a relevant performance cost.&lt;/p&gt;

&lt;h1 id=&#34;when-in-doubt-document&#34;&gt;When in doubt, document&lt;/h1&gt;

&lt;p&gt;Some readers of the code of &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl&#34;&gt;DynamicHMC.jl&lt;/a&gt; will have the impression that it is &lt;em&gt;overdocumented&lt;/em&gt;. Probably 20–25% of the lines in the source are docstrings, and most internal interfaces and convenience functions have one.&lt;/p&gt;

&lt;p&gt;Primarily, this is driven by instances of the embarassing realization of having written some code two years ago which kind of works, but no longer being sure of all the details that would be nice to know before refactoring. But another consideration is encouraging contributions, or uses of the packages for research — besides being an implementation of the NUTS sampler, &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl&#34;&gt;DynamicHMC.jl&lt;/a&gt; is also a platform for experimenting, which is easier to do when the internals are documented.&lt;/p&gt;

&lt;p&gt;Julia&#39;s documentation ecosystem is now very mature and robust. Besides the excellent &lt;a href=&#34;https://github.com/JuliaDocs/Documenter.jl&#34;&gt;Documenter.jl&lt;/a&gt;, I also find &lt;a href=&#34;https://github.com/JuliaDocs/DocStringExtensions.jl&#34;&gt;DocStringExtensions.jl&lt;/a&gt; very useful.&lt;/p&gt;

&lt;h1 id=&#34;internal-interfaces-have-high-return-on-investment&#34;&gt;Internal interfaces have high return on investment&lt;/h1&gt;

&lt;p&gt;Many packages, especially those that are work in progress or experimental, do not document their &lt;em&gt;user&lt;/em&gt; interfaces very carefully. This is of course understandable, but I have developed a preference for abstracting out and documenting interfaces in &lt;em&gt;internally used code&lt;/em&gt;, too, as the package matures.&lt;/p&gt;

&lt;p&gt;This makes refactoring and compartmentalization much easier, and makes sense even if a particular interface has only a &lt;em&gt;single implementation in the package&lt;/em&gt;, because unit tests can just provide a “dummy” implementation and test related code that way. An example of this is the code for &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl/blob/4c0d616ebaa4cec900d5f023376f08f204feb020/src/trees.jl&#34;&gt;“trees”&lt;/a&gt; and the &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl/blob/4c0d616ebaa4cec900d5f023376f08f204feb020/test/test-trees.jl&#34;&gt;related tests&lt;/a&gt;: trees here are an abstraction for walking &lt;em&gt;integer positions&lt;/em&gt; in two directions. This is key for the NUTS algorithm, but can be handled as an abstraction separate from the details of leapfrog integrators.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">ANN: DynamicHMC 2.0</title>
    <link href="https://tamaspapp.eu/post/2019-08-29-dynamichmc2/"/>
    <id>https://tamaspapp.eu/post/2019-08-29-dynamichmc2/</id>
    <published>2019-09-03T09:03:50+02:00</published>
    <updated>2019-09-03T09:03:50+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/2019-08-29-dynamichmc2/">&lt;p&gt;I am very pleased to announce version 2.0 of &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl&#34;&gt;DynamicHMC.jl&lt;/a&gt;. I briefly summarize the new the developments in this blog post.&lt;/p&gt;


&lt;div class=&#34;juliaversionwarning&#34;&gt;&lt;p&gt;Code used in this post was written for Julia &lt;strong&gt;v1.*&lt;/strong&gt; and, when applicable, reflects the state of packages used on &lt;strong&gt;2019-09-03&lt;/strong&gt;. You may need to modify it for different versions.&lt;/p&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: &lt;em&gt;my blog no longer has a comment section. Feel free to ask questions about this post &lt;a href=&#34;https://discourse.julialang.org/t/ann-dynamichmc-2-0/28314&#34;&gt;on the Julia Discourse forum&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&#34;some-context&#34;&gt;Some context&lt;/h1&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl&#34;&gt;DynamicHMC.jl&lt;/a&gt; is part of a collection of packages for implementing Bayesian inference using a &lt;em&gt;modular&lt;/em&gt; approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/TransformVariables.jl&#34;&gt;TransformVariables.jl&lt;/a&gt; just maps &lt;span  class=&#34;math&#34;&gt;\(\mathbb{R}^n\)&lt;/span&gt; vectors into collections of constrained parameters, like positive real numbers or valid correlation matrices,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/LogDensityProblems.jl&#34;&gt;LogDensityProblems.jl&lt;/a&gt; provides an interface for &lt;em&gt;log density functions&lt;/em&gt; &lt;span  class=&#34;math&#34;&gt;\(\mathbb{R}^n \to \mathbb{R}\)&lt;/span&gt; and their derivative, also calculating the latter using automatic differentiation via one of the supported native Julia AD frameworks (see below),&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl&#34;&gt;DynamicHMC.jl&lt;/a&gt;, which just takes a log density and its gradient on &lt;span  class=&#34;math&#34;&gt;\(\mathbb{R}^n\)&lt;/span&gt;, and performs MCMC using NUTS,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/MCMCDiagnostics.jl&#34;&gt;MCMCDiagnostics.jl&lt;/a&gt; for &lt;em&gt;generic&lt;/em&gt; convergence diagnostics (ie not specific to a particular MCMC method).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In contrast to a single interface and a DSL for describing models, these packages provide a &lt;em&gt;suite&lt;/em&gt; of tools for modern MCMC, with easily interchangable and modular building blocks. For example, the gradients of a log density can be obtained with&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/JuliaDiff/ForwardDiff.jl&#34;&gt;ForwardDiff.jl&lt;/a&gt;, which is very robust,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/JuliaDiff/ReverseDiff.jl&#34;&gt;ReverseDiff.jl&lt;/a&gt;, which works better for medium-sized problems using a classic taped approach,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/FluxML/Flux.jl&#34;&gt;Flux.jl&lt;/a&gt; which is more modern and can be faster on larger problems, and of course&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/FluxML/Zygote.jl&#34;&gt;Zygote.jl&lt;/a&gt; which is very promising, but work in progress;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;and switching between these usually just requires changing a single line. I find this especially important since as Zygote keeps maturing, it will play a more and more important role for fast AD. Moreover, the user is free to code all gradients manually, or just parts of them to help out AD, for example with the &lt;a href=&#34;https://math.mit.edu/~stevenj/18.336/adjoint.pdf&#34;&gt;adjoint method&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition to this, some packages use DynamicHMC.jl as a &lt;em&gt;backend&lt;/em&gt;. This is encouraged and remains to be supported. Finally, the third common use case for this package is as a &lt;em&gt;research platform&lt;/em&gt; for experimenting with modern HMC algorithms: this is supported by a detailed documentation of internals.&lt;/p&gt;

&lt;h1 id=&#34;why-a-new-api-was-needed&#34;&gt;Why a new API was needed&lt;/h1&gt;

&lt;p&gt;As bug reports and test cases kept accumulating, it was very clear that &lt;em&gt;better adaptation heuristics&lt;/em&gt;, and a more sophisticated &lt;em&gt;diagnosic and warmup interface&lt;/em&gt; was needed. When NUTS/HMC goes wrong with models it should be able to handle otherwise, the problem is usually with &lt;em&gt;adaptation&lt;/em&gt;. The user should be able to learn what went wrong, and either manually tune stepsize and the kinetic energy metric, or choose an adaptation better suited to the model.&lt;/p&gt;

&lt;p&gt;The old API of DynamicHMC was lacking in several ways. The main entry point was something like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tuning&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NUTS_init_tune_mcmc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;∇P&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;with &lt;code&gt;tuning&lt;/code&gt; containing the adapted stepsize and kinetic energy metric.&lt;/p&gt;

&lt;p&gt;In practice, it turns out that&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;either the model works fine&lt;/em&gt;, and then the user cares little about warmup,&lt;/li&gt;
&lt;li&gt;or it doesn&#39;t, then &lt;em&gt;information about the warmup would be necessary&lt;/em&gt; to debug the model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fine-tuning the adaptation sequence was possible, but rather unintuitive in the old API. I doubt that many people used this feature, or were even aware that it was available. Statistics on &lt;em&gt;why&lt;/em&gt; adaptation failed or sampling didn&#39;t mix were also difficult to obtain.&lt;/p&gt;

&lt;p&gt;After collecting the various problems, I spent some time on redesigning the internals, then the API to address all major issues.&lt;/p&gt;

&lt;p&gt;Here I would like to &lt;strong&gt;thank all users of this library who provided a lot of valuable feedback&lt;/strong&gt;, especially in the form of bug reports which I could study and use to tweak the sampler. Robert J Goedman coded &lt;em&gt;all&lt;/em&gt; the models of the excellent “&lt;a href=&#34;https://xcelab.net/rm/statistical-rethinking/&#34;&gt;Statistical Rethinking&lt;/a&gt;” book in  &lt;a href=&#34;https://github.com/StatisticalRethinkingJulia/DynamicHMCModels.jl&#34;&gt;DynamicHMCModels.jl&lt;/a&gt;, which is the most comprehensive collection of examples for this package, and also provides and extremely useful test suite for it. &lt;a href=&#34;https://github.com/JuliaDiffEq/DiffEqBayes.jl/&#34;&gt;DiffEqBayes.jl&lt;/a&gt; included DynamicHMC as a backend, while &lt;a href=&#34;https://github.com/cscherrer/Soss.jl&#34;&gt;Soss.jl&lt;/a&gt; provides a higher-level DSL for building models. Users (who are, mostly, also the authors) of these packages provided a lot of example models and test cases.&lt;/p&gt;

&lt;h1 id=&#34;changes-in-20&#34;&gt;Changes in 2.0&lt;/h1&gt;

&lt;h2 id=&#34;documentation&#34;&gt;Documentation&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&#34;https://tamaspapp.eu/DynamicHMC.jl/latest/worked_example/&#34;&gt;documentation&lt;/a&gt; was rewritten from scratch, now including a worked example. All functions of the API have extensive docstrings, usually with examples where relevant. This documentation should be the starting point for using this package.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Of course, if you have questions, feature requests, or bug reports, don&#39;t hesitate to &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl/issues/new&#34;&gt;open an issue&lt;/a&gt;; I would like to emphasize that it is still perfectly fine to open issues just to ask questions. You can also address questions to &lt;a href=&#34;https://discourse.julialang.org/u/Tamas_Papp&#34;&gt;&lt;code&gt;@Tamas_Papp&lt;/code&gt;&lt;/a&gt; on the Julia discourse forum.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&#34;main-interface&#34;&gt;Main interface&lt;/h2&gt;

&lt;p&gt;Most people would now call the sampler with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;results&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mcmc_with_warmup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Random&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GLOBAL_RNG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;∇P&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;where &lt;code&gt;∇P&lt;/code&gt; is an object that supports the &lt;a href=&#34;https://github.com/tpapp/LogDensityProblems.jl&#34;&gt;LogDensityProblems.jl&lt;/a&gt; API (basically “give me a log density and its gradient at this position”, withs some bells and whistles). &lt;code&gt;results&lt;/code&gt; is a &lt;code&gt;NamedTuple&lt;/code&gt; with fields like &lt;code&gt;chain&lt;/code&gt; (a vector of positions in &lt;span  class=&#34;math&#34;&gt;\(\mathbb{R}^n\)&lt;/span&gt;, which most users probably need to transform into a collection of constrained parameters), information on tree statistics and the adapted parameters. A detailed &lt;a href=&#34;https://tamaspapp.eu/DynamicHMC.jl/latest/worked_example/&#34;&gt;worked example&lt;/a&gt; is available.&lt;/p&gt;

&lt;p&gt;In contrast to the previous API, the random number generator needs to be explicitly provided. This is in preparation for &lt;a href=&#34;https://julialang.org/blog/2019/07/multithreading&#34;&gt;multithreading&lt;/a&gt;, encouraging the user to be conscious of RNGs as mutable states; the internals now also follow this approach with no default RNG in the sampling part.&lt;/p&gt;

&lt;h2 id=&#34;exposed-warmup-building-blocks&#34;&gt;Exposed warmup building blocks&lt;/h2&gt;

&lt;p&gt;The new API allows fine-grained control over the warmup stages. For example, this is how one would skip local optimization, ask for a dense (&lt;code&gt;Symmetric&lt;/code&gt;) metric instead of the default &lt;code&gt;Diagonal&lt;/code&gt;, and provide an initial position while at the same time allowing the stepsize to be found and adapted using the default heuristic:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# some initial position&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;warmup_stages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default_warmup_stages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;local_optimization&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;nothing&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                                      &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Symmetric&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;κ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GaussianKineticEnergy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;mcmc_with_warmup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rng&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ℓ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
                 &lt;span class=&#34;n&#34;&gt;initialization&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;κ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;κ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
                 &lt;span class=&#34;n&#34;&gt;warmup_stages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;warmup_stages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;warmup_stages&lt;/code&gt; above is just a &lt;code&gt;Tuple&lt;/code&gt;, with no secret sauce, you are provided the tools to make up your own if necessary.&lt;/p&gt;

&lt;h2 id=&#34;changed-heuristics-and-warmup-defaults&#34;&gt;Changed heuristics and warmup defaults&lt;/h2&gt;

&lt;p&gt;In contrast to Stan, the old API did not look for a local optimum before starting the stepsize adaptation. This is fine in most cases, but occasionally adapting to an otherwise atypical region of the parameter space can cause problems with the algorithm later on. On the other hand, adapting too eagerly to models with singularities in the log posterior can also backfire very easily.&lt;/p&gt;

&lt;p&gt;The new default heuristics make a half-hearted effort to go near some local optimum, but don&#39;t overdo it, which I think is the right compromise. Also, there is some protection against singularities on the “edges” of &lt;span  class=&#34;math&#34;&gt;\(\mathbb{R}^n\)&lt;/span&gt; (which can happen with the “funnels” of hierarchical models).&lt;/p&gt;

&lt;p&gt;Stepsize adaptation became a bit more robust with some tweaks. I still think that the initial bracketing algorithm in this package is better than Stan&#39;s in some cases and worth the extra couple of evaluations, as it plays nicer with the dual averaging for posteriors where the optimal stepsize can change rapidly.&lt;/p&gt;

&lt;p&gt;The default kinetic energy metric is now &lt;code&gt;Diagonal&lt;/code&gt;. This should be nearly optimal except for very heavily correlated posteriors which also happen to be devoid of any other pathologies (this is rare in practice).&lt;/p&gt;

&lt;h2 id=&#34;diagnostics&#34;&gt;Diagnostics&lt;/h2&gt;

&lt;p&gt;Diagnostics were reorganized into a &lt;code&gt;DynamicHMC.Diagnostics&lt;/code&gt; submodule of their own. They are intended for &lt;em&gt;interactive use&lt;/em&gt;, and the exposed API can change with just a minor version increment. You can import them into your current module with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DynamicHMC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Diagnostics&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note that this package has no plotting functionality.&lt;/strong&gt; Use your favorite plotting package to visualize information, I made the plots below with &lt;a href=&#34;https://github.com/KristofferC/PGFPlotsX.jl&#34;&gt;PGFPlotsX.jl&lt;/a&gt; (and relevant code may eventually end up in a mini-package, for now see the link below).&lt;/p&gt;



&lt;div class=&#34;codedownload&#34;&gt;&lt;p&gt;download code as &lt;a href=&#34;https://tamaspapp.eu/post/2019-08-29-dynamichmc2/plots.jl&#34;&gt;plots.jl&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;


&lt;h3 id=&#34;detailed-tree-statistics&#34;&gt;Detailed tree statistics&lt;/h3&gt;

&lt;p&gt;Each result that contains a &lt;code&gt;chain&lt;/code&gt; also comes with corresponding &lt;code&gt;tree_statistics&lt;/code&gt;, which is a &lt;em&gt;vector&lt;/em&gt; of statistics for each NUTS step. It contains information about acceptance ratios, number of leapfrog steps and tree depth, and the doubling directions. In 2.0, it also contains a field which informs the user about the location (in steps relative to the starting point).&lt;/p&gt;

&lt;p&gt;There is a &lt;code&gt;summarize_tree_statistics&lt;/code&gt; function that produces a useful summary about acceptance rations:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;results&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mcmc_with_warmup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Random&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GLOBAL_RNG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ℓ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
                                  &lt;span class=&#34;n&#34;&gt;reporter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NoProgressReport&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;results&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tree_statistics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;DynamicHMC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TreeStatisticsNUTS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.7246438302263802&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                              &lt;span class=&#34;n&#34;&gt;turning&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;at&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;positions&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.963443025058039&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                              &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DynamicHMC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Directions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0x595b1b9c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;summarize_tree_statistics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;results&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tree_statistics&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Hamiltonian&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Monte&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Carlo&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sample&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;acceptance&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rate&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.94&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;25&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;75&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;95&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.75&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.92&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.97&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;termination&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;divergence&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;max_depth&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;turning&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;depth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;55&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;calculating-leapfrog-trajectories&#34;&gt;Calculating leapfrog trajectories&lt;/h3&gt;

&lt;p&gt;A call not unlike&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;traj&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;leapfrog_trajectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ℓ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
                           &lt;span class=&#34;n&#34;&gt;κ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GaussianKineticEnergy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
                           &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;was used to produce the information that was used for the plot below. The resulting vector (here, &lt;code&gt;traj&lt;/code&gt;) contains a &lt;code&gt;NamedTuple&lt;/code&gt; of positions, momenta, and relative energy. Here the stepsize &lt;span  class=&#34;math&#34;&gt;\(\epsilon = 0.2\)&lt;/span&gt; was selected to on purpose as near-but-not-quite-unstable, starting from position &lt;code&gt;[0, -2]&lt;/code&gt;, taking 6 leapfrog steps backward and 10 forward.&lt;/p&gt;



&lt;img src=&#34;../post/2019-08-29-dynamichmc2/trajectory.svg&#34; alt=&#34;Hamiltonian trajectory&#34;&gt;


&lt;p&gt;The plot below visualizes the energy relative to the starting point.&lt;/p&gt;



&lt;img src=&#34;../post/2019-08-29-dynamichmc2/relative_energy.svg&#34; alt=&#34;Relative energy&#34;&gt;


&lt;h3 id=&#34;exploring-log-acceptance-ratios&#34;&gt;Exploring log acceptance ratios&lt;/h3&gt;

&lt;p&gt;It can be very useful to explore log acceptance ratios. &lt;code&gt;explore_log_acceptance_ratios&lt;/code&gt; returns a matrix of them with random momenta. In the plot below, we can see things become iffy for &lt;span  class=&#34;math&#34;&gt;\(\epsilon &gt; 0.5\)&lt;/span&gt;, approximately.&lt;/p&gt;



&lt;img src=&#34;../post/2019-08-29-dynamichmc2/log_accept.svg&#34; alt=&#34;&#34;&gt;


&lt;h2 id=&#34;internal-changes&#34;&gt;Internal changes&lt;/h2&gt;

&lt;p&gt;Although there is a new API, the bulk of the changes were internal: resulting in (hopefully) much cleaner and more generic code, better unit tests, and improved documentation documentation for the internals, which are especially relevant for users using this package for research. If this affects you, please read the code and the docstrings and feel free to ask questions.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">PSA: breaking API changes LogDensityProblems and DynamicHMC</title>
    <link href="https://tamaspapp.eu/post/2019-07-25-psa-dhmc-api-change/"/>
    <id>https://tamaspapp.eu/post/2019-07-25-psa-dhmc-api-change/</id>
    <published>2019-07-25T10:32:13+02:00</published>
    <updated>2019-07-25T10:32:13+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/2019-07-25-psa-dhmc-api-change/">&lt;p&gt;The API of LogDensityProblems and DynamicHMC is being redesigned (issues: &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl/issues/30&#34;&gt;DynamicHMC#30&lt;/a&gt;, &lt;a href=&#34;https://github.com/tpapp/LogDensityProblems.jl/issues/45&#34;&gt;LogDensityProblems#45&lt;/a&gt;). This is necessary to address some issues related to ease of use, debugging, robustness, adaptation, and better integration with some advanced AD packages like Zygote.&lt;/p&gt;

&lt;p&gt;Once the changes are complete, I will post a detailed writeup for the transition. But in the meantime, if you are using my MCMC libraries, you may want to pin versions, or put the following in your &lt;code&gt;Project.toml&lt;/code&gt;&#39;s &lt;code&gt;[compat]&lt;/code&gt; section (you only need the &lt;code&gt;[compat]&lt;/code&gt; if there isn&#39;t one):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;compat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;DynamicHMC&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;^1.0.5&amp;#34;&lt;/span&gt;
&lt;span class=&#34;nx&#34;&gt;LogDensityProblems&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;^0.8.3&amp;#34;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For more information, please refer to the &lt;a href=&#34;https://julialang.github.io/Pkg.jl/dev/compatibility/&#34;&gt;Pkg docs&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Changes for DynamicHMC.jl and related packages</title>
    <link href="https://tamaspapp.eu/post/dynamichmc-reorganization/"/>
    <id>https://tamaspapp.eu/post/dynamichmc-reorganization/</id>
    <published>2018-10-04T13:30:24+02:00</published>
    <updated>2018-10-04T13:30:24+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/dynamichmc-reorganization/">&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: new wrapper types for AD (with support for &lt;a href=&#34;https://github.com/FluxML/Flux.jl&#34;&gt;Flux.jl&lt;/a&gt;), new transformation interface, &lt;a href=&#34;https://github.com/tpapp/DynamicHMCExamples.jl&#34;&gt;see the examples&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl&#34;&gt;DynamicHMC.jl&lt;/a&gt; is Julia package for Hamiltonian MCMC using the NUTS algorithm. Its interface and the related packages underwent some reorganization which involves API changes. This post is a brief summary, as I prefer to maintain the actual &lt;a href=&#34;https://github.com/tpapp/DynamicHMCExamples.jl&#34;&gt;examples in a repository&lt;/a&gt; I can test. You are encouraged to read these, and the documentation for each package (some of which is WIP).&lt;/p&gt;

&lt;p&gt;A summary of the changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/TransformVariables.jl&#34;&gt;TransformVariables.jl&lt;/a&gt; replaces the previous DSL for transforming parameters (which was &lt;a href=&#34;https://github.com/tpapp/ContinuousTransformations.jl&#34;&gt;ContinuousTransformations.jl&lt;/a&gt;). It has a different syntax, and should make it easier to specify custom transformations in the future (this is work in progress).&lt;/p&gt;

&lt;p&gt;For example,&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asℝ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asℝ₊&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;will specify a transformation of 2 real numbers to a &lt;code&gt;NamedTuple&lt;/code&gt; with fields &lt;code&gt;μ&lt;/code&gt; (unconstrained) and &lt;code&gt;σ&lt;/code&gt; (constrained to be positive, eg a standard deviation).&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/LogDensityProblems.jl&#34;&gt;LogDensityProblems.jl&lt;/a&gt; contains the wrapper types for log density functions &lt;span  class=&#34;math&#34;&gt;\(\mathbb{R}^n \to \mathbb{R}\)&lt;/span&gt;. The most common workflow is making your function map a tuple of parameters to a &lt;code&gt;::Real&lt;/code&gt; (which may be &lt;code&gt;-Inf&lt;/code&gt;), define a transformation, and then obtain the gradient via automatic differentiation. Currently &lt;a href=&#34;https://github.com/JuliaDiff/ForwardDiff.jl&#34;&gt;ForwardDiff.jl&lt;/a&gt; (suboptimal for gradients, but very robust) and &lt;a href=&#34;https://github.com/FluxML/Flux.jl&#34;&gt;Flux.jl&lt;/a&gt; (faster) are supported. Support for &lt;a href=&#34;https://github.com/FluxML/Zygote.jl&#34;&gt;Zygote.jl&lt;/a&gt; and &lt;a href=&#34;https://github.com/JuliaDiff/ReverseDiff.jl&#34;&gt;ReverseDiff.jl&lt;/a&gt; should be easy to add, just open an issue.&lt;/p&gt;

&lt;p&gt;For example, once you have specified a callable &lt;code&gt;p&lt;/code&gt; that takes the transformed parameters which result from transformation &lt;code&gt;t&lt;/code&gt;,&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;P&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TransformedLogDensity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;∇P&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FluxGradientLogDensity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;P&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;will wrap them so that &lt;a href=&#34;https://github.com/FluxML/Flux.jl&#34;&gt;Flux.jl&lt;/a&gt; is used for obtaining the gradient via AD.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl&#34;&gt;DynamicHMC.jl&lt;/a&gt; expects a callable that supports the &lt;code&gt;dimension&lt;/code&gt; query function, takes a vector of reals, and returns a &lt;code&gt;LogDensityProblems.ValueGradient&lt;/code&gt; type. The recommended way of obtaining this is using the wrapper libraries above, but you are of course free to code your own.&lt;/p&gt;

&lt;p&gt;To continue the example, obtaining samples is now as simple as&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NUTS_tuned&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NUTS_init_tune_mcmc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;∇P&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;because &lt;code&gt;∇P&lt;/code&gt; now contains the dimension information.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of the above packages are registered. The new version for DynamicHMC.jl is &lt;code&gt;v1.0.0&lt;/code&gt;, as the API change is breaking. All of the packages require at least Julia &lt;code&gt;v0.7&lt;/code&gt;, but &lt;code&gt;v1.0&lt;/code&gt; or later is recommended.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/tpapp/DynamicHMCExamples.jl&#34;&gt;DynamicHMCExamples.jl&lt;/a&gt; has some examples on suggested usage. I am happy to provide &lt;em&gt;support with coding specific models&lt;/em&gt;, just please open an issue there. As usual, bug reports, feature requests and PRs are welcome.&lt;/p&gt;

&lt;p&gt;Finally, I would like to thank users for their patience and feedback. I hope that you will find new interface more convenient, and the improved speed useful.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PS.: I have removed the Disqus comments from the blog; they broke the style and hardly anyone was using them anyway.&lt;/em&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Making dotted graph paper in Julia with Luxor.jl</title>
    <link href="https://tamaspapp.eu/post/dotted-paper-luxor/"/>
    <id>https://tamaspapp.eu/post/dotted-paper-luxor/</id>
    <published>2018-06-18T11:30:24+02:00</published>
    <updated>2018-06-18T11:30:24+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/dotted-paper-luxor/">&lt;p&gt;I needed some graph paper with subdivisions at centimeters and millimetres. There are some generators online, but I found their output too heavy, visually cluttered, or simply not ideal (yes, I am very picky about these things).&lt;/p&gt;

&lt;p&gt;The obvious solution was to generate a PDF or SVG using a program. Before learning Julia, I would have just started in &lt;a href=&#34;https://sourceforge.net/projects/pgf/&#34;&gt;&lt;code&gt;pgf/tikz&lt;/code&gt;&lt;/a&gt;, and spent hours searching online to do the thing I want. &lt;code&gt;pgf/tikz&lt;/code&gt; are fine tools, but I generally try to avoid programming anything nontrivial in LaTeX, so I always have to spend a lot of time debugging my code.&lt;/p&gt;

&lt;p&gt;However, being a Julia user, this was a great opportunity to try &lt;a href=&#34;https://github.com/JuliaGraphics/Luxor.jl&#34;&gt;&lt;code&gt;Luxor.jl&lt;/code&gt;&lt;/a&gt;, the “Cairo for tourists!”. This means that I don&#39;t have to immerse myself in the intricacies of its syntax and concepts; I can just dip my toes and get the results.&lt;/p&gt;

&lt;p&gt;I was not disappointed: within 15 minutes of &lt;code&gt;Pkg.add(&amp;quot;Luxor&amp;quot;)&lt;/code&gt;, I had arrived at a solution I like. I am very satisfied with &lt;code&gt;Luxor.jl&lt;/code&gt; and will probably use it in the future when I need graphics built up from primitives.&lt;/p&gt;




&lt;div class=&#34;codedisplay&#34;&gt;
  &lt;div class=&#34;codeheader&#34;&gt;&lt;p&gt;download as &lt;a href=&#34;https://tamaspapp.eu/post/dotted-paper-luxor/dotted_paper.jl&#34;&gt;dotted_paper.jl&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Luxor&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;#######################&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# customize script here&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;#######################&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;paper&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;A4&amp;#34;&lt;/span&gt;                       &lt;span class=&#34;c&#34;&gt;# paper size&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;major_unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cm&lt;/span&gt;                   &lt;span class=&#34;c&#34;&gt;# gridlines at each&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subdivisions&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;                  &lt;span class=&#34;c&#34;&gt;# dots on gridlines in between&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;radius&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mm&lt;/span&gt;                     &lt;span class=&#34;c&#34;&gt;# radius for the tiny dots&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;margins&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;               &lt;span class=&#34;c&#34;&gt;# minimum margins (may be more, centered)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;black&amp;#34;&lt;/span&gt;                    &lt;span class=&#34;c&#34;&gt;# color for the tiny dots&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;dotted_paper.pdf&amp;#34;&lt;/span&gt;      &lt;span class=&#34;c&#34;&gt;# output goes here, OVERWRITTEN&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;#######################################################&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# runtime code - you probably don&amp;#39;t need to change this&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;#######################################################&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;pagesize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;paper_sizes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;paper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;floor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pagesize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;margins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;major_unit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;offsetx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offsety&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;margins&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pagesize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;major_unit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;major_grid_x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offsetx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;major_unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;major_grid_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offsety&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;major_unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;minor_grid_x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offsetx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;major_unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subdivisions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subdivisions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;minor_grid_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offsety&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.+&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;major_unit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subdivisions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subdivisions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;Drawing&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;paper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;background&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;white&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;sethue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;circle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;major_grid_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;minor_grid_y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;radius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fill&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;circle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;minor_grid_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;major_grid_y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;radius&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fill&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;finish&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;preview&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The final PDF is &lt;a href=&#34;dotted_paper.pdf&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Teaching</title>
    <link href="https://tamaspapp.eu/teaching/"/>
    <id>https://tamaspapp.eu/teaching/</id>
    <published>2018-04-27T14:48:06+02:00</published>
    <updated>2018-04-27T14:48:06+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/teaching/">&lt;h2 id=&#34;introduction-to-bayesian-estimation-of-dsge-models&#34;&gt;Introduction to Bayesian estimation of DSGE models&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;../pdf/DSGE_Bayesian_slides.pdf&#34;&gt;PDF&lt;/a&gt; Slides (with references and further reading) for an introductory course on Bayesian estimation of DSGE models. Mostly Bayesian concepts and practical issues (diagnostics, posterior predictive checks, convergence problems).&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Common random variables: an optimization case study</title>
    <link href="https://tamaspapp.eu/post/common-random-variables/"/>
    <id>https://tamaspapp.eu/post/common-random-variables/</id>
    <published>2018-03-23T15:23:16+01:00</published>
    <updated>2018-03-23T15:23:16+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/common-random-variables/">
&lt;div class=&#34;juliaversionwarning&#34;&gt;&lt;p&gt;Code used in this post was written for Julia &lt;strong&gt;v0.6.2&lt;/strong&gt; and, when applicable, reflects the state of packages used on &lt;strong&gt;2018-03-23&lt;/strong&gt;. You may need to modify it for different versions.&lt;/p&gt;&lt;/div&gt;


&lt;h2 id=&#34;motivation&#34;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;When simulating models with random components, it is frequently advantageous to decompose the structure into&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;parameters&lt;/em&gt; &lt;span  class=&#34;math&#34;&gt;\(\theta\)&lt;/span&gt; that we need to characterize structural relationships,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;em&gt;noise&lt;/em&gt; &lt;span  class=&#34;math&#34;&gt;\(\varepsilon\)&lt;/span&gt;  that is independent of parameters,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;a function &lt;span  class=&#34;math&#34;&gt;\(f(\theta, \varepsilon)\)&lt;/span&gt; that generates observed data or moments.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Doing this allows us to use &lt;a href=&#34;https://en.wikipedia.org/wiki/Variance_reduction#Common_Random_Numbers_(CRN)&#34;&gt;common random variables&lt;/a&gt; (aka common random &lt;em&gt;numbers&lt;/em&gt;), which is a technique which simply keeps &lt;span  class=&#34;math&#34;&gt;\(\varepsilon\)&lt;/span&gt; fixed for different &lt;span  class=&#34;math&#34;&gt;\(\theta\)&lt;/span&gt;. This can help with making &lt;span  class=&#34;math&#34;&gt;\(f\)&lt;/span&gt; differentiable, which allows the use of derivative-based optimization algorithms (eg for maximum likelihood or &lt;a href=&#34;https://en.wikipedia.org/wiki/Maximum_a_posteriori_estimation&#34;&gt;MAP&lt;/a&gt;) or derivative-based MCMC methods. It is also used to reduce the variance of simulated moments.&lt;/p&gt;

&lt;p&gt;When implementing this technique in Julia, I frequently create a wrapper structure that saves the &lt;span  class=&#34;math&#34;&gt;\(\varepsilon\)&lt;/span&gt;, allocating an &lt;code&gt;Array&lt;/code&gt; which can be updated in place. Since a redesign of &lt;a href=&#34;https://github.com/tpapp/DynamicHMC.jl/&#34;&gt;DynamicHMC.jl&lt;/a&gt; is coming up which will accommodate simulated likelihood methods in a more disciplined manner, and I wanted to explore other options, most importantly &lt;a href=&#34;https://github.com/JuliaArrays/StaticArrays.jl&#34;&gt;StaticArrays.jl&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here I benchmark the alternatives for Julia &lt;code&gt;v0.6.2&lt;/code&gt; using a simple toy model. &lt;strong&gt;TL;DR&lt;/strong&gt; for the impatient: &lt;code&gt;StaticArrays.jl&lt;/code&gt; is 150x faster, and this does not depend on using immutable or mutable &lt;code&gt;StaticArray&lt;/code&gt;s, or even reallocating every time new &lt;span  class=&#34;math&#34;&gt;\(\varepsilon\)&lt;/span&gt;s are generated.&lt;/p&gt;

&lt;h2 id=&#34;problem-setup&#34;&gt;Problem setup&lt;/h2&gt;

&lt;p&gt;The setup is simple: we draw &lt;span  class=&#34;math&#34;&gt;\(M\)&lt;/span&gt; observations, and our noise is&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\varepsilon_{i,j} \sim N(0, 1)
\qquad
\text{for } i = 1, \dots, M; j = 1, \dots, 7.
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Our parameters are &lt;span  class=&#34;math&#34;&gt;\(\mu\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(\sigma\)&lt;/span&gt;, and for each &lt;span  class=&#34;math&#34;&gt;\(i\)&lt;/span&gt; we calculate&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
A_i = \frac17 \sum_{j=1}^7 \exp(\mu + \sigma \varepsilon_{i,j})
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;which is the sample average after a nonlinear transformation. The &lt;span  class=&#34;math&#34;&gt;\(7\)&lt;/span&gt; is a bit accidental, it comes from simplifying an actual problem I am working on. We are interested in the sample average for &lt;span  class=&#34;math&#34;&gt;\(A_i\)&lt;/span&gt;. I deliberately refrain micro-optimizing each version, to reflect how I would approach a real-life problem.&lt;/p&gt;

&lt;p&gt;We code the common interface as&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BenchmarkTools&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StaticArrays&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Parameters&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;# common interface&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&amp;#34;Dimension of noise ``ϵ`` for each observation.&amp;#34;&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EDIM&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Common random variables. The user needs to define
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;1. `observation_moments`, which should use `observation_moment`,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;2. `newcrv = update!(crv)`, which returns new common random variables,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;potentially (but not necessarily) overwriting `crv`.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;abstract type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CRVContainer&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;observation_moment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;average_moment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CRVContainer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;observation_moments&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&amp;#34;Calculate statistics, making `N` draws, updating every `L`th time.&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;L&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;_stat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;L&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crv&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;update!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;average_moment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_stat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The way I wrote &lt;code&gt;stats&lt;/code&gt; is representative of how I use HMC/NUTS: simulated moments on the same trajectory are calculated with the same &lt;span  class=&#34;math&#34;&gt;\(\varepsilon\)&lt;/span&gt;s, which are updated for each trajectory. Of course, the parameters would change along the trajectory; here they don&#39;t, but this does not affect the benchmarks.&lt;/p&gt;

&lt;p&gt;The semantics of &lt;code&gt;update!&lt;/code&gt; allows &lt;em&gt;both&lt;/em&gt; in-place modifications and a functional style.&lt;/p&gt;

&lt;h2 id=&#34;using-a-preallocated-matrix&#34;&gt;Using a preallocated matrix&lt;/h2&gt;

&lt;p&gt;This is the standard way I would write this.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:Which-will-chang&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:Which-will-chang&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;span  class=&#34;math&#34;&gt;\(\varepsilon\)&lt;/span&gt;s are in columns of a matrix, which is preferable for mapping them as slices, then they are mapped using &lt;code&gt;observation_moment&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;update!&lt;/code&gt; overwrites the contents.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Common random variables are stored in columns of a matrix.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PreallocatedMatrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CRVContainer&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;PreallocatedMatrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PreallocatedMatrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EDIM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;update!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PreallocatedMatrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;observation_moments&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PreallocatedMatrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mapslices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;observation_moment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;using-static-vectors&#34;&gt;Using static vectors&lt;/h2&gt;

&lt;p&gt;We share the following between various static vector implementations:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Common random variables as a vector of vectors, in the `ϵs`.&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;abstract type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CRVVectors&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CRVContainer&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;observation_moments&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CRVVectors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;observation_moment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;σ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I find the use of &lt;code&gt;map&lt;/code&gt; more intuitive here than &lt;code&gt;mapslices&lt;/code&gt; above.&lt;/p&gt;

&lt;h3 id=&#34;static-vectors-container-preallocated&#34;&gt;Static vectors, container preallocated&lt;/h3&gt;

&lt;p&gt;In the first version using static vectors, we keep &lt;code&gt;SVector&lt;/code&gt; in a &lt;code&gt;Vector&lt;/code&gt;, and update in place.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PreallocatedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CRVVectors&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;PreallocatedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;PreallocatedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@SVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EDIM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;update!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PreallocatedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@unpack&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@inbounds&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;indices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@SVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EDIM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;mutable-static-vectors-overwritten&#34;&gt;Mutable static vectors, overwritten&lt;/h3&gt;

&lt;p&gt;We modify this to use mutable vectors — this should not make a difference.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MutableStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CRVVectors&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;MutableStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;MutableStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@MVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EDIM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;update!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MutableStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@unpack&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@inbounds&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;indices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;randn!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&#34;static-vectors-allocated-each-time&#34;&gt;Static vectors, allocated each time&lt;/h3&gt;

&lt;p&gt;Finally, for the third solution,&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GeneratedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CRVVectors&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;GeneratedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;GeneratedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@SVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EDIM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;update!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GeneratedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;where&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;GeneratedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@SVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;indices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ϵs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)])&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&#34;results&#34;&gt;Results&lt;/h2&gt;

&lt;p&gt;Running&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@btime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PreallocatedMatrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@btime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PreallocatedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@btime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MutableStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@btime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GeneratedStaticCRV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we obtain&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;solution&lt;/th&gt;
&lt;th align=&#34;left&#34;&gt;time&lt;/th&gt;
&lt;th align=&#34;right&#34;&gt;allocations&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PreallocatedMatrix&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;230 ms&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;&lt;code&gt;22 MiB&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PreallocatedStaticCRV&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;1.5 ms&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;&lt;code&gt;102 KiB&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MutableStaticCRV&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;1.5 ms&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;&lt;code&gt;104 KiB&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GeneratedStaticCRV&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;1.5 ms&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;&lt;code&gt;666 KiB&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;As a preview of future improvements, I tried &lt;code&gt;PreallocatedMatrix&lt;/code&gt; on current &lt;code&gt;master&lt;/code&gt; (which will become Julia &lt;code&gt;v0.7&lt;/code&gt;, obtaining &lt;code&gt;3.5 ms&lt;/code&gt; (&lt;code&gt;2.46 MiB&lt;/code&gt;), which is really promising.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:The-other-3-opti&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:The-other-3-opti&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;The conclusion is that &lt;code&gt;StaticArrays&lt;/code&gt; simplifies and speeds up my code &lt;em&gt;at the same time&lt;/em&gt;. I especially like the last version (&lt;code&gt;GeneratedStaticCRV&lt;/code&gt;), because it obviates the need to think about types in advance. While here the example is simple, in practice I would use automatic differentiation, which makes it more challenging to determine buffer types in advance. I expect I will transition to a more “buffer-free” style in the future, and design the interface for DynamicHMC.jl accordingly.&lt;/p&gt;



&lt;div class=&#34;codedownload&#34;&gt;&lt;p&gt;download code as &lt;a href=&#34;https://tamaspapp.eu/post/common-random-variables/code.jl&#34;&gt;code.jl&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;PS:&lt;/strong&gt; From now on, my blog posts with Julia code will have a banner about version information.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:Which-will-chang&#34;&gt;Which will change following this blog post 😁 &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:Which-will-chang&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:The-other-3-opti&#34;&gt;The other 3 options are slow because of deprecation warnings. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:The-other-3-opti&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Local test coverage in Julia</title>
    <link href="https://tamaspapp.eu/post/julia-local-coverage/"/>
    <id>https://tamaspapp.eu/post/julia-local-coverage/</id>
    <published>2018-03-09T08:31:23+01:00</published>
    <updated>2018-03-09T08:31:23+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/julia-local-coverage/">&lt;p&gt;While &lt;a href=&#34;https://codecov.io/&#34;&gt;codecov.io&lt;/a&gt; and &lt;a href=&#34;https://coveralls.io/&#34;&gt;coveralls.io&lt;/a&gt; are fine services and very easy to set up for Github repositories with Julia packages, they become more difficult to use under some circumstances. For example, if testing requires large binaries you don&#39;t want to build every time, you need to &lt;a href=&#34;https://tamaspapp.eu/post/travis-docker-julia-ci/&#34;&gt;build a Docker image&lt;/a&gt; to run testing and obtain coverage information. Also, if your test scripts take a long time and you have access to a powerful computer, you might want to just run coverage locally when working on the code.&lt;/p&gt;

&lt;p&gt;Naturally, Julia has all the facilities for generating and collecting coverage information locally. To make their application even easier, I packaged up a small set of scripts in &lt;a href=&#34;https://github.com/tpapp/LocalCoverage.jl&#34;&gt;LocalCoverage.jl&lt;/a&gt; that I use to generate and visualize coverage information for Julia packages on my machine.&lt;/p&gt;

&lt;p&gt;This is how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;run &lt;code&gt;generate_coverage(pkg)&lt;/code&gt; to&lt;/p&gt;

&lt;p&gt;a. run &lt;code&gt;Pkg.test(pkg; coverage = true)&lt;/code&gt;,&lt;/p&gt;

&lt;p&gt;b. use &lt;code&gt;Coverage.jl&lt;/code&gt; for collecting information to a single file in &lt;code&gt;lcov&lt;/code&gt; format,&lt;/p&gt;

&lt;p&gt;c. unless disabled, run the external program &lt;code&gt;genhtml&lt;/code&gt; to format everything as a nice HTML file.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;if you have generated the HTML files, &lt;code&gt;open_coverage(pkg)&lt;/code&gt; opens them for you in your default browser.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;if you want to tidy up, run &lt;code&gt;clean_coverage(pkg)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is what it looks like for this package:&lt;/p&gt;

&lt;iframe src=&#34;../misc/coverage-example/src/LocalCoverage.jl.gcov.html&#34;&gt;&lt;/iframe&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Setting up Julia with continuous integration on Gitlab</title>
    <link href="https://tamaspapp.eu/post/julia-ci-gitlab/"/>
    <id>https://tamaspapp.eu/post/julia-ci-gitlab/</id>
    <published>2018-03-08T17:06:54+01:00</published>
    <updated>2018-03-08T17:06:54+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/julia-ci-gitlab/">&lt;p&gt;As an academic, I picked up good practices for programming mostly by osmosis. My approach to “testing” software went through the following stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;See if the code runs (this got me through my undergrad years).&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Check if the results “look OK”, then forget about testing.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Compare results occasionally to known results from papers or other code (eg in a different language).&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Write some unit tests &lt;em&gt;ex post&lt;/em&gt;, as an afterthought after the code is finished (time pressure helps to ensure that overtesting is never a problem).&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Use unit tests from the very beginning, especially before optimizing and refactoring code.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Set up automatic testing, as part of &lt;em&gt;continuous integration&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I think that 1–3 above is a pretty usual path, naturally traversed after the recognition that &lt;em&gt;some&lt;/em&gt; testing would be nice, but lacking the knowledge of &lt;em&gt;how to implement it&lt;/em&gt; in a consistent manner. This is comparable to using copies of directories as crude attempts at “version control”.&lt;/p&gt;

&lt;p&gt;Later, I picked up 4–6 while being exposed to these ideas when learning about new languages. Automated unit testing is one of those things one does not miss until learning about it, then subsequently cannot imagine doing without. In a research context, the two main advantages are &lt;em&gt;scientific integrity&lt;/em&gt; — I should make a best effort to ensure that my results are correct — and &lt;em&gt;dealing with bugs early&lt;/em&gt;. While the first one is abstract and philosophical, the second is a practical concern: I found that if I skimp on testing, the bugs show up much later, usually at an inconvenient time, and I will have to spent time locating the bug (not always trivial, especially with numerical code) and switch context to something I was working on months ago. It is my experience that while tests can be tedious to write, time spent on them is a very good investment.&lt;/p&gt;

&lt;p&gt;I knew about unit tests before coming to Julia, but learned about automated CI in the Julia community. This was because package template libraries “do the right thing” by making it very easy to set up an automated testing framework: for example, &lt;code&gt;PkgDev.generate&lt;/code&gt; creates the appropriate test configuration for &lt;a href=&#34;http://travis-ci.org/&#34;&gt;Travis CI&lt;/a&gt; and various coverage services.&lt;/p&gt;

&lt;p&gt;I never cease to be amazed by the fact that these services are available for free for public / open source projects, which is very generous of these providers. However, occasionally one would like to keep the project private for a little while. The usual scenario for me is working on code that is related to a paper, which I plan to make public with the latter; in this case one would need the pro (non-free) version of Travis and related tools.&lt;/p&gt;

&lt;p&gt;Alternatively, &lt;a href=&#34;https://gitlab.com/&#34;&gt;Gitlab&lt;/a&gt; offers CI/CD with private repositories. I am exploring this at the moment for various projects, and boiled down the necessary configuration into the repository &lt;a href=&#34;https://gitlab.com/tkpapp/GitlabJuliaDemo.jl&#34;&gt;GitlabJuliaDemo.jl&lt;/a&gt;. It has&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;a CI setup for &lt;code&gt;Pkg.test&lt;/code&gt;,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;a coverage &lt;em&gt;summary&lt;/em&gt; as a percentage.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While coverage analysis could be &lt;a href=&#34;https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/&#34;&gt;automated&lt;/a&gt; too with a custom Docker image, I leave his for future work.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:In-the-next-post&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:In-the-next-post&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;So far, I am very satisfied with Gitlab. The interface is well-designed, clean, and intuitive; tests complete in a few minutes (just like Travis).&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:In-the-next-post&#34;&gt;In the next post I will talk about local coverage analysis in Julia. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:In-the-next-post&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Continuous integration for Julia packages using Docker</title>
    <link href="https://tamaspapp.eu/post/travis-docker-julia-ci/"/>
    <id>https://tamaspapp.eu/post/travis-docker-julia-ci/</id>
    <published>2018-01-19T08:47:06+01:00</published>
    <updated>2018-01-19T08:47:06+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/travis-docker-julia-ci/">&lt;p&gt;This post may be useful for maintainers of Julia packages which require a large binary dependencies on CI services like Travis.&lt;/p&gt;

&lt;p&gt;I have recently started using Kristoffer Carlsson&#39;s excellent &lt;a href=&#34;https://github.com/KristofferC/PGFPlotsX.jl&#34;&gt;PGFPlotsX&lt;/a&gt; for plotting. The package is a thin wrapper which emits LaTeX code for use with &lt;a href=&#34;http://pgfplots.sourceforge.net/&#34;&gt;pgfplots&lt;/a&gt;, which is extremely versatile and well-documented.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:Using-this-packa&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:Using-this-packa&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; However, since most of the action happens in LaTeX, unit testing requires a lot of binary dependencies, including the &lt;a href=&#34;https://tug.org/texlive/&#34;&gt;TeXLive&lt;/a&gt; suite and some related packages. This is not a problem on one&#39;s own machine where these would need to be installed just once, but when I submitted PRs, tests on Travis timed out more often than not because it had to install all of these for every run using &lt;code&gt;apt-get&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The documentation of Travis suggested that &lt;a href=&#34;http://docker.com/&#34;&gt;docker&lt;/a&gt; may be a solution for such cases, and I have been looking an opportunity to experiment with it anyway. After reading their tutorial it was relatively quick to produce an image based on plain vanilla Ubuntu 17.10, which is available as a docker image to build on, and the required TeXLive and related packages, plus some utilities.&lt;/p&gt;

&lt;p&gt;During building the image, I download the binaries for the stable version Julia, while &lt;code&gt;nightly&lt;/code&gt; is downloaded on demand. This speeds up CI by 40–50 seconds for &lt;code&gt;stable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is how it is run:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;the directory of the Julia package is mounted in the container at &lt;code&gt;/mnt&lt;/code&gt;,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;Pkg.clone()&lt;/code&gt; and testing proceed as usual,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;coverage results are copied back to &lt;code&gt;/mnt&lt;/code&gt; when done.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The resulting image runs in 3–4 minutes consistently. In case someone finds it useful for Julia packages with similarly large binary dependencies, I made it available as &lt;a href=&#34;https://github.com/tpapp/texlive-julia-minimal-docker&#34;&gt;&lt;code&gt;texlive-julia-minimal-docker&lt;/code&gt;&lt;/a&gt; on Github.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:Minimal-turns-ou&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:Minimal-turns-ou&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; Naturally, for projects with other large binary dependencies, one would install different Ubuntu packages or binaries.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:Using-this-packa&#34;&gt;Using this package accelerated my plotting workflow in Julia. A post on this will follow soon. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:Using-this-packa&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:Minimal-turns-ou&#34;&gt;“Minimal” turns out to be a misnomer, since some dependencies end up requiring X11 and the image is &amp;gt;700GB. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:Minimal-turns-ou&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Working with large Julia source files in Emacs</title>
    <link href="https://tamaspapp.eu/post/large-files-julia/"/>
    <id>https://tamaspapp.eu/post/large-files-julia/</id>
    <published>2017-12-04T15:32:41+01:00</published>
    <updated>2017-12-04T15:32:41+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/large-files-julia/">&lt;p&gt;When writing software, especially libraries, a natural question is how to organize source code into files. Some languages, eg Matlab, encourage a very fragmented style (one function per file), while for some other languages (C/C++), a separation between the interface (&lt;code&gt;.h&lt;/code&gt;) and the implementation (&lt;code&gt;.c&lt;/code&gt;/&lt;code&gt;.cpp&lt;/code&gt;) is traditional.&lt;/p&gt;

&lt;p&gt;Julia has no such constraint: &lt;code&gt;include&lt;/code&gt; allows the source code for a module to be organized into small pieces, possibly scattered in multiple directories, or it can be a single monolithic piece of code. The choice on this spectrum is up to the authors, and is largely a matter of personal preference.&lt;/p&gt;

&lt;p&gt;When I started working with Julia, I was following the example of some prominent packages, and organized code into small pieces (~ 500 LOC). Lately, whenever I refactored my code, I ended up putting it in a single file.&lt;/p&gt;

&lt;p&gt;I found the following Emacs tools very helpful for navigation.&lt;/p&gt;

&lt;h2 id=&#34;form-feeds-and-pagebreaklinesmode&#34;&gt;Form feeds and page-break-lines-mode&lt;/h2&gt;

&lt;p&gt;Form feed, or &lt;code&gt;\f&lt;/code&gt;, is an ASCII control character that was used to request a new page in line printers. Your editor may display it as &lt;code&gt;^L&lt;/code&gt;. It has a long history of being used as a separator, and Emacs supports it in various ways.&lt;/p&gt;

&lt;p&gt;By default, &lt;code&gt;C-x [&lt;/code&gt; and &lt;code&gt;C-x ]&lt;/code&gt; take you to the previous and next form feed separators. Combined with numerical prefixes, eg &lt;code&gt;C-3 C-x [&lt;/code&gt;, you can jump across multiple ones very quickly. Other commands with &lt;code&gt;page&lt;/code&gt; in their name allow narrowing, marking, and other functions.&lt;/p&gt;

&lt;p&gt;Many Emacs packages provide extra functionality for page breaks. My favorite is &lt;a href=&#34;https://github.com/purcell/page-break-lines&#34;&gt;page-break-lines&lt;/a&gt;, which replaces &lt;code&gt;^L&lt;/code&gt; with a horizontal line, so that the output looks like this:&lt;/p&gt;

&lt;pre style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;export&lt;/span&gt;
    ML_estimator

&lt;hr style=&#34;background-color: #008b45; height: 1px; border: 0 none;&#34;&gt;&lt;span style=&#34;color: #008b45;&#34;&gt;# &lt;/span&gt;&lt;span style=&#34;color: #008b45;&#34;&gt;general API
&lt;/span&gt;
&lt;span style=&#34;color: #fa5151;&#34;&gt;&#34;&#34;&#34;
    ML_estimator(ModelType, data...)

Estimate `ModelType` using maximum likelihood
on `data`, which  is model-specific.
&#34;&#34;&#34;&lt;/span&gt;
&lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color: #2c53ca;&#34;&gt;ML_estimator&lt;/span&gt; &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;h2 id=&#34;finding-things-quickly&#34;&gt;Finding things quickly&lt;/h2&gt;

&lt;p&gt;I am using &lt;a href=&#34;https://emacs-helm.github.io/helm/&#34;&gt;helm&lt;/a&gt; pervasively. &lt;code&gt;helm-occur&lt;/code&gt; is very handy for listing all occurrences of something, and navigating them. The following is an except from &lt;code&gt;base/operators.jl&lt;/code&gt;, looking for &lt;code&gt;isless&lt;/code&gt;:&lt;/p&gt;

&lt;pre style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;span style=&#34;color: #00ced1; text-decoration: underline;&#34;&gt;operators.jl&lt;/span&gt;:&lt;span style=&#34;color: #ff7f00;&#34;&gt;213&lt;/span&gt;:types with a canonical total order should implement `&lt;span style=&#34;color: #b00000;&#34;&gt;isless&lt;/span&gt;`.
&lt;span style=&#34;color: #00ced1; text-decoration: underline;&#34;&gt;operators.jl&lt;/span&gt;:&lt;span style=&#34;color: #ff7f00;&#34;&gt;227&lt;/span&gt;:&amp;lt;(x, y) = &lt;span style=&#34;color: #b00000;&#34;&gt;isless&lt;/span&gt;(x, y)
&lt;span style=&#34;color: #00ced1; text-decoration: underline;&#34;&gt;operators.jl&lt;/span&gt;:&lt;span style=&#34;color: #ff7f00;&#34;&gt;300&lt;/span&gt;:# this definition allows Number types to implement &amp;lt; instead of &lt;span style=&#34;color: #b00000;&#34;&gt;isless&lt;/span&gt;,
&lt;span style=&#34;color: #00ced1; text-decoration: underline;&#34;&gt;operators.jl&lt;/span&gt;:&lt;span style=&#34;color: #ff7f00;&#34;&gt;302&lt;/span&gt;:&lt;span style=&#34;color: #b00000;&#34;&gt;isless&lt;/span&gt;(x::Real, y::Real) = x&amp;lt;y
&lt;span style=&#34;color: #00ced1; text-decoration: underline;&#34;&gt;operators.jl&lt;/span&gt;:&lt;span style=&#34;color: #ff7f00;&#34;&gt;303&lt;/span&gt;:lexcmp(x::Real, y::Real) = &lt;span style=&#34;color: #b00000;&#34;&gt;isless&lt;/span&gt;(x,y) ? -1 : ifelse(&lt;span style=&#34;color: #b00000;&#34;&gt;isless&lt;/span&gt;(y,x), 1, 0)
&lt;/pre&gt;

&lt;p&gt;You can move across these matches, jump to one in an adjacent buffer while keeping this list open, or save the list for later use. Its big brother &lt;code&gt;helm-do-grep-ag&lt;/code&gt; is even more powerful, using &lt;a href=&#34;https://geoff.greer.fm/ag/&#34;&gt;ag&lt;/a&gt; to find something in a directory tree.&lt;/p&gt;

&lt;p&gt;With these two tools, I find navigating files around 5K LOC very convenient — the better I learn Emacs, the larger my threshold for a “large” file becomes.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:In-case-you-are&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:In-case-you-are&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:In-case-you-are&#34;&gt;In case you are wondering, the largest files are around 6K LOC in Julia &lt;code&gt;Base&lt;/code&gt; at the moment. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:In-case-you-are&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Publication quality plots in Julia</title>
    <link href="https://tamaspapp.eu/post/plot-workflow/"/>
    <id>https://tamaspapp.eu/post/plot-workflow/</id>
    <published>2017-12-01T09:56:00+01:00</published>
    <updated>2017-12-01T09:56:00+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/plot-workflow/">&lt;p&gt;In light of recent discussions on Julia&#39;s &lt;a href=&#34;https://discourse.julialang.org/&#34;&gt;Discourse forum&lt;/a&gt; about getting “publication-quality” or simply “nice” plots in Julia, I thought it would be worthwhile to briefly summarize what works for me.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:Code-in-this-pos&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:Code-in-this-pos&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; If you are a seasoned Julia user, this post may have nothing new for you, but I hope that newcomers to Julia find it useful.&lt;/p&gt;

&lt;h2 id=&#34;generate-the-data&#34;&gt;Generate the data&lt;/h2&gt;

&lt;p&gt;I try to separate &lt;em&gt;data generation&lt;/em&gt; and &lt;em&gt;plotting&lt;/em&gt;. The first may be time-consuming (some calculations can take hours or days to run), and I find it best to save the results independently of any plotting. Recently I was sitting at a conference where a presentation about a really interesting topic had some plots that were extremely hard to see: if I remember correctly, something like 10x2 subplots, with almost all fine detail lost due to the resolution of the projector or the human eye. When someone in the audience asked about this, the presenting author replied that he is aware of the issue, but remaking the plots would involve rerunning the calculations, which take weeks. Saving the data separately will ensure that you are never in this situation; also, you can benefit from updates to plotting libraries when tweaking your plots.&lt;/p&gt;

&lt;p&gt;For saving results, &lt;a href=&#34;https://github.com/simonster/JLD2.jl&#34;&gt;JLD2&lt;/a&gt; is probably the most convenient tool: while it is technically work in progress, it is stable, fast, and convenient.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:In-the-worst-cas&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:In-the-worst-cas&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; The key question is &lt;em&gt;where&lt;/em&gt; to save the data: I find it best to use a consistent path that you can just include in scripts.&lt;/p&gt;

&lt;p&gt;You have several options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;define a global variable in your &lt;code&gt;~/.juliarc&lt;/code&gt; for your projects, and construct a path with &lt;code&gt;joinpath&lt;/code&gt;,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;if you have packaged your code, &lt;code&gt;Pkg.dir&lt;/code&gt; can be used to obtain a subdirectory in the package root,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;if your code is in a module, you can wrap &lt;code&gt;@__DIR__&lt;/code&gt; in a function to obtain a directory.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this blog post I used the first option, while in practice I use the second and the third.&lt;/p&gt;

&lt;p&gt;To illustrate plots, I use the code below to generate random variates for &lt;a href=&#34;https://en.wikipedia.org/wiki/Skewness#Sample_skewness&#34;&gt;sample skewness&lt;/a&gt;, and save it.&lt;/p&gt;




&lt;div class=&#34;codedisplay&#34;&gt;
  &lt;div class=&#34;codeheader&#34;&gt;&lt;p&gt;download as &lt;a href=&#34;https://tamaspapp.eu/post/plot-workflow/data.jl&#34;&gt;data.jl&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;StatsBase&lt;/span&gt;                 &lt;span class=&#34;c&#34;&gt;# for skewness&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JLD2&lt;/span&gt;                      &lt;span class=&#34;c&#34;&gt;# saving data&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;joinpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BLOG_POSTS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;plot-workflow&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# default path&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;sample_skewness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;skewness&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@save&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;data.jld2&amp;#34;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sample_skewness&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# save data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2 id=&#34;make-the-plot&#34;&gt;Make the plot&lt;/h2&gt;

&lt;p&gt;No plotting so far, so let&#39;s remedy that. I use &lt;a href=&#34;http://docs.juliaplots.org/latest/&#34;&gt;Plots.jl&lt;/a&gt;, which is a metapackage that unifies syntax for plotting via various &lt;em&gt;plotting backends&lt;/em&gt; in Julia. I find this practical, because I can quickly switch backends for different purposes, and experiment with various options when I find the output suboptimal. The price you pay for this flexibility is &lt;em&gt;compilation time&lt;/em&gt;, a known issue which means that you have to wait a bit to get your first plot. Separating plotting and data generation has the advantage that once I fire up the plotting infrastructure, I switch to “plotting mode” and clean up several plots at the same time.&lt;/p&gt;

&lt;p&gt;Users frequently ask what the “best” backend is. This all depends on your needs, but these days I use the &lt;code&gt;pgfplots()&lt;/code&gt; backend almost exclusively.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:Note-that-you-ne&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:Note-that-you-ne&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; The &lt;code&gt;gr()&lt;/code&gt; backend is also useful, because it is very fast.&lt;/p&gt;

&lt;p&gt;Time to tweak the plot! I find the &lt;a href=&#34;http://docs.juliaplots.org/latest/attributes/&#34;&gt;attributes&lt;/a&gt; documentation the most useful for this. For this plot I need axis labels, a title, and prefer to disable the legend since I am plotting a single series. I am also using &lt;a href=&#34;https://github.com/stevengj/LaTeXStrings.jl&#34;&gt;LaTeXStrings.jl&lt;/a&gt;, which means that I can use LaTeX-compatible syntax for labels seamlessly (notice the &lt;code&gt;L&lt;/code&gt; before the string).&lt;/p&gt;




&lt;div class=&#34;codedisplay&#34;&gt;
  &lt;div class=&#34;codeheader&#34;&gt;&lt;p&gt;download as &lt;a href=&#34;https://tamaspapp.eu/post/plot-workflow/plot.jl&#34;&gt;plot.jl&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JLD2&lt;/span&gt;                      &lt;span class=&#34;c&#34;&gt;# loading data&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Plots&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pgfplots&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;         &lt;span class=&#34;c&#34;&gt;# PGFPlots backend&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LaTeXStrings&lt;/span&gt;              &lt;span class=&#34;c&#34;&gt;# nice LaTeX strings&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;joinpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BLOG_POSTS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;plot-workflow&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# default path&lt;/span&gt;
&lt;span class=&#34;nd&#34;&gt;@load&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;data.jld2&amp;#34;&lt;/span&gt;                         &lt;span class=&#34;c&#34;&gt;# load data&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# make plot and tweak; this is the end result&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;plot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;histogram&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sample_skewness&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;normalize&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
     &lt;span class=&#34;n&#34;&gt;xlab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;L&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;\gamma_1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fillcolor&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lightgray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
     &lt;span class=&#34;n&#34;&gt;yaxis&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;frequency&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;sample skewness&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# finally save&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;savefig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;sample_skewness.svg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# for quick viewing and web content&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;savefig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;sample_skewness.tex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# for inclusion into papers&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;savefig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;sample_skewness.pdf&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# for quick viewing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Having generated the plot, I save it in various formats with &lt;code&gt;savefig&lt;/code&gt;. The SVG output is shown below.&lt;/p&gt;



&lt;img src=&#34;../post/plot-workflow/sample_skewness.svg&#34; alt=&#34;The plot&#34;&gt;


&lt;h2 id=&#34;how-to-get-help&#34;&gt;How to get help&lt;/h2&gt;

&lt;p&gt;If you cannot achieve the desired output, you can&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;reread the &lt;a href=&#34;http://docs.juliaplots.org/latest/&#34;&gt;Plots.jl manual&lt;/a&gt;,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;study the &lt;a href=&#34;https://github.com/JuliaPlots/ExamplePlots.jl&#34;&gt;example plots&lt;/a&gt;,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;ask for help in the &lt;a href=&#34;https://discourse.julialang.org/c/domain/viz&#34;&gt;Visualization topic&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the third option, make sure you include a &lt;em&gt;self-contained minimal working example&lt;/em&gt;,&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:You-should-use-t&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:You-should-use-t&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; which also generates or loads the data, so that others can run your code as is. Randomly generated data should be fine, or standard datasets from &lt;a href=&#34;https://github.com/johnmyleswhite/RDatasets.jl&#34;&gt;RDatasets.jl&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sometimes you will find that the feature you are looking for is not (yet) supported. You should check if there is an &lt;a href=&#34;https://github.com/JuliaPlots/Plots.jl/issues&#34;&gt;open issue&lt;/a&gt; for your problem (the discussion forum linked above is useful for this), and if not, open one.&lt;/p&gt;

&lt;p&gt;When asking for help or just discussing plotting libraries in Julia, please keep in mind that they are a community effort with volunteers devoting their time to address a very difficult problem. Plotting is not a well-defined exercise, it involves a lot of heuristics and special cases, and most languages took years to get it right (for a given value of “right”). Make it easy for people to help you by making a reproducible, clean MWE: it is very hard to explain how to improve your plot without the actual code and output.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:Code-in-this-pos&#34;&gt;Code in this post was written in December 2017, you may need to tweak it if the API of the packages changes. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:Code-in-this-pos&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:In-the-worst-cas&#34;&gt;In the worst case scenario, you can always regenerate the data ☺ &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:In-the-worst-cas&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:Note-that-you-ne&#34;&gt;Note that you need a &lt;a href=&#34;https://github.com/sisl/TikzPictures.jl&#34;&gt;working TeX installation&lt;/a&gt;, which is easy to obtain on Linux. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:Note-that-you-ne&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:You-should-use-t&#34;&gt;You should use triple-backticks &lt;code&gt;```&lt;/code&gt; to format your code. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:You-should-use-t&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Checking uncommitted changes when opening a file in Emacs</title>
    <link href="https://tamaspapp.eu/post/check-uncommitted/"/>
    <id>https://tamaspapp.eu/post/check-uncommitted/</id>
    <published>2017-11-18T10:48:30+01:00</published>
    <updated>2017-11-18T10:48:30+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/check-uncommitted/">&lt;p&gt;Alas, the following happens all too frequently: I am working on code, some interruption happens, and I fail to commit the changes coherently into the repository.&lt;/p&gt;

&lt;p&gt;Next time I open the file, perhaps to work on some other feature, I forget that I have &lt;em&gt;uncommitted changes&lt;/em&gt; and work on something new. When staging, I realize the mistake and have to spend time disentangling the mess.&lt;/p&gt;

&lt;p&gt;The following Emacs Lisp snippet takes care of this problem by checking for uncommitted changes and taking me to the &lt;code&gt;magit&lt;/code&gt; popup if there is something I should deal with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cl-defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;tkpapp/check-file-and-popup&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kp&#34;&gt;&amp;amp;optional&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;buffer-file-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;If the file is version controlled with git and has uncommitted
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;changes, open the magit status popup.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;magit-core&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;magit-anything-modified-p&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;magit-status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;find-file-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;tkpapp/check-file-and-popup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title type="html">WIP: making error locations in julia-repl clickable</title>
    <link href="https://tamaspapp.eu/post/wip-julia-repl-clickable/"/>
    <id>https://tamaspapp.eu/post/wip-julia-repl-clickable/</id>
    <published>2017-11-01T12:27:23+01:00</published>
    <updated>2017-11-01T12:27:23+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/wip-julia-repl-clickable/">&lt;p&gt;I scratched a long-standing itch and made locations in error messages &amp;quot;clickable&amp;quot; in &lt;code&gt;julia-repl&lt;/code&gt;. Not yet merged into &lt;code&gt;master&lt;/code&gt;, the change is in the &lt;a href=&#34;https://github.com/tpapp/julia-repl/tree/clickable-locations&#34;&gt;&lt;code&gt;clickable-locations&lt;/code&gt;&lt;/a&gt; branch.&lt;/p&gt;

&lt;p&gt;Testing is needed because of some hacks (again, I am not an Emacs expert), I will see if there are issues then merge it. This is what it looks like, those red and orange lines take you to the source:&lt;/p&gt;

&lt;pre style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;span style=&#34;color: #008b45; background-color: #ded6c5; font-weight: bold;&#34;&gt;julia&amp;gt; &lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;include(&#34;/tmp/Foo.jl&#34;)&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;ERROR: LoadError: UndefVarError: T not defined&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;Stacktrace:&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt; [1] &lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; font-weight: bold;&#34;&gt;include_from_node1(&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;::String&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; font-weight: bold;&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; text-decoration: underline;&#34;&gt;at &lt;/span&gt;&lt;span style=&#34;color: #f71010; font-weight: bold; text-decoration: underline;&#34;&gt;./loading.jl&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; font-weight: bold; text-decoration: underline;&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color: #ef8300; text-decoration: underline;&#34;&gt;576&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt; [2] &lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; font-weight: bold;&#34;&gt;include(&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;::String&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; font-weight: bold;&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; text-decoration: underline;&#34;&gt;at &lt;/span&gt;&lt;span style=&#34;color: #f71010; font-weight: bold; text-decoration: underline;&#34;&gt;./sysimg.jl&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; font-weight: bold; text-decoration: underline;&#34;&gt;:&lt;/span&gt;&lt;span style=&#34;color: #ef8300; text-decoration: underline;&#34;&gt;14&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; text-decoration: underline;&#34;&gt;while loading &lt;/span&gt;&lt;span style=&#34;color: #f71010; font-weight: bold; text-decoration: underline;&#34;&gt;/tmp/Foo.jl&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5; text-decoration: underline;&#34;&gt;, in expression starting on line &lt;/span&gt;&lt;span style=&#34;color: #ef8300; text-decoration: underline;&#34;&gt;9&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;

&lt;/span&gt;&lt;span style=&#34;color: #008b45; background-color: #ded6c5; font-weight: bold;&#34;&gt;julia&amp;gt; &lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;/span&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Working with a large ragged dataset in Julia</title>
    <link href="https://tamaspapp.eu/post/large-ragged-dataset-julia/"/>
    <id>https://tamaspapp.eu/post/large-ragged-dataset-julia/</id>
    <published>2017-10-26T19:14:07+02:00</published>
    <updated>2017-10-26T19:14:07+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/large-ragged-dataset-julia/">&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;One of the projects I am working on at the moment at the &lt;a href=&#34;http://www.ihs.ac.at/research-groups/macroeconomics-and-public-finance/&#34;&gt;Institute for Advanced Studies&lt;/a&gt; (in Vienna) is an analysis of the Austrian Social Security Database. We are using this extremely rich dataset to refine our understanding of the cross-sectional heterogeneity and age structure of employment and labor market participation.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:This-research-is&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:This-research-is&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Naturally, I am using &lt;a href=&#34;https://julialang.org/&#34;&gt;Julia&lt;/a&gt;, not only because it is fast, convenient, and elegant, but also because it allows me to use a &lt;em&gt;single language&lt;/em&gt; for data processing, exploratory data analysis, descriptive statistics, and more sophisticated Bayesian indirect inference using MCMC. When analyzing real-world data, it is useful to do some exploratory plots, fit a simple model, refine, disaggregate, fit a more complex model, and repeat this until I am satisfied with the result. Not having to switch languages is a great bonus.&lt;/p&gt;

&lt;p&gt;In this post I talk about my experience with the very first step of the above process: ingesting and collating a &lt;em&gt;large&lt;/em&gt;, &lt;em&gt;ragged&lt;/em&gt; dataset using Julia. I found that accomplishing this was nontrivial: while the &lt;a href=&#34;https://github.com/JuliaData/DataFrames.jl&#34;&gt;DataFrames.jl&lt;/a&gt; ecosystem is converging nicely, I found that I had to develop some custom tools to work with this dataset. I hope that others in a similar situation find them and this writeup useful.&lt;/p&gt;

&lt;p&gt;I made the resulting libraries available &lt;a href=&#34;https://github.com/tpapp?tab=repositories&#34;&gt;on Github&lt;/a&gt;, with some documentation and lots of unit tests, but they are not finalized since I will probably rewrite some of them once &lt;a href=&#34;https://github.com/JuliaLang/julia/pull/22194&#34;&gt;named tuples&lt;/a&gt; are incorporated into the language. This is not a detailed introduction to any of these libraries, especially since they are subject to change, rather an account of work in progress and some starting points if you want to do something similar. However, if you want to use these libraries, look at the docstrings and the unit tests, and feel free to ask for help, preferably by opening an issue for the relevant library.&lt;/p&gt;

&lt;h2 id=&#34;about-the-data&#34;&gt;About the data&lt;/h2&gt;

&lt;p&gt;The whole data comprises about 2000 million observations on various &amp;quot;spells&amp;quot;, which either involve contributions to or benefits from Austria&#39;s comprehensive social security system (eg being employed, or being on maternity leave). Each spell has the unique ID of the individual it belongs to, a start and end date, and spell information (eg insurance event). They look something like this:&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:The-samples-show&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:The-samples-show&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1;...;19800101;19800201;...;AA;...;
1;...;19800301;19800401;...;B;...;
2;...;19800701;19800901;...;CCC;...;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fields are separated by &lt;code&gt;;&lt;/code&gt;, the &lt;code&gt;...&lt;/code&gt;s are fields which we ignore for now (we may use them later). Dates have the &lt;code&gt;yyyymmdd&lt;/code&gt; format. There are about 70 spell types.&lt;/p&gt;

&lt;p&gt;Gzipped data in delimited format is about 45 GB, raw data would be over 500 GB. Data for each year is in a separate file, so individual &lt;code&gt;1&lt;/code&gt; may have spells scattered in multiple files. Ideally, for our analysis, we would like to end up with a data structure that has the spells organized by individual, eg&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;individual &lt;code&gt;1&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;start date &lt;code&gt;1980-01-01&lt;/code&gt;, end date &lt;code&gt;1980-02-01&lt;/code&gt;, spell type &lt;code&gt;AA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;start date &lt;code&gt;1980-03-01&lt;/code&gt;, end date &lt;code&gt;1980-04-01&lt;/code&gt;, spell type &lt;code&gt;B&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;... other spells from subsequent files&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;individual &lt;code&gt;2&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The number of spells varies by individual, which makes this dataset &lt;em&gt;ragged&lt;/em&gt;.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:Irregular-and-no&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:Irregular-and-no&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h2 id=&#34;rationale-for-custom-tools&#34;&gt;Rationale for custom tools&lt;/h2&gt;

&lt;p&gt;A simple back of the envelope calculation is useful to think about the size of the dataset. If we encode each column as an &lt;code&gt;Int64&lt;/code&gt; or similar (eg &lt;code&gt;Date&lt;/code&gt;), we use&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[8 \text{ bytes} \times 2 \cdot 10^9 \approx 16 \text{ gigabytes}\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;per column&lt;/em&gt;. For 4 columns, this would use up 64 GB, plus some extra for keeping track of the ragged structure. While this is feasible if we have enough RAM, it is very nice to use smaller machines (especially laptops — I am typing this on the train) for exploratory data work.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:We-also-used-a-s&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:We-also-used-a-s&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; Also, economizing on RAM speeds up the calculations, as more data fits into the CPU cache.&lt;/p&gt;

&lt;p&gt;Early experiments suggested that simply reading this data into native Julia structures or tools in the &lt;a href=&#34;https://github.com/JuliaData/DataFrames.jl&#34;&gt;&lt;code&gt;DataFrames.jl&lt;/code&gt;&lt;/a&gt; ecosystem is either infeasible or unnecessarily slow. I also considered databases, but found them to be more trouble than it is worth, especially since what I am doing below is straightforward and fits into Julia very nicely.&lt;/p&gt;

&lt;p&gt;Below, I discuss the key ingredients I used to process this dataset.&lt;/p&gt;

&lt;h2 id=&#34;mmapping-large-columns&#34;&gt;Mmapping large columns&lt;/h2&gt;

&lt;p&gt;Julia supports &lt;a href=&#34;https://en.wikipedia.org/wiki/Memory-mapped_file&#34;&gt;memory
mapped&lt;/a&gt; arrays, which map virtual memory to disk seamlessly, allowing lazy loading and access managed by the virtual memory manager. Using
the syntax&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;io&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;path_to_file.bin&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;w+&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# create, truncate&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Mmap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mmap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# map to array&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;gives you a vector that is mapped to the disk (you have to call &lt;code&gt;Mmap.sync!&lt;/code&gt; after you are finished to make sure, and you have to use &lt;code&gt;growth = true&lt;/code&gt;, which is the default). The advantage is that the size of the array is limited by the disk space, not RAM, and the OS takes care of reading, writing, and caching as necessary.&lt;/p&gt;

&lt;p&gt;A complication for our data analysis is that we do not know the total number of elements before having read the whole dataset, so we can&#39;t specify the dimensions above. Fortunately, simply opening a stream and &lt;code&gt;write&lt;/code&gt;ing values of bits types works fine.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:Currently-needs&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:Currently-needs&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;I packaged the code for managing columns of bits types using the strategies above in &lt;a href=&#34;https://github.com/tpapp/LargeColumns.jl&#34;&gt;&lt;code&gt;LargeColumns.jl&lt;/code&gt;&lt;/a&gt;, which keeps track of column types and imposing some basic sanity checks. This makes working with large vectors as easy as&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LargeColumns&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;cols&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MmappedColumns&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;path/to/directory&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2_000_000_000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which takes care of &lt;code&gt;mmap&lt;/code&gt;ing, and makes &lt;code&gt;cols&lt;/code&gt; behave as a vector of tuples of the given type. The files, including metadata, are located in the given directory.&lt;/p&gt;

&lt;h2 id=&#34;ragged-data-and-collation&#34;&gt;Ragged data and collation&lt;/h2&gt;

&lt;p&gt;I want to end up with data grouped by individuals contiguously, eg&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 1 1 1 2 2 2 3 3 4 4 ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;where the first 4 observations belong to individual &lt;code&gt;1&lt;/code&gt;, the second 3 to &lt;code&gt;2&lt;/code&gt;, and so on. This can be indexed with &lt;code&gt;UnitRange&lt;/code&gt;s: for individual &lt;code&gt;1&lt;/code&gt; we would use &lt;code&gt;1:4&lt;/code&gt;, for &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;5:8&lt;/code&gt;, etc. Note that storage of both endpoints is unnecessary, since they can be calculated from a cumulative sum, also, we can reuse the same index for multiple columns.&lt;/p&gt;

&lt;p&gt;The package &lt;a href=&#34;https://github.com/tpapp/RaggedData.jl&#34;&gt;&lt;code&gt;RaggedData.jl&lt;/code&gt;&lt;/a&gt; implements simple datastructures for counting, collating, and indexing ragged data into vectors. When I first parse and ingest the data, I count the number of observations for each individual:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;id_counter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RaggedCounter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Int32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# process by line&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_id_from_line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;push!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id_counter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then in the second pass, I start with the index for the first observation for each (eg &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;5&lt;/code&gt;, &lt;code&gt;9&lt;/code&gt; above), and increment it for each row of the data. So the first observation for individual &lt;code&gt;2&lt;/code&gt; goes to index &lt;code&gt;5&lt;/code&gt;, the second &lt;code&gt;6&lt;/code&gt;, and so on. For this, I create a collator object &lt;code&gt;coll&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;coll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;collate_index_keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id_counter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;indices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;first_pass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spell_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dates&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first_pass&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;j&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;next_index!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;coll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;collated&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;j&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;spell_index&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;where &lt;code&gt;collated&lt;/code&gt; is another set of &lt;code&gt;mmap&lt;/code&gt;ed columns. &lt;code&gt;ix&lt;/code&gt; is used later for indexing into the result: &lt;code&gt;ix[1]&lt;/code&gt; gives the &lt;code&gt;UnitRange&lt;/code&gt; for the observations about the first individual, and so on.&lt;/p&gt;

&lt;h2 id=&#34;saving-space&#34;&gt;Saving space&lt;/h2&gt;

&lt;p&gt;Before processing the whole dataset, I assumed that the individual ids fit into &lt;code&gt;Int32&lt;/code&gt;s. This is easy to verify after parsing, with the standard constructor, which simply throws an error if the value does not fit:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Int32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;typemax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;InexactError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Stacktrace&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
 &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Int32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;at&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;./&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sysimg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;77&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For the spell types, I simply indexed them in the order of appearance, saving the index as an &lt;code&gt;Int8&lt;/code&gt;. They are reconstructed using &lt;a href=&#34;https://github.com/JuliaArrays/IndirectArrays.jl&#34;&gt;&lt;code&gt;IndirectArrays.jl&lt;/code&gt;&lt;/a&gt; when working with the data.&lt;/p&gt;

&lt;p&gt;Dates turned out to be the trickiest, until I realized that using &lt;code&gt;Int16&lt;/code&gt;, I can represent a timespan of about 179 years, which is a lot more than I need for this data. Of course, this requires that we count from some epoch other than &lt;code&gt;0001-01-01&lt;/code&gt; like &lt;code&gt;Base.Date&lt;/code&gt;. Fortunately, Julia allows encoding the epoch in the type, making it costless as long as I use it consistently for the same dataset. The package &lt;a href=&#34;https://github.com/tpapp/FlexDates.jl&#34;&gt;&lt;code&gt;FlexDates.jl&lt;/code&gt;&lt;/a&gt; implements this approach.&lt;/p&gt;

&lt;h2 id=&#34;parsing&#34;&gt;Parsing&lt;/h2&gt;

&lt;p&gt;Being very impressed by the amazing speed gains for date parsing in Julia (see &lt;a href=&#34;https://github.com/JuliaLang/julia/pull/18000&#34;&gt;#18000&lt;/a&gt;, &lt;a href=&#34;https://github.com/JuliaLang/julia/issues/15888&#34;&gt;#15888&lt;/a&gt;, &lt;a href=&#34;https://github.com/JuliaLang/julia/pull/19545&#34;&gt;#19545&lt;/a&gt;), I used this project as an excuse to experiment with parsers. Existing packages like &lt;a href=&#34;https://github.com/JuliaComputing/TextParse.jl&#34;&gt;&lt;code&gt;TextParse.jl&lt;/code&gt;&lt;/a&gt; are already so fast that writing yet another parser library would not have made sense for a small amount of data, but since I plan to reuse this code for large datasets I felt the investment was justified.&lt;/p&gt;

&lt;p&gt;Most of the datasets I work with are ASCII: other character sets are still very rare in social science data, since data is predominantly anonymous (so no names), categorical variables are usually encoded as short strings or integers, and the rest are numbers and punctuation. Moreover, delimited &lt;a href=&#34;https://en.wikipedia.org/wiki/UTF-8&#34;&gt;UTF-8&lt;/a&gt; can be parsed as ASCII &lt;em&gt;when the delimiters themselves are ASCII&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For this dataset, I was also free to ignore quotes and within-field linebreaks, since they do not occur in the data dumps. Given these, I was free to parse this dataset as ASCII, ie &lt;code&gt;UInt8&lt;/code&gt; (bytes). The algorithms are very simple: parse a given number of characters (eg as numbers), or stop when hitting a delimiter.&lt;/p&gt;

&lt;p&gt;Since I ignore some fields, I also needed functionality to simply &lt;em&gt;skip&lt;/em&gt; to the next delimiter, returning nothing (but the position for the next byte after the delimiter) — this takes about 25–30% of the time, compared to parsing it. The result is packaged as &lt;a href=&#34;https://github.com/tpapp/ByteParsers.jl&#34;&gt;&lt;code&gt;ByteParsers.jl&lt;/code&gt;&lt;/a&gt;. Parsing using ASCII turns out to be 30%–120% faster than UTF-8.&lt;/p&gt;

&lt;h2 id=&#34;putting-it-all-together&#34;&gt;Putting it all together&lt;/h2&gt;

&lt;p&gt;I use three passes to process the data.&lt;/p&gt;

&lt;h3 id=&#34;first-pass&#34;&gt;First pass&lt;/h3&gt;

&lt;p&gt;The first pass parses the data and writes it out in a binary format, also counting observations for each individual at the same time. Categorical data is indexed in the order of appearance and written out as an &lt;code&gt;Int8&lt;/code&gt;, dates are written using &lt;a href=&#34;https://github.com/tpapp/FlexDates.jl&#34;&gt;&lt;code&gt;FlexDate{Date(2000, 1, 1), Int16}&lt;/code&gt;&lt;/a&gt;, represented with 16 bits.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the gzipped files using &lt;a href=&#34;https://github.com/bicycle1885/CodecZlib.jl&#34;&gt;&lt;code&gt;CodecZlib.jl&lt;/code&gt;&lt;/a&gt;. Open sinks for binary data using &lt;a href=&#34;https://github.com/tpapp/LargeColumns.jl&#34;&gt;&lt;code&gt;LargeColumns.jl&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Read and parsed them line by line, using &lt;a href=&#34;https://github.com/tpapp/ByteParsers.jl&#34;&gt;&lt;code&gt;ByteParsers.jl&lt;/code&gt;&lt;/a&gt;. You can also use &lt;a href=&#34;https://github.com/JuliaComputing/TextParse.jl&#34;&gt;&lt;code&gt;TextParse.jl&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Write the parsed data into the sinks, at the same time counting with a &lt;code&gt;RaggedCounter&lt;/code&gt; from &lt;a href=&#34;https://github.com/tpapp/RaggedData.jl&#34;&gt;&lt;code&gt;RaggedData.jl&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Close the streams, write the categorical values and the &lt;code&gt;RaggedCounter&lt;/code&gt; using &lt;a href=&#34;https://github.com/simonster/JLD2.jl&#34;&gt;&lt;code&gt;JLD2.jl&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The whole process takes about 90 minutes, and generates 18 GB of binary data.&lt;/p&gt;

&lt;h3 id=&#34;second-pass&#34;&gt;Second pass&lt;/h3&gt;

&lt;p&gt;The second pass reads back the binary dump from the first pass using &lt;code&gt;mmap&lt;/code&gt;, and collates observations for the individuals it using a &lt;code&gt;RaggedCollate&lt;/code&gt; indexer from &lt;code&gt;RaggedData.jl&lt;/code&gt;. The latter is an object which keeps track of where observations should end up, if their counts are consistent with the first pass. The result is written using &lt;code&gt;LargeColumns.jl&lt;/code&gt; into &lt;code&gt;mmap&lt;/code&gt;ped columns, and it is reasonably fast, taking about 30–80 minutes, depending on the RAM size (the non-contiguous collating process has to use the disk if the resulting large vectors cannot fit in RAM). Finally, the &lt;code&gt;RaggedIndex&lt;/code&gt; object is written out using &lt;code&gt;JLD2&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&#34;third-pass&#34;&gt;Third pass&lt;/h3&gt;

&lt;p&gt;The third pass is optional, it sorts spells by the start date for each individual (we found this helps the kind of analysis we perform). It uses the &lt;code&gt;mmap&lt;/code&gt;ed columns from the second pass, and takes about 2 minutes (since the data is accessed almost linearly).&lt;/p&gt;

&lt;h3 id=&#34;using-the-data&#34;&gt;Using the data&lt;/h3&gt;

&lt;p&gt;The columns are &lt;code&gt;mmap&lt;/code&gt;ped using &lt;a href=&#34;https://github.com/tpapp/LargeColumns.jl&#34;&gt;&lt;code&gt;LargeColumns.jl&lt;/code&gt;&lt;/a&gt;. &lt;a href=&#34;https://github.com/JuliaArrays/IndirectArrays.jl&#34;&gt;&lt;code&gt;IndirectArrays.jl&lt;/code&gt;&lt;/a&gt; is used to reconstitute categorical data with the keys previously saved, and the resulting vector is wrapped in a ragged access data structure using &lt;code&gt;RaggedColumns&lt;/code&gt; (from &lt;code&gt;RaggedData.jl&lt;/code&gt;) and the previously saved index. Iterating through the dataset takes about 2 minutes.&lt;/p&gt;

&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Ingesting and working with large amounts of data turns out to be very simple and convenient using &lt;code&gt;mmap&lt;/code&gt;ed arrays in Julia. I packaged the code into libraries because&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I like to have unit test, especially if I keep benchmarking and optimizing,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;It simplifies code and communication for colleagues I am cooperating with,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;May be useful in future projects,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;I find packaged code with continuous integration tests closer to
the idea of reproducible research.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I plan to register some of these libraries in the future (when the interface stabilizes).&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:This-research-is&#34;&gt;This research is supported by the Austrian National Bank Jubiläumsfonds grant #17378. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:This-research-is&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:The-samples-show&#34;&gt;The samples shown here are made up, the actual dataset is not public. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:The-samples-show&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:Irregular-and-no&#34;&gt;&lt;em&gt;Irregular&lt;/em&gt; and &lt;em&gt;non-rectangular&lt;/em&gt; are also used. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:Irregular-and-no&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:We-also-used-a-s&#34;&gt;We also used a subset of the data for initial work. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:We-also-used-a-s&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:Currently-needs&#34;&gt;Currently needs a workaround for which I submitted a &lt;a href=&#34;https://github.com/JuliaLang/julia/pull/24234&#34;&gt;PR&lt;/a&gt;. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:Currently-needs&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">My Julia workflow</title>
    <link href="https://tamaspapp.eu/post/julia-workflow/"/>
    <id>https://tamaspapp.eu/post/julia-workflow/</id>
    <published>2017-10-21T12:40:04+02:00</published>
    <updated>2017-10-21T12:40:04+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/julia-workflow/">&lt;p&gt;(&lt;strong&gt;edit&lt;/strong&gt; 2017-10-22: fixed path for &lt;code&gt;PkgDev.generate&lt;/code&gt; example)&lt;/p&gt;

&lt;p&gt;This is a summary of the workflow I find ideal for working with Julia. Although the manual has a &lt;a href=&#34;https://docs.julialang.org/en/latest/manual/workflow-tips/&#34;&gt;section on workflow&lt;/a&gt;, it does not mention all the tools that I find useful, so perhaps this will benefit some users of Julia.&lt;/p&gt;

&lt;p&gt;I use Emacs, with &lt;a href=&#34;https://github.com/JuliaEditorSupport/julia-emacs&#34;&gt;&lt;code&gt;julia-mode&lt;/code&gt;&lt;/a&gt; (for editing the source) and &lt;a href=&#34;https://github.com/tpapp/julia-repl&#34;&gt;&lt;code&gt;julia-repl&lt;/code&gt;&lt;/a&gt; (REPL integration). The latter is my own package; you can use &lt;a href=&#34;https://ess.r-project.org/&#34;&gt;&lt;code&gt;ESS&lt;/code&gt;&lt;/a&gt; instead, which has some advantages (eg multiple inferior processes) and disadvantages (no ANSI terminal support). The choice of an editor is highly subjective: at the end of the day, all you need is one that is capable of sending code to the REPL and can, in turn, be used by the REPL to open a file at a particular point. I use&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;nb&#34;&gt;ENV&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;EDITOR&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;emacsclient&amp;#34;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;in &lt;code&gt;~/.juliarc.jl&lt;/code&gt; to ensure this. This helps me find code with the &lt;code&gt;@edit&lt;/code&gt; macro.&lt;/p&gt;

&lt;p&gt;Small code snippets and experiments below ~30 lines just go into files, from which I send regions of code to the REPL. Frequently, for throwaway code, I just open a file in &lt;code&gt;/tmp/&lt;/code&gt;, which will get removed automatically after the next reboot.&lt;/p&gt;

&lt;p&gt;Even very small projects get their own &lt;a href=&#34;https://docs.julialang.org/en/latest/manual/packages/&#34;&gt;package&lt;/a&gt;. This way I get version control&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:I-use-the-amazin&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:I-use-the-amazin&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and a sensible structure for unit tests set up automatically. I put my own packages in their own directory, &lt;em&gt;keeping them separate from &lt;code&gt;Pkg.dir()&lt;/code&gt;&lt;/em&gt;. This allows me to use the same package across Julia versions, and makes &lt;code&gt;Pkg.update()&lt;/code&gt; ignore them. I tell Julia where they are with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LOCAL_PACKAGES&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expanduser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;~/src/julia-local-packages/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;push!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;LOAD_PATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LOCAL_PACKAGES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I create local packages with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PkgDev&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;PkgDev&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;MyPkg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;MIT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LOCAL_PACKAGES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then I open the file and start working on it with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MyPkg&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I use &lt;a href=&#34;https://github.com/timholy/Revise.jl&#34;&gt;&lt;code&gt;Revise.jl&lt;/code&gt;&lt;/a&gt; to automate reloading.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:You-just-need-to&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:You-just-need-to&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; This package has changed my workflow completely; it can cope with most changes, except for type redefinitions. For these, I need to restart the REPL.&lt;/p&gt;

&lt;p&gt;To test my code, I use &lt;code&gt;Pkg.test&lt;/code&gt; with &lt;a href=&#34;https://github.com/tpapp/RoguePkg.jl&#34;&gt;&lt;code&gt;RoguePkg.jl&lt;/code&gt;&lt;/a&gt;, which makes it find packages outside &lt;code&gt;Pkg.dir()&lt;/code&gt; for testing and benchmarks:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pkg_for&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;MyPkg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:I-use-the-amazin&#34;&gt;I use the amazing &lt;a href=&#34;https://magit.vc/&#34;&gt;&lt;code&gt;magit&lt;/code&gt;&lt;/a&gt; for interacting with &lt;code&gt;git&lt;/code&gt; &amp;mdash; having obtained &lt;a href=&#34;https://www.kickstarter.com/projects/1681258897/its-magit-the-magical-git-client&#34;&gt;funding on KickStarter&lt;/a&gt; recently, it is bound to become even more convenient. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:I-use-the-amazin&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:You-just-need-to&#34;&gt;You just need to set it up once according to its documentation, after that it is automatic. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:You-just-need-to&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">HTML &amp;#34;screenshots&amp;#34; from Emacs</title>
    <link href="https://tamaspapp.eu/post/htmlize-screenshot/"/>
    <id>https://tamaspapp.eu/post/htmlize-screenshot/</id>
    <published>2017-10-17T13:26:04+02:00</published>
    <updated>2017-10-17T13:26:04+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/htmlize-screenshot/">&lt;p&gt;&lt;a href=&#34;https://github.com/hniksic/emacs-htmlize&#34;&gt;&lt;code&gt;htmlize&lt;/code&gt;&lt;/a&gt;, written by Hrvoje Nikšić, is a neat little Emacs package that converts face information from an Emacs buffer (or region) into HTML, effectively allowing the verbatim reproduction of what it looks like.&lt;/p&gt;

&lt;p&gt;I found this so useful for blogging that I submitted a PR which saves marked up regions as self-contained &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; snippets, complete with inline CSS. Hrvoje kindly merged the PR today, so now you can call &lt;code&gt;htmlize-region-save-screenshot&lt;/code&gt; and the result will be saved into the kill ring. You can paste this into, say, a blog post written in Markdown or &lt;a href=&#34;https://github.com/miekg/mmark&#34;&gt;Mmark&lt;/a&gt;, such as this one, and get a &amp;quot;screenshot&amp;quot; like&lt;/p&gt;

&lt;pre style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;defun&lt;/span&gt; &lt;span style=&#34;color: #2c53ca;&#34;&gt;htmlize-region-save-screenshot&lt;/span&gt; &lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;beg end&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;
  &lt;span style=&#34;color: #505050; font-style: italic;&#34;&gt;&#34;Save the htmlized (see `&lt;/span&gt;&lt;span style=&#34;color: #259ea2; font-style: italic;&#34;&gt;htmlize-region-for-paste&lt;/span&gt;&lt;span style=&#34;color: #505050; font-style: italic;&#34;&gt;&#39;) region in
the kill ring. Uses `&lt;/span&gt;&lt;span style=&#34;color: #259ea2; font-style: italic;&#34;&gt;inline-css&lt;/span&gt;&lt;span style=&#34;color: #505050; font-style: italic;&#34;&gt;&#39;, with style information in
`&lt;/span&gt;&lt;span style=&#34;color: #259ea2; font-style: italic;&#34;&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;&lt;span style=&#34;color: #505050; font-style: italic;&#34;&gt;&#39; tags, so that the rendering of the marked up text
approximates the buffer as closely as possible.&#34;&lt;/span&gt;
  &lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;interactive&lt;/span&gt; &lt;span style=&#34;color: #fa5151;&#34;&gt;&#34;r&#34;&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;
  &lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;let&lt;/span&gt; &lt;span style=&#34;color: #262626;&#34;&gt;((&lt;/span&gt;htmlize-pre-style t&lt;span style=&#34;color: #262626;&#34;&gt;))&lt;/span&gt;
    &lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;kill-new &lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;htmlize-region-for-paste beg end&lt;span style=&#34;color: #262626;&#34;&gt;)))&lt;/span&gt;
  &lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;deactivate-mark&lt;span style=&#34;color: #262626;&#34;&gt;))&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;which is &lt;em&gt;almost&lt;/em&gt; exactly what it looks like on my screen when it comes to colors and font style/weight, but using a different font of course. This allows integration of Emacs &amp;quot;screenshots&amp;quot; into blog posts without resorting to pixel-based formats, which would result from taking actual screenshots.&lt;/p&gt;

&lt;p&gt;You can install &lt;code&gt;htmlize&lt;/code&gt; from &lt;a href=&#34;https://melpa.org/&#34;&gt;MELPA&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Switching from Common Lisp to Julia</title>
    <link href="https://tamaspapp.eu/post/common-lisp-to-julia/"/>
    <id>https://tamaspapp.eu/post/common-lisp-to-julia/</id>
    <published>2017-10-15T14:17:47+02:00</published>
    <updated>2017-10-15T14:17:47+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/common-lisp-to-julia/">&lt;p&gt;I have written this post for developers in the Common Lisp community who asked why I am switching to Julia. It may only be relevant for the small set of people who use Common Lisp for scientific computing.&lt;/p&gt;

&lt;p&gt;I used Common Lisp for scientific computing for a while, from 2008 to about 2015, in combination with R and C++. This choice may surprise people who don&#39;t know about projects like &lt;a href=&#34;https://en.wikipedia.org/wiki/Maxima_(software)&#34;&gt;Maxima&lt;/a&gt; or &lt;a href=&#34;http://www.femlisp.org/&#34;&gt;FEMLISP&lt;/a&gt;, but Common Lisp is not a bad language for &lt;a href=&#34;https://link.springer.com/chapter/10.1007/978-3-642-19014-8_11&#34;&gt;scientific computing&lt;/a&gt;: it has a great FFI, compilers like &lt;a href=&#34;http://sbcl.org/&#34;&gt;SBCL&lt;/a&gt; can generate very fast code with a few hints, and the language itself is composed of convenient features that interact nicely.&lt;/p&gt;

&lt;p&gt;However, around 2012 I started to become very frustrated with Common Lisp. Despite various attempts, it became very clear that libraries for scientific computing were not goint to take off: there were many one-person efforts (including &lt;a href=&#34;https://tamaspapp.eu/post/orphaned-lisp-libraries/&#34;&gt;mine&lt;/a&gt;), but very few of them evolved into general tools.&lt;/p&gt;

&lt;p&gt;Initially, I was puzzled by this: Common Lisp is an extremely convenient and productive language. Experienced Lisp hackers can write very complex, fast, and elegant libraries in reasonably short time. Why did this not happen for numerical code?&lt;/p&gt;

&lt;h1 id=&#34;the-problem-with-common-lisp&#34;&gt;The problem with Common Lisp&lt;/h1&gt;

&lt;p&gt;Now I think that one of the main reasons for this is that while you can write scientific code in CL that will be (1) fast, (2) portable, and (3) convenient, you &lt;em&gt;cannot do all of these at the same time&lt;/em&gt;. Arrays provide a convenient example for this.&lt;/p&gt;

&lt;p&gt;Consider&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;make-array&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:element-type&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;double-float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;a href=&#34;http://clhs.lisp.se/Body/f_upgr_1.htm&#34;&gt;standard&lt;/a&gt; does not guarantee that this gives you an array of &lt;code&gt;double-float&lt;/code&gt;: it may (if the implementation provides them), otherwise you get an array of element type &lt;code&gt;T&lt;/code&gt;. This turned out to be a major difficulty for implementing portable scientific code in Common Lisp.&lt;/p&gt;

&lt;p&gt;However, this gets worse: while you can tell a function that operates on arrays that these arrays have element type &lt;code&gt;double-float&lt;/code&gt;, you cannot dispatch on this, as Common Lisp does not have parametric types. For example, if you want to write a sum as&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defmethod&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mysum&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;vec&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;loop&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;elt&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;across&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;vec&lt;/span&gt;
       &lt;span class=&#34;nb&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;incf&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;elt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;you can dispatch on the argument being a &lt;code&gt;vector&lt;/code&gt;, but not on the element type. The compiled code may be generic.&lt;/p&gt;

&lt;p&gt;You can of course branch on the array element types and maybe even paper over the whole mess with sufficient macrology (which is what &lt;a href=&#34;https://github.com/tpapp/lla&#34;&gt;LLA&lt;/a&gt; ended up doing), but this approach is not very extensible, as eventually you end up hardcoding a few special types for which your functions will be &amp;quot;fast&amp;quot;, otherwise they have to fall back to a generic, boxed type. With multiple arguments, the number of combinations explodes very quickly.&lt;/p&gt;

&lt;h1 id=&#34;how-julia-solves-this-problem&#34;&gt;How Julia solves this problem&lt;/h1&gt;

&lt;p&gt;A comparable native implementation in Julia would be&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:This-is-not-the&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:This-is-not-the&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mysum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;AbstractVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;where&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is still generic: it works for all subtypes of &lt;code&gt;AbstractVector&lt;/code&gt; (including vectors and vector-like objects), but notice how the generated code is conditional on the element type:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@code_warntype&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mysum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Variables&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
  &lt;span class=&#34;c&#34;&gt;#self#::#mysum&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;
  &lt;span class=&#34;c&#34;&gt;#temp#::Int64&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;Body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;begin&lt;/span&gt; 
      &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# line 3:&lt;/span&gt;
      &lt;span class=&#34;c&#34;&gt;#temp#::Int64 = 1&lt;/span&gt;
      &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; 
      &lt;span class=&#34;n&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;not_int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)((&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#temp#::Int64 === (Base.add_int)((Base.arraylen)(vec::Array{Int64,1&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Bool&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;goto&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;                                                     
      &lt;span class=&#34;n&#34;&gt;SSAValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arrayref&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;#temp#::Int64)::Int64&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;SSAValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#temp#::Int64, 1)::Int64&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SSAValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;c&#34;&gt;#temp#::Int64 = SSAValue(3) # line 4:&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;
      &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; 
      &lt;span class=&#34;n&#34;&gt;goto&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;
      &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# line 6:&lt;/span&gt;
      &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@code_warntype&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mysum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Variables&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
  &lt;span class=&#34;c&#34;&gt;#self#::#mysum&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;
  &lt;span class=&#34;c&#34;&gt;#temp#::Int64&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;Body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;begin&lt;/span&gt; 
      &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sitofp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# line 3:&lt;/span&gt;
      &lt;span class=&#34;c&#34;&gt;#temp#::Int64 = 1&lt;/span&gt;
      &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; 
      &lt;span class=&#34;n&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;not_int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)((&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#temp#::Int64 === (Base.add_int)((Base.arraylen)(vec::Array{Float64&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Bool&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;goto&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;                                                   
      &lt;span class=&#34;n&#34;&gt;SSAValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;arrayref&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;#temp#::Int64)::Float64&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;SSAValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;#temp#::Int64, 1)::Int64&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SSAValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;c&#34;&gt;#temp#::Int64 = SSAValue(3) # line 4:&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_float&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;
      &lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; 
      &lt;span class=&#34;n&#34;&gt;goto&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;
      &lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# line 6:&lt;/span&gt;
      &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;
  &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I mentioned &amp;quot;vector-like objects&amp;quot; above, since I can choose different representations for special objects. For example, to do calculations with a vector of &lt;code&gt;1&lt;/code&gt;s, I can define&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Ones&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;AbstractVector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this point, in order to calculate the sum above, I have two choices:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implement the &lt;a href=&#34;https://docs.julialang.org/en/latest/manual/interfaces/&#34;&gt;relevant interface&lt;/a&gt;, with functions like&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ones&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and similarly for element access, etc. This would generate specialized code for the method above, reasonably efficient code, but still iterate over the &amp;quot;elements&amp;quot;.&lt;/p&gt;

&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;In addition, I can define&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;mysum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Ones&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;where&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;one&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which would provide a method for &lt;code&gt;mysum&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A sufficiently rich parametric type system with multiple dispatch integrated into the language and supported by a JIT compiler is the secret weapon of Julia. Most of the time, &lt;em&gt;you don&#39;t have to do anything&lt;/em&gt;, as it happens automatically for concrete types. Sometimes, you have to help the compiler a bit, by writing code where the result is &lt;a href=&#34;https://docs.julialang.org/en/latest/manual/performance-tips/#Write-%22type-stable%22-functions-1&#34;&gt;type stable&lt;/a&gt;, ie the result type just depends on the type (not the value) of the arguments and can be inferred by the compiler. Sometimes you have to nudge the compiler a bit, and sometimes you have to be careful not to mess up type inference: for example, the &lt;code&gt;zero(T)&lt;/code&gt; above gives a &lt;code&gt;0&lt;/code&gt; of type &lt;code&gt;T&lt;/code&gt;, always ensuring a correct type that does not change during the summation.&lt;/p&gt;

&lt;h1 id=&#34;comparison-of-other-language-features&#34;&gt;Comparison of other language features&lt;/h1&gt;

&lt;p&gt;While I would say that multiple dispatch with parametric types designed into the language from the ground up is the most important feature of Julia, there are other language features worth comparing to Common Lisp.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://docs.julialang.org/en/latest/manual/metaprogramming/&#34;&gt;Metaprogramming&lt;/a&gt; is supported. Because of infix syntax, the AST is not as simple as S-expressions, but the tools to work with it are evolving fast. That said, I don&#39;t write as many macros as I did in Common Lisp. Parametric types are so powerful that I rarely need macros for performance reasons, and instead of syntax extensions, I often go for zero-cost abstraction via functions and wrapper types. An interesting metaprogramming tool in Julia is &lt;a href=&#34;https://docs.julialang.org/en/latest/manual/metaprogramming/#Generated-functions-1&#34;&gt;generated functions&lt;/a&gt;, which allow code generation based on argument templates, I use this frequently. The equivalent of reader macros are called &lt;a href=&#34;https://docs.julialang.org/en/latest/manual/metaprogramming/#Non-Standard-String-Literals-1&#34;&gt;non-standard string literals&lt;/a&gt; in Julia.&lt;/p&gt;

&lt;p&gt;The foreign function interface of Julia is seamlessly integrated into the language and very convenient to use. Docstrings are almost the same as in Common Lisp, but they support Markdown. Strings are UTF8 by default, and very fast. The &lt;a href=&#34;https://discourse.julialang.org/&#34;&gt;community&lt;/a&gt; is very vibrant, open, and helpful. Simple questions get an answer within minutes, complicated ones (eg compiler internals) may take a bit longer, but are usually answered within a few hours or a day at most. If you are coming from the Common Lisp community, you will see quite a few familiar faces.&lt;/p&gt;

&lt;p&gt;The library ecosystem already surpasses that of Common Lisp, at least for scientific programming. High-quality, well-tested code is available for linear algebra including sparse matrices (most of it in the standard library), optimization, differential equations, and automatic differentiation. The &lt;a href=&#34;http://www.juliadiff.org/ForwardDiff.jl/stable/&#34;&gt;latter&lt;/a&gt; is simply amazing: by providing a type for dual numbers and a few operations, forward-mode AD can be used without any implementation overhead. Plotting libraries are available (mostly using foreign function backends), and R-like &amp;quot;dataframes&amp;quot; are under development.&lt;/p&gt;

&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Common Lisp has been and remains a great language, with many excellent features that preceded other languages by decades. It has an ANSI standard, which means that portable code written decades ago will run on a recent implementation. This is a great advantage, but at the same time this freezes the language development at the point the standard was finalized. No matter how flexible and forward-looking it is, it cannot predict and accommodate all possible advances for decades.&lt;/p&gt;

&lt;p&gt;In contrast, Julia is rapidly evolving. At this stage, code that was written half a year ago is very likely to be broken with the most recent release.&lt;sup class=&#34;footnote-ref&#34; id=&#34;fnref:An-elegant-depre&#34;&gt;&lt;a class=&#34;footnote&#34; href=&#34;#fn:An-elegant-depre&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; The pace of change will most likely slow down a bit after 1.0 is released, but for now, expect a lot of churning.&lt;/p&gt;

&lt;p&gt;On the other hand, programmers who used Common Lisp for scientific computing have always expected to get their hands dirty, since so little existing code was available. This is a good time to consider investing into Julia instead: you will get more done with less work, and you still get to program in a very elegant language that traces a lot of its roots to the Lisp family.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34;&gt;

&lt;hr&gt;

&lt;ol&gt;
&lt;li id=&#34;fn:This-is-not-the&#34;&gt;This is not the fastest, nor the most precise implementation, just a comparable example. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:This-is-not-the&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li id=&#34;fn:An-elegant-depre&#34;&gt;An elegant &lt;a href=&#34;https://github.com/JuliaLang/Compat.jl&#34;&gt;deprecation mechanism&lt;/a&gt; is available, but that can&#39;t deal with some fundamental language changes. &lt;a class=&#34;footnote-return&#34; href=&#34;#fnref:An-elegant-depre&#34;&gt;&lt;sup&gt;[return]&lt;/sup&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Clarification: on orphaning my Common Lisp libraries</title>
    <link href="https://tamaspapp.eu/post/orphaned-lisp-libraries/"/>
    <id>https://tamaspapp.eu/post/orphaned-lisp-libraries/</id>
    <published>2017-10-15T13:02:14+02:00</published>
    <updated>2017-10-15T13:02:14+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/orphaned-lisp-libraries/">&lt;p&gt;I have not been programming in Common Lisp for a few years, and since I find &lt;a href=&#34;https://julialang.org/&#34;&gt;Julia&lt;/a&gt; a &amp;quot;much better Lisp&amp;quot;, I am unlikely to go back to it in the foreseeable future. This is a clarification regarding some &lt;a href=&#34;https://github.com/tpapp?utf8=%E2%9C%93&amp;amp;tab=repositories&amp;amp;q=&amp;amp;type=public&amp;amp;language=common%20lisp&#34;&gt;libraries&lt;/a&gt; I have written in Common Lisp and made public.&lt;/p&gt;

&lt;h1 id=&#34;all-of-my-common-lisp-libraries-are-orphaned&#34;&gt;All of my Common Lisp libraries are orphaned&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;They are effectively &lt;em&gt;abandonware&lt;/em&gt; as far as I am concerned. Since fixing issues and evaluating PRs entails a large fixed cost for which I don&#39;t have the time (setting up my CL environment again, understanding what I wrote years ago, thinking about code correctness and corner cases of the language spec that I have forgotten), I will ignore issues and pull requests. Sorry about this.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;If you find anything of value in these libraries, please feel free to use that according to their licenses. &lt;em&gt;You don&#39;t have to ask me explicitly.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;If you want to take over maintaining any of these libraries, &lt;em&gt;you don&#39;t have to ask me&lt;/em&gt;. &lt;strong&gt;Just fork, and start coding.&lt;/strong&gt; If you have been consistently maintaining one of these libraries for a year or more, announce that you are resurrecting the library on the relevant Common Lisp forums. You can also drop me an e-mail and I will put a line in the README of my version that redirects users to your version. Eventually, you should convince &lt;a href=&#34;https://github.com/quicklisp/&#34;&gt;Zach Beane&lt;/a&gt; to use your version in Quicklisp.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;I cannot provide any significant help regarding the code due to time constraints. Some of it is documented, and most of it has unit tests, you have to figure out the rest yourself.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&#34;which-libraries-are-worth-the-effort&#34;&gt;Which libraries are worth the effort?&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;let-plus&lt;/code&gt; is an extensible destructuring library. The syntax is versatile and intuitive.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;LLA&lt;/code&gt;, aka Lisp Linear Algebra, is a wrapper for BLAS/LAPACK using native Common Lisp arrays. It is somewhat incomplete (eigenvalues need some work) but what is available works. It is &lt;em&gt;fast&lt;/em&gt; on implementations which provide arrays for certain float element types, so that it does not have to copy the data, and is a bit slower on implementations that don&#39;t allow this. Still, copying is &lt;span  class=&#34;math&#34;&gt;\(O(n)\)&lt;/span&gt;, while most LAPACK operations are &lt;span  class=&#34;math&#34;&gt;\(O(n^2)\)&lt;/span&gt; or worse, so this is not a huge concern. Nevertheless, it is possible that implementations that did not provide specialized arrays at the time I wrote LLA have caught up. You would need to extend the glue code to work with them.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;cl-slice&lt;/code&gt;, array slices for native Common Lisp arrays.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;cl-random&lt;/code&gt;, &lt;code&gt;cl-num-utils&lt;/code&gt;, &lt;code&gt;cl-rmath&lt;/code&gt;: random numbers, simple numerical algorithms, a wrapper for libRmath.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;code&gt;cl-colors&lt;/code&gt;, named colors and color combinations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The rest are either early experiments, preliminary versions that evolved into the libraries above, or projects that did not pan out.&lt;/p&gt;

&lt;p&gt;PS.: Some people asked why I switched to Julia from Common Lisp. A post about that will follow soon.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Branch prediction: yet another example</title>
    <link href="https://tamaspapp.eu/post/branch_prediction2/"/>
    <id>https://tamaspapp.eu/post/branch_prediction2/</id>
    <published>2017-10-04T10:12:02+02:00</published>
    <updated>2017-10-04T10:12:02+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/branch_prediction2/">&lt;p&gt;Tomas Lycken linked a &lt;a href=&#34;https://stackoverflow.com/questions/11227809/why-is-it-faster-to-process-a-sorted-array-than-an-unsorted-array/11227902#11227902&#34;&gt;very nice discussion on StackOverflow&lt;/a&gt; about branch prediction as a comment on the &lt;a href=&#34;https://tamaspapp.eu/post/branch_prediction/&#34;&gt;previous post&lt;/a&gt;. It has an intuitive explanation (read it if you like good metaphors) and some Java benchmarks. I was curious about how it looks in Julia.&lt;/p&gt;

&lt;p&gt;The exercise is to sum elements in a vector &lt;em&gt;only if&lt;/em&gt; they are greater than or equal to 128.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sumabove_if&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eltype&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≥&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;128&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This calculation naturally has a branch in it, while the branchless version, using &lt;code&gt;ifelse&lt;/code&gt;, does not:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sumabove_ifelse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eltype&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ifelse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≥&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;128&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;zero&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eltype&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The actual example has something different: using tricky bit-twiddling to calculate the same value. I generally like to leave this sort of thing up to the compiler, because it is much, much better at it than I am, and I make mistakes all the time; worse, I don&#39;t know what I actually did when I reread the code 6 months later. But I included it here for comparison:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sumabove_tricky&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Vector&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Int64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;~&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;128&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;63&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elt&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;s&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Following the original example on StackOverflow, we sum &lt;code&gt;2^15&lt;/code&gt; random integers in &lt;code&gt;1:256&lt;/code&gt;. For this, we don&#39;t need to worry about overflow. We also sum the &lt;em&gt;sorted&lt;/em&gt; vector: this will facilitate branch predicion, since the various branches will be contiguous.&lt;/p&gt;

&lt;p&gt;I also benchmark a simple version using generators:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;sumabove_generator&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≥&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;128&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;table&gt;
&lt;caption&gt;
Benchmarks (&lt;span  class=&#34;math&#34;&gt;\(μ\)&lt;/span&gt;s)

&lt;/caption&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&#34;left&#34;&gt;&lt;/th&gt;
&lt;th align=&#34;right&#34;&gt;random&lt;/th&gt;
&lt;th align=&#34;right&#34;&gt;sorted&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;if&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;139&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;28&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;ifelse&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;21&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;21&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;&lt;code&gt;if&lt;/code&gt; &amp;amp; &lt;code&gt;sort&lt;/code&gt;&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;96&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;n/a&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;tricky&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;27&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;27&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&#34;left&#34;&gt;generator&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;219&lt;/td&gt;
&lt;td align=&#34;right&#34;&gt;168&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Benchmarks are in the table above. Note that&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;for the version with &lt;code&gt;if&lt;/code&gt;, working on sorted vectors is dramatically faster (about 5x).&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;the non-branching &lt;code&gt;ifelse&lt;/code&gt; version beats them hands down, and naturally it does not care about sorting.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;if you have to use &lt;code&gt;if&lt;/code&gt;, then you are better off sorting, &lt;em&gt;even if you take the time of that into account&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;generators are susprisingly bad.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;the tricky bit-twiddling version is actually worse than &lt;code&gt;ifelse&lt;/code&gt; (which reinforces my aversion to it).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Self-contained code for everything is available below.&lt;/p&gt;



&lt;div class=&#34;codedownload&#34;&gt;&lt;p&gt;download code as &lt;a href=&#34;https://tamaspapp.eu/post/branch_prediction2/code.jl&#34;&gt;code.jl&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;

</content>
  </entry>
  
  <entry>
    <title type="html">CPU pipelines: when more is less</title>
    <link href="https://tamaspapp.eu/post/branch_prediction/"/>
    <id>https://tamaspapp.eu/post/branch_prediction/</id>
    <published>2017-10-03T11:40:58+02:00</published>
    <updated>2017-10-03T11:40:58+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/branch_prediction/">&lt;p&gt;I have been working on micro-optimizations for some simulation code, and was reminded of a counter-intuitive artifact of modern CPU architecture, which is worth a short post.&lt;/p&gt;

&lt;p&gt;Consider (just for the sake of example) a very simple (if not particularly meaningful) function,&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
f(x) = \begin{cases}
(x+2)^2 &amp; \text{if } x \ge 0,\\
1-x &amp; \text{otherwise}
\end{cases}
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;with implementations&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;f1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ifelse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≥&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;abs2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;f2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≥&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;abs2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;f1&lt;/code&gt; calculates &lt;em&gt;both&lt;/em&gt; possibilities before choosing between them with &lt;code&gt;ifelse&lt;/code&gt;, while &lt;code&gt;f2&lt;/code&gt; will only calculate values on demand. So, intuitively, it should be faster.&lt;/p&gt;

&lt;p&gt;But it isn&#39;t...&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1_000_000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BenchmarkTools&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@btime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;664.228&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;μs&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;allocations&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;7.63&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MiB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@btime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
  &lt;span class=&#34;mf&#34;&gt;6.519&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ms&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;allocations&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;7.63&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MiB&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;...it is about 10x &lt;em&gt;slower&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This can be understood as an artifact of the &lt;a href=&#34;https://en.wikipedia.org/wiki/Instruction_pipelining&#34;&gt;instruction pipeline&lt;/a&gt;: your x86 CPU likes to perform similar operations in staggered manner, and it does not like branches (jumps) because they break the flow.&lt;/p&gt;

&lt;p&gt;Comparing the native code reveals that while &lt;code&gt;f1&lt;/code&gt; is jump-free, the &lt;code&gt;if&lt;/code&gt; in &lt;code&gt;f2&lt;/code&gt; results in a jump (&lt;code&gt;jae&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@code_native&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Filename&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;REPL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;pushq&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rbp&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movq&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rsp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rbp&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movabsq&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;139862498743472&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# imm = 0x7F34468E14B0&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movsd&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm2&lt;/span&gt;           &lt;span class=&#34;c&#34;&gt;# xmm2 = mem[0],zero&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Source&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;addsd&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm2&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;mulsd&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm2&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movabsq&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;139862498743480&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# imm = 0x7F34468E14B8&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movsd&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm3&lt;/span&gt;           &lt;span class=&#34;c&#34;&gt;# xmm3 = mem[0],zero&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;subsd&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm3&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;xorps&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;cmpnlesd&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;andpd&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm3&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;andnpd&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;orpd&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movapd&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;popq&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rbp&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;retq&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;nopw&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@code_native&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Filename&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;REPL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;pushq&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rbp&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movq&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rsp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rbp&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Source&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;xorps&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;ucomisd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;jae&lt;/span&gt;     &lt;span class=&#34;n&#34;&gt;L37&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movabsq&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;139862498680736&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# imm = 0x7F34468D1FA0&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movsd&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;           &lt;span class=&#34;c&#34;&gt;# xmm1 = mem[0],zero&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;subsd&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movapd&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;popq&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rbp&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;retq&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;L37&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;movabsq&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;139862498680728&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# imm = 0x7F34468D1F98&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;addsd&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;mulsd&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmm0&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;popq&lt;/span&gt;    &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rbp&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;retq&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;nopl&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;%&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In my application the speed gain was more modest, but still sizeable. Benchmarking a non-branching version of your code is sometimes worth it, especially if it the change is simple &lt;em&gt;and&lt;/em&gt; both branches of the conditional can be run error-free. If, for example, we had to calculate&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≥&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;√&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;then we could not use &lt;code&gt;ifelse&lt;/code&gt; without restricting the domain, since &lt;code&gt;√(x+2)&lt;/code&gt; would fail whenever &lt;code&gt;x &amp;lt; -2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Julia &lt;code&gt;Base&lt;/code&gt; contains many optimizations like this: for a particularly nice example see functions that use &lt;code&gt;Base.null_safe_op&lt;/code&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Blog redesign 2.0</title>
    <link href="https://tamaspapp.eu/post/blog-redesign-201709/"/>
    <id>https://tamaspapp.eu/post/blog-redesign-201709/</id>
    <published>2017-09-29T19:55:44+02:00</published>
    <updated>2017-09-29T19:55:44+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/blog-redesign-201709/">&lt;p&gt;I have redesigned my blog (again), mainly tweaking the CSS and
hopefully achieving better support on small screens (which are still
not ideal for math, but now you should get a red warning float at the
bottom).&lt;/p&gt;
&lt;p&gt;I also re-did the feed code so that it would render better on
&lt;a href=&#34;https://www.juliabloggers.com/&#34;&gt;juliabloggers.com&lt;/a&gt;. Now the whole
content of each post should be scraped seamlessly, and appear
correctly. However, the only way to test the whole toolchain is to do
it live, and I apologize if something is still not perfect and you get
bogus updates (BTW, this post should not show up in the Julia feed).&lt;/p&gt;
&lt;p&gt;Highlights of the changes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;responsive design,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;nicer fonts,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;line breaks in MathJax when necessary and supported,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;better highlighting (Julia now looks especially nice),&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;embedded code blocks with a download link,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;better image placement,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Emacs screenshots now use a branch of &lt;a href=&#34;https://github.com/tpapp/emacs-htmlize/tree/pre-colors&#34;&gt;emacs-htmlize&lt;/a&gt;, which hopefully gets merged soon.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As always, the source code for the whole site is &lt;a href=&#34;https://github.com/tpapp/tpapp.github.io-source&#34;&gt;available&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Automatic differentiation of discontinuous integrals</title>
    <link href="https://tamaspapp.eu/post/discontinuous_integral_ad/"/>
    <id>https://tamaspapp.eu/post/discontinuous_integral_ad/</id>
    <published>2017-09-15T16:03:10+02:00</published>
    <updated>2017-09-15T16:03:10+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/discontinuous_integral_ad/">&lt;p&gt;This is a &lt;em&gt;much simplified&lt;/em&gt; writeup of a problem I encountered, in a self-contained blog post.&lt;/p&gt;

&lt;p&gt;You want to approximate the integral&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
I(\theta) = \int 1(g(x) &gt; 0) f(x,\theta) dx
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where &lt;span  class=&#34;math&#34;&gt;\(g\)&lt;/span&gt; is a continuous function, and &lt;span  class=&#34;math&#34;&gt;\(f(x,\theta)\)&lt;/span&gt; is a parametric distribution over &lt;span  class=&#34;math&#34;&gt;\(x\)&lt;/span&gt;. Everthing is continous, and thus &lt;span  class=&#34;math&#34;&gt;\(I\)&lt;/span&gt; is, too.&lt;/p&gt;

&lt;p&gt;You face the following constraints:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\(g\)&lt;/span&gt; is a black box. We will pretend that you can&#39;t invert it (except for checking our results, of course).&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;You can calculate the probability density function &lt;span  class=&#34;math&#34;&gt;\(f\)&lt;/span&gt; and even draw &lt;span  class=&#34;math&#34;&gt;\(x\)&lt;/span&gt;&#39;s for a particular &lt;span  class=&#34;math&#34;&gt;\(\theta\)&lt;/span&gt;, but that&#39;s pretty much it. You don&#39;t even get a cdf! (Again, except for checking our results.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using Monte Carlo methods, you can do the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;draw &lt;span  class=&#34;math&#34;&gt;\(x_i \sim F(\cdot, \theta)\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(i=1,\dots,N\)&lt;/span&gt;,&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;approximate&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
I(\theta) \approx \frac{1}{N}\sum_i 1(g(x_i) &gt; 0)
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;You could code this in Julia as&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;distr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;   &lt;span class=&#34;c&#34;&gt;# suppose this returns some distribution that supports Base.rand&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So far, neat and simple. Now, the fly in the ointment: &lt;strong&gt;you need the derivative&lt;/strong&gt; &lt;span  class=&#34;math&#34;&gt;\(I&#39;(\theta)\)&lt;/span&gt; for optimization or Hamiltonian Monte Carlo. The problem is that you cannot &lt;code&gt;ForwardDiff&lt;/code&gt; your way through the code above: AD&#39;ing a discontinuous step function will just give you &lt;span  class=&#34;math&#34;&gt;\(0\)&lt;/span&gt;, and &lt;code&gt;rand&lt;/code&gt; does not work with &lt;code&gt;ForwardDiff.Dual&lt;/code&gt;s anyway (which is very sensible).&lt;/p&gt;

&lt;p&gt;However, there &lt;em&gt;is&lt;/em&gt; a solution: rewrite the approximation as&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
I(\theta; \theta_0) \approx \frac{1}{N}\sum_i 1(g(x_i) &gt; 0) \frac{f(x_i,\theta)}{f(x_i,\theta_0)}
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where &lt;span  class=&#34;math&#34;&gt;\(\theta_0\)&lt;/span&gt; is the parameter used to simulate the &lt;span  class=&#34;math&#34;&gt;\(x_i\)&lt;/span&gt;. Differentiate the above at &lt;span  class=&#34;math&#34;&gt;\(\theta = \theta_0\)&lt;/span&gt;. This approximates&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
I&#39;(\theta) = \int 1(g(x) &gt; 0) \frac{\partial f(x,\theta)/\partial \theta}{f(x,\theta)}f(x,\theta) dx = \int 1(g(x) &gt; 0) \partial f(x,\theta)/\partial \theta dx
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;which is exactly what you want.&lt;/p&gt;

&lt;p&gt;Assume that the actual calculation is very complicated, so we would rather avoid implementing it for the integral and the derivative separately. It turns out that this is very simple to do with &lt;code&gt;ForwardDiff.Dual&lt;/code&gt; values: the code is literally a one-liner and a fallback method:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;elasticity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Real&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;one&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;elasticity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;where&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;one&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;partials&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which you can use in a function like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;integral_approx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elasticity&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pdf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I demonstrate this with &lt;span  class=&#34;math&#34;&gt;\(g(x) = x\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(x \sim \text{Normal}(\theta, 1)\)&lt;/span&gt;, for which of course we know that the analytical values for &lt;span  class=&#34;math&#34;&gt;\(I\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(I&#39;\)&lt;/span&gt; are the right tail probability and the pdf at 0, respectively.&lt;/p&gt;

&lt;p&gt;Graphs below show that the approximation is reasonable — we could make it much better with &lt;a href=&#34;https://github.com/stevengj/Sobol.jl&#34;&gt;low-discrepancy sequences&lt;/a&gt;, but that is an orthogonal issue.&lt;/p&gt;



&lt;img src=&#34;../post/discontinuous_integral_ad/integral.svg&#34; alt=&#34;integral&#34;&gt;




&lt;img src=&#34;../post/discontinuous_integral_ad/derivative.svg&#34; alt=&#34;derivative&#34;&gt;


&lt;p&gt;It is amazing how much you can accomplish with two lines of code in Julia! The problem that motivated this blog post is multivariate with irregular regions over which &lt;span  class=&#34;math&#34;&gt;\(\{ x: g(x) &gt; 0 \}\)&lt;/span&gt;, but I used &lt;code&gt;elasticity&lt;/code&gt; as above.&lt;/p&gt;

&lt;p&gt;Self-contained code for everything is available below.&lt;/p&gt;




&lt;div class=&#34;codedisplay&#34;&gt;
  &lt;div class=&#34;codeheader&#34;&gt;&lt;p&gt;download as &lt;a href=&#34;https://tamaspapp.eu/post/discontinuous_integral_ad/code.jl&#34;&gt;code.jl&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ForwardDiff&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ForwardDiff&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;partials&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Tag&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Distributions&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Plots&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LaTeXStrings&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;gr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;######################################################################&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# elasticity calculation&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;######################################################################&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;    elasticity(x)
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Calculate `x/x`, stripping `x` of partial derivative information. Useful for
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;calculating elasticities of the form `∂f/f` using ForwardDiff.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;elasticity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Real&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;one&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;elasticity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;where&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;one&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;V&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;partials&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;######################################################################&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# example application&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;######################################################################&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;integral_approx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;elasticity&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pdf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&amp;#34;Helper function that returns the value and derivative at the same time.&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value_and_derivative&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;where&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;:&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Real&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;typeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;F&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;R&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dual&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;one&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;partials&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;distr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Normal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ID_analytical&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;d&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;distr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;ccdf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pdf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ID_approx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;distr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;value_and_derivative&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;integral_approx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;distr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;θs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;linspace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;51&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ID0s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ID_analytical&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ID1s&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ID_approx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;scatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ID0s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xlab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;theta&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ylab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;integral&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;analytical&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;topleft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;scatter!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ID1s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;approximation&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;savefig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;integral.svg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;scatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ID0s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xlab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;theta&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ylab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;derivative&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;analytical&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;topleft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;scatter!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ID1s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;label&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;approximation&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;savefig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;derivative.svg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

</content>
  </entry>
  
  <entry>
    <title type="html">log1p in Julia</title>
    <link href="https://tamaspapp.eu/post/log1p/"/>
    <id>https://tamaspapp.eu/post/log1p/</id>
    <published>2017-09-13T11:18:59+02:00</published>
    <updated>2017-09-13T11:18:59+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/log1p/">&lt;p&gt;&lt;em&gt;edit&lt;/em&gt;: fixed bogus interaction of MathJax and code highlighting.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;edit2&lt;/em&gt;: added benchmarks.&lt;/p&gt;

&lt;p&gt;This is a follow-up on a &lt;a href=&#34;https://discourse.julialang.org/t/log1p-in-base-vs-base-math-julialibm/5852&#34;&gt;question&lt;/a&gt; I asked on the Julia forums about calculating&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\text{log1p}(x) = \log(1+x)
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This calculation is tricky because if &lt;span  class=&#34;math&#34;&gt;\(x \approx 0\)&lt;/span&gt;,&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\log(1+x) \approx x
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;while as &lt;span  class=&#34;math&#34;&gt;\(x \to \infty\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(\log(1+x)\)&lt;/span&gt; approaches &lt;span  class=&#34;math&#34;&gt;\(\log(x)\)&lt;/span&gt;, so simply using &lt;code&gt;log(1+x)&lt;/code&gt; will not be as accurate as it could be. Numerical analysts have developed specialized methods for these calculations that try to get an accurate answer, and all programming languages serious about numerical calculations have an implementation either in the core language or a library.&lt;/p&gt;

&lt;p&gt;Julia&#39;s &lt;code&gt;Base.log1p&lt;/code&gt; currently suggests that &lt;code&gt;Base.Math.JuliaLibm.log1p&lt;/code&gt; would be preferable, but then I was wondering why isn&#39;t that the default? So I decided to perform a trivial numerical experiment, calculating the error for both, and also benchmark the two methods.&lt;/p&gt;

&lt;h2 id=&#34;accuracy&#34;&gt;Accuracy&lt;/h2&gt;

&lt;p&gt;The key question is what to compare the results with. One could compare to an existing &amp;quot;gold standard&amp;quot; implementation, or simply calculate the results using a higher precision representation. Fortunately, Julia has &lt;code&gt;BigFloat&lt;/code&gt;s available right out of the box.&lt;/p&gt;

&lt;p&gt;The graph below shows the base-2 logarithm of the &lt;em&gt;relative&lt;/em&gt; error for &lt;code&gt;Base.log1p&lt;/code&gt; vs &lt;span  class=&#34;math&#34;&gt;\(\log\_2(1+x)\)&lt;/span&gt;; horizontal lines are &lt;code&gt;log2(eps())&lt;/code&gt; and &lt;code&gt;log2(eps())+1&lt;/code&gt;. This suggests that &lt;code&gt;Base.log1p&lt;/code&gt; is &lt;em&gt;very accurate&lt;/em&gt;, but not as good as it could be when &lt;span  class=&#34;math&#34;&gt;\(x \approx 0\)&lt;/span&gt;.&lt;/p&gt;



&lt;img src=&#34;../post/log1p/Base_log1p_error.svg&#34; alt=&#34;Base.log1p error&#34;&gt;


&lt;p&gt;The next plot shows the relative accuracy of the relative error above, comparing &lt;code&gt;Base.Math.JuliaLibm.log1p&lt;/code&gt; to &lt;code&gt;Base.log1p&lt;/code&gt; (lower values better). In these simulations, &lt;code&gt;Base.Math.JuliaLibm.log1p&lt;/code&gt; is never worse, but sometimes significantly better (resulting in an extra binary digit of accuracy). This matters especially when &lt;span  class=&#34;math&#34;&gt;\(x \approx 0\)&lt;/span&gt;.&lt;/p&gt;



&lt;img src=&#34;../post/log1p/JuliaLibm_improvement.svg&#34; alt=&#34;relative log2 acccuracy improvement over Base.log1p&#34;&gt;


&lt;p&gt;The next plot confirms this.&lt;/p&gt;



&lt;img src=&#34;../post/log1p/JuliaLibm_log1p_error.svg&#34; alt=&#34;JuliaLibm log1p error&#34;&gt;


&lt;h2 id=&#34;speed&#34;&gt;Speed&lt;/h2&gt;

&lt;p&gt;I also evaluated relative speed. The graph below shows the relative runtimes, obtained using &lt;code&gt;BenchmarkTools.@belapsed&lt;/code&gt;. Values below &lt;span  class=&#34;math&#34;&gt;\(1\)&lt;/span&gt; mean that &lt;code&gt;Base.Math.JuliaLibm.log1p&lt;/code&gt; is faster: indeed, this seems to be the case except for values very close to &lt;span  class=&#34;math&#34;&gt;\(0\)&lt;/span&gt;, where there is a 10–20% performance penalty. At other values, &lt;code&gt;Base.Math.JuliaLibm.log1p&lt;/code&gt; is 30–40% &lt;em&gt;faster&lt;/em&gt;.&lt;/p&gt;



&lt;img src=&#34;../post/log1p/relative_time.svg&#34; alt=&#34;relative time&#34;&gt;


&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;For values near &lt;span  class=&#34;math&#34;&gt;\(0\)&lt;/span&gt;, &lt;code&gt;Base.Math.JuliaLibm.log1p&lt;/code&gt; is more accurate, at a slight performance cost.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;For values away from &lt;span  class=&#34;math&#34;&gt;\(0\)&lt;/span&gt;, it is at least as accurate as &lt;code&gt;Base.log1p&lt;/code&gt;, and 30—40% faster.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To me, this suggests that &lt;code&gt;Base.Math.JuliaLibm.log1p&lt;/code&gt; should be the default method — mostly because the extra accuracy is more important to me than the slight performance cost.&lt;/p&gt;

&lt;p&gt;Code is available below.&lt;/p&gt;




&lt;div class=&#34;codedisplay&#34;&gt;
  &lt;div class=&#34;codeheader&#34;&gt;&lt;p&gt;download as &lt;a href=&#34;https://tamaspapp.eu/post/log1p/code.jl&#34;&gt;code.jl&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;c&#34;&gt;# consistent random numbers&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;srand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;UInt32&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mh&#34;&gt;0xfd909253&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x7859c364&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x7cd42419&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mh&#34;&gt;0x4c06a3b6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;    err(x, [prec])
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Return two values, which are the log2 relative errors for calculating
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`log1p(x)`, using `Base.log1p` and `Base.Math.JuliaLibm.log1p`.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;The errors are calculated by compating to `BigFloat` calculations with the given
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;precision `prec`.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prec&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;yb&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;BigFloat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;e2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Float64&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;abs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;abs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;e2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log1p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JuliaLibm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log1p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;20000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;       &lt;span class=&#34;c&#34;&gt;# z &amp;gt; 0, Lognormal(0, 10)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;z&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;                      &lt;span class=&#34;c&#34;&gt;# x &amp;gt; -1&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;es&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;                &lt;span class=&#34;c&#34;&gt;# errors&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Plots&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;               &lt;span class=&#34;c&#34;&gt;# plots&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;scatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;es&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xlab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;log2(x+1)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ylab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;log2 error of Base.log1p&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;hline!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Plots&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;svg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Base_log1p_error.svg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;scatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;es&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;first&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;es&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xlab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;log2(x+1)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;ylab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;improvement (Base.Math.JuliaLibm.log1p)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Plots&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;svg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;JuliaLibm_improvement.svg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;scatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;es&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xlab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;log2(x+1)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;ylab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;log2 error of Base.Math.JuliaLibm.log1p&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;hline!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Plots&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;svg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;JuliaLibm_log1p_error.svg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;######################################################################&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;# WARNING: these run for a very long time&lt;/span&gt;
&lt;span class=&#34;c&#34;&gt;######################################################################&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BenchmarkTools&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vcat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rand&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# z &amp;gt; 0, more values around &lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;z&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;                                   &lt;span class=&#34;c&#34;&gt;# x &amp;gt; -1&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;b1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@belapsed&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;log1p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;        &lt;span class=&#34;c&#34;&gt;# WARNING: takes forever&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;b2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@belapsed&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JuliaLibm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log1p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# ditto&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;scatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;z&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;./&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xlab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;log2(x+1)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;ylab&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;time Math.JuliaLibm.log1p / log1p&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;yticks&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;hline!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;Plots&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;svg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;relative_time.svg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

</content>
  </entry>
  
  <entry>
    <title type="html">Emacs customizations for julia-mode</title>
    <link href="https://tamaspapp.eu/post/emacs-julia-customizations/"/>
    <id>https://tamaspapp.eu/post/emacs-julia-customizations/</id>
    <published>2017-08-28T14:41:58+02:00</published>
    <updated>2017-08-28T14:41:58+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/emacs-julia-customizations/">&lt;p&gt;I find the following customizations very useful for &lt;em&gt;editing&lt;/em&gt; Julia
code in Emacs. Add them to &lt;code&gt;julia-mode-hook&lt;/code&gt;, eg&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;customize-julia-mode&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Customize julia-mode.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;;; my customizations go here&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;add-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;julia-mode-hook&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;customize-julia-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;highlight-fixmetodo&#34;&gt;Highlight FIXME/TODO/&amp;hellip;&lt;/h2&gt;
&lt;p&gt;When I just want to note something in a comment for future reference,
I prefer to have certain words highlighted. You can use something like
this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;font-lock-add-keywords&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;
                        &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;\\&amp;lt;\\(FIXME\\|TODO\\|QUESTION\\|NOTE\\)&amp;#34;&lt;/span&gt;
                        &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;font-lock-warning-face&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is what it looks like:&lt;/p&gt;
&lt;pre style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
            chklapackerror&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;info&lt;span style=&#34;color: #262626;&#34;&gt;[])&lt;/span&gt;
            &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;if&lt;/span&gt; any&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;ifail .!= 0&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;
                &lt;span style=&#34;color: #008b45;&#34;&gt;# &lt;/span&gt;&lt;span style=&#34;color: #f71010; font-weight: bold;&#34;&gt;TODO&lt;/span&gt;&lt;span style=&#34;color: #008b45;&#34;&gt;: better error message / type
&lt;/span&gt;                error&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color: #fa5151;&#34;&gt;&#34;failed to converge eigenvectors:\n$(nonzeros(ifail))&#34;&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;
            &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;h2 id=&#34;highlight-symbols&#34;&gt;Highlight symbols&lt;/h2&gt;
&lt;p&gt;After&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;highlight-symbol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;add a hook for&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;local-set-key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;control&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;?c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;?s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;highlight-symbol-at-point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;local-set-key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;control&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;?c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;?n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;highlight-symbol-next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;local-set-key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;control&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;?c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;sc&#34;&gt;?p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;highlight-symbol-prev&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This highlights symbols with &lt;code&gt;C-c s&lt;/code&gt;:&lt;/p&gt;
&lt;pre style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
&lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;function&lt;/span&gt; &lt;span style=&#34;color: #2c53ca;&#34;&gt;issymmetric&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color: #000000; background-color: #ffff00;&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color: #9400d3;&#34;&gt;AbstractMatrix&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;
    indsm, indsn = indices&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color: #000000; background-color: #ffff00;&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;if&lt;/span&gt; indsm != indsn
        &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color: #259ea2;&#34;&gt;false&lt;/span&gt;
    &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;end&lt;/span&gt;
    &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;for&lt;/span&gt; i = first&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;indsn&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;:last&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;indsn&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;, j = &lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;i&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;:last&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;indsn&lt;span style=&#34;color: #262626;&#34;&gt;)&lt;/span&gt;
        &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color: #000000; background-color: #ffff00;&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;[&lt;/span&gt;i,j&lt;span style=&#34;color: #262626;&#34;&gt;]&lt;/span&gt; != transpose&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color: #000000; background-color: #ffff00;&#34;&gt;A&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;[&lt;/span&gt;j,i&lt;span style=&#34;color: #262626;&#34;&gt;])&lt;/span&gt;
            &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color: #259ea2;&#34;&gt;false&lt;/span&gt;
        &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;end&lt;/span&gt;
    &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;end&lt;/span&gt;
    &lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color: #259ea2;&#34;&gt;true&lt;/span&gt;
&lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;h2 id=&#34;fill-docstrings&#34;&gt;Fill docstrings&lt;/h2&gt;
&lt;p&gt;This is useful if you want to use &lt;code&gt;M-q&lt;/code&gt; on docstrings.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;julia-fill-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;s&#34;&gt;&amp;#34;Fill a docstring, preserving newlines before and after triple quotation marks.&amp;#34;&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interactive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;transient-mark-mode&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mark-active&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fill-region&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;region-beginning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;region-end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cl-flet&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fill-if-string&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
                              &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;looking-at&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;rx&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\&amp;#34;\&amp;#34;\&amp;#34;&amp;#34;&lt;/span&gt;
                                                        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;group&lt;/span&gt;
                                                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;*?&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;any&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\\&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                                                                 &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;seq&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\\&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;anything&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
                                                        &lt;span class=&#34;s&#34;&gt;&amp;#34;\&amp;#34;\&amp;#34;\&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;looking-at&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;rx&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\&amp;#34;&amp;#34;&lt;/span&gt;
                                                        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;group&lt;/span&gt;
                                                         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;*?&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;any&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\\&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                                                                 &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;seq&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\\&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;anything&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
                                                        &lt;span class=&#34;s&#34;&gt;&amp;#34;\&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
                                &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;match-beginning&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
                                      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;match-end&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
                                  &lt;span class=&#34;c1&#34;&gt;;; (ess-blink-region start end)&lt;/span&gt;
                                  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fill-region&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;save-excursion&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;syntax-ppss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;when&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fourth&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;goto-char&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ninth&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fill-if-string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;local-set-key&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;kbd&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;M-q&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;julia-fill-string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to the mode hook.&lt;/p&gt;
&lt;h2 id=&#34;highlight-things-after-column-80&#34;&gt;Highlight things after column 80&lt;/h2&gt;
&lt;p&gt;I add this to the mode hook:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;set-fill-column&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;80&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I also use &lt;code&gt;whitespace&lt;/code&gt; globally:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;&amp;#39;whitespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;setq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;whitespace-style&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;face&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;empty&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;tabs&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;lines-tail&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;trailing&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;global-whitespace-mode&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is what it looks like:&lt;/p&gt;
&lt;pre style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;
    QR&lt;span style=&#34;color: #262626;&#34;&gt;{&lt;/span&gt;T,S&lt;span style=&#34;color: #262626;&#34;&gt;}(&lt;/span&gt;factors&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color: #9400d3;&#34;&gt;AbstractMatrix&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;{&lt;/span&gt;T&lt;span style=&#34;color: #262626;&#34;&gt;}&lt;/span&gt;, &amp;#964;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color: #9400d3;&#34;&gt;Vector&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;{&lt;/span&gt;T&lt;span style=&#34;color: #262626;&#34;&gt;})&lt;/span&gt; where &lt;span style=&#34;color: #262626;&#34;&gt;{&lt;/span&gt;T,S&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;&amp;lt;:&lt;/span&gt;&lt;span style=&#34;color: #9400d3;&#34;&gt;AbstractMatrix&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #f6f0e1;&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;background-color: #f6f0e1;&#34;&gt; = new&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #f6f0e1;&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;background-color: #f6f0e1;&#34;&gt;factors, &amp;#964;&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #f6f0e1;&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color: #2020cc; font-weight: bold;&#34;&gt;end&lt;/span&gt;
QR&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;factors&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color: #9400d3;&#34;&gt;AbstractMatrix&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;{&lt;/span&gt;T&lt;span style=&#34;color: #262626;&#34;&gt;}&lt;/span&gt;, &amp;#964;&lt;span style=&#34;color: #262626; background-color: #ded6c5;&#34;&gt;::&lt;/span&gt;&lt;span style=&#34;color: #9400d3;&#34;&gt;Vector&lt;/span&gt;&lt;span style=&#34;color: #262626;&#34;&gt;{&lt;/span&gt;T&lt;span style=&#34;color: #262626;&#34;&gt;})&lt;/span&gt; where &lt;span style=&#34;color: #262626;&#34;&gt;{&lt;/span&gt;T&lt;span style=&#34;color: #262626;&#34;&gt;}&lt;/span&gt; = QR&lt;span style=&#34;color: #262626;&#34;&gt;{&lt;/span&gt;T,typeof&lt;span style=&#34;color: #262626;&#34;&gt;(&lt;/span&gt;factors&lt;span style=&#34;color: #262626;&#34;&gt;)}(&lt;/span&gt;f&lt;span style=&#34;background-color: #f6f0e1;&#34;&gt;actors, &amp;#964;&lt;/span&gt;&lt;span style=&#34;color: #262626; background-color: #f6f0e1;&#34;&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;h2 id=&#34;hungry-delete-mode&#34;&gt;Hungry delete-mode&lt;/h2&gt;
&lt;p&gt;Add this to the mode hook:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-emacs-lisp&#34; data-lang=&#34;emacs-lisp&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;hungry-delete-mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and then backspace and delete will remove all whitespace near the point in the relevant direction.&lt;/p&gt;
&lt;p&gt;In case you are wondering, the theme is &lt;a href=&#34;https://github.com/alezost/alect-themes&#34;&gt;alect-light&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Local packages in a separate directory in Julia</title>
    <link href="https://tamaspapp.eu/post/julia-local-test/"/>
    <id>https://tamaspapp.eu/post/julia-local-test/</id>
    <published>2017-08-23T10:10:48+02:00</published>
    <updated>2017-08-23T10:10:48+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/julia-local-test/">&lt;p&gt;I run &lt;code&gt;Pkg.update()&lt;/code&gt; fairly often to stay up to date and benefit from
the latest improvements of various packages. I rarely ever &lt;code&gt;pin&lt;/code&gt; to a
specific package version, but I occasionally checkout &lt;code&gt;master&lt;/code&gt; for
some packages, especially if I am contributing.&lt;/p&gt;
&lt;p&gt;Despite updating regularly, I found that the documentation subtly diverged from what I was experiencing for some packages. After looking into the issue, I learned that I was 2&amp;ndash;3 minor versions behind despite updating regularly. For example, when I would&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ForwardDiff&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I would be told that there is a new version, and to get it I should update &lt;code&gt;ReverseDiff&lt;/code&gt; and &lt;code&gt;Optim&lt;/code&gt;. But&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ForwardDiff&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;ReverseDiff&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Optim&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;would just run quietly without updating.&lt;/p&gt;
&lt;p&gt;I could not figure out the cause for this and did not want to get sidetracked debugging it, so I decided to wipe the package directory and start over. However, in order to do this, I had to make sure that no code is lost, especially for local packages. First, I moved my local packages into a separate directory, and added that to &lt;code&gt;LOAD_PATH&lt;/code&gt; in &lt;code&gt;.juliarc.jl&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;push!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;LOAD_PATH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expanduser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;~/src/julia-local-packages/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I ran &lt;a href=&#34;https://github.com/fboender/multi-git-status&#34;&gt;multi-git-status&lt;/a&gt; to make sure that there were no unpushed changes. Finally, I deleted the package directory and reinstalled everything. Surprisingly, &lt;code&gt;Pkg.add&lt;/code&gt; ran much faster than before.&lt;/p&gt;
&lt;p&gt;In case I have to do this again, I decided to keep my local packages separate &amp;mdash; the only drawback is that &lt;code&gt;Pkg.test&lt;/code&gt; now can&amp;rsquo;t find them. A workaround is below, using some code from &lt;code&gt;Base.Pkg&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;    local_test(pkgname, [coverage])
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Find and test a package in `LOAD_PATH`. Useful when the package is outside
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`Pkg.dir()`.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Assumes the usual directory structure: package has the same name as the module,
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the main file is in `src/Pkgname.jl`, while tests are in `test/runtests.jl`.
&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;local_test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pkgname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;coverage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Bool&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;module_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_in_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pkgname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;nothing&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;src_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;module_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;splitdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;module_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;normpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;..&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;test_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;joinpath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;test&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;runtests.jl&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;nd&#34;&gt;@assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;isfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Could not find &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;color&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;have_color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;--color=yes&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;--color=no&amp;#34;&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;codecov&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;coverage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;--code-coverage=user&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;--code-coverage=none&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;compilecache&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;--compilecache=&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;JLOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;use_compilecache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;yes&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;no&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;julia_exe&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;julia_cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$julia_exe&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt; --check-bounds=yes &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$codecov&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$color&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$compilecache&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$test_path&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$module_file&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; tests passed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;err&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;Base&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Entry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warnbanner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;label&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;[ ERROR: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$module_file&lt;/span&gt;&lt;span class=&#34;s&#34;&gt; ]&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Compared to simply &lt;code&gt;include(&amp;quot;wherever-it-is/runtests.jl&amp;quot;)&lt;/code&gt;, this has the advantage of running a separate Julia process, so your workspace does not contaminate the test environment and in case of segfaults, the parent process won&amp;rsquo;t be affected.&lt;/p&gt;
&lt;p&gt;Hopefully, the code above will be obsolete once &lt;a href=&#34;https://github.com/StefanKarpinski/Pkg3.jl&#34;&gt;Pkg3&lt;/a&gt; is released, but until then it is a useful workaround.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;edit&lt;/strong&gt;: function above was corrupted during copy-paste, corrected.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Emacs 25.2 on Ubuntu</title>
    <link href="https://tamaspapp.eu/post/emacs25-ubuntu/"/>
    <id>https://tamaspapp.eu/post/emacs25-ubuntu/</id>
    <published>2017-07-03T10:49:56+02:00</published>
    <updated>2017-07-03T10:49:56+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/emacs25-ubuntu/">&lt;p&gt;Emacs is undoubtedly the most important program on my computers. On my
laptop, I use it to keep track of stuff with &lt;a href=&#34;http://orgmode.org/&#34;&gt;org-mode&lt;/a&gt;, read mail with &lt;a href=&#34;https://www.djcbsoftware.nl/code/mu/mu4e.html&#34;&gt;mu4e&lt;/a&gt;, edit LaTeX with &lt;a href=&#34;https://www.gnu.org/software/auctex/&#34;&gt;AUCTeX&lt;/a&gt;, and of course program. On servers, the first alias I define is usually &lt;code&gt;qe=&#39;emacs -Q -nw&#39;&lt;/code&gt;, which give me a fast and responsive editor. With &lt;a href=&#34;https://github.com/emacs-helm/helm&#34;&gt;helm&lt;/a&gt;, doing just about anything (eg locating files, &lt;code&gt;rgrep&lt;/code&gt;ing for something) is orders of magnitude faster and more convenient than any alternative I have tried.&lt;/p&gt;
&lt;p&gt;I also try to keep up with the latest versions for software in general. Usually, whatever Ubuntu stable/Debian testing has is good enough not to justify the extra effort, but when I really need it, I grab the source and compile. That is usually only a minor hassle, but I try to restrict it to a few critical programs, otherwise it adds up. The major issue is not compiling, but having cruft in the filesystem (despite &lt;a href=&#34;https://www.gnu.org/software/stow/manual/stow.html&#34;&gt;stow&lt;/a&gt; and &lt;a href=&#34;https://wiki.debian.org/CheckInstall&#34;&gt;checkinstall&lt;/a&gt;, it piles up). So I try to avoid it if I can.&lt;/p&gt;
&lt;p&gt;Emacs 25.2 was released in April 2017, but there is no sign of an Ubuntu package for it yet. On various forums the &lt;a href=&#34;https://launchpad.net/~kelleyk/+archive/ubuntu/emacs&#34;&gt;PPA of kelleyk&lt;/a&gt; is recommended, but that does not have 25.2 for 17.04 (some files clash if you install previous versions).&lt;/p&gt;
&lt;p&gt;Fortunately, Robert Bruce Park has now added Emacs 25.2 to the &lt;a href=&#34;https://launchpad.net/~ubuntu-elisp/+archive/ubuntu/ppa&#34;&gt;Ubuntu Emacs Lisp PPA&lt;/a&gt;, so having the latest of your favorite editor is only an &lt;code&gt;add-apt-repository&lt;/code&gt; away. You may want to add a file to &lt;code&gt;/etc/apt/preferences.d&lt;/code&gt; with contents&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Package: *
Pin: release o=LP-PPA-ubuntu-elisp
Pin-Priority: 600
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to make sure the right packages are installed.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Sampling variation in effective sample size estimates (MCMC)</title>
    <link href="https://tamaspapp.eu/post/ess-sampling/"/>
    <id>https://tamaspapp.eu/post/ess-sampling/</id>
    <published>2017-06-12T16:25:57+02:00</published>
    <updated>2017-06-12T16:25:57+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/ess-sampling/">&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;MCMC samples, used in Bayesian statistics, are not independent --- in fact, unless one uses specialized methods or &lt;a href=&#34;https://arxiv.org/abs/1701.02434&#34;&gt;modern HMC&lt;/a&gt;, posterior draws are usually at highly autocorrelated. For independent draws,&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\text{variance of simulation mean} \propto \frac1N
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where &lt;span  class=&#34;math&#34;&gt;\(N\)&lt;/span&gt; is the sample size, but for correlated draws, one has to scale the sample size with a factor&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\tau = \frac{1}{1+2\sum_{k=1}^\infty \rho_k}
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where &lt;span  class=&#34;math&#34;&gt;\(\rho_k\)&lt;/span&gt; is the lag-&lt;span  class=&#34;math&#34;&gt;\(k\)&lt;/span&gt; autocorrelation. &lt;span  class=&#34;math&#34;&gt;\(\tau N\)&lt;/span&gt; is the &lt;em&gt;effective sample size&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Usually, &lt;span  class=&#34;math&#34;&gt;\(\rho_k\)&lt;/span&gt; is estimated from the data using the variogram&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
V_k = \frac{1}{N-k} \sum_{i=1}^{N-k} x_i x_{i+k}
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;from which we obtain&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\rho_k = 1-\frac{V_k}{2\text{var}(x)}
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where an estimator for the variance is also used. Then, to avoid using noisy estimates, we only add up to the last &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt; where&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\rho_{K} + \rho_{K+1} \ge 0
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I will call &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt; the &lt;em&gt;last lag&lt;/em&gt;. &lt;a href=&#34;http://mc-stan.org/&#34;&gt;Stan&lt;/a&gt; does something slightly different, using FFT for autocorrelations, and cutting off at the first negative &lt;span  class=&#34;math&#34;&gt;\(\rho_K\)&lt;/span&gt;, but for HMC this does not make a whole lot of difference.&lt;/p&gt;

&lt;h2 id=&#34;the-sampling-variation&#34;&gt;The sampling variation&lt;/h2&gt;

&lt;p&gt;I was coding up the above calculation, and needed some unit tests. Surprisignly, I could not find anything on the sampling variation of &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;, so I wrote some simulations in Julia (&lt;a href=&#34;../ess-sampling.jl&#34;&gt;source code for everything&lt;/a&gt;). I did the following simulation exercise:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;for a given autocorrelation coefficient &lt;span  class=&#34;math&#34;&gt;\(\phi\)&lt;/span&gt;, simulate &lt;span  class=&#34;math&#34;&gt;\(N\)&lt;/span&gt; draws from the AR(1) process
&lt;span  class=&#34;math&#34;&gt;\(
x_t = \phi x_{t-1} + \sigma \epsilon_t
\qquad
\epsilon_t \sim \text{Normal}(0,1), \text{IID}
\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;calculate &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt;,&lt;/li&gt;
&lt;li&gt;repeat 1000 times and plot the results.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I use &lt;span  class=&#34;math&#34;&gt;\(N=1000\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(N=10000\)&lt;/span&gt;, as these would be typical sample sizes, first for a fairly efficient algorithm, then for a more stubborn but still manageable posterior.&lt;/p&gt;

&lt;h2 id=&#34;iid-samples&#34;&gt;IID samples&lt;/h2&gt;

&lt;p&gt;Let &lt;span  class=&#34;math&#34;&gt;\(\phi=0\)&lt;/span&gt;, then we expect &lt;span  class=&#34;math&#34;&gt;\(\tau=1\)&lt;/span&gt; (red line in histogram, coefficient of variation on top).&lt;/p&gt;

&lt;p&gt;Results with &lt;span  class=&#34;math&#34;&gt;\(\phi=0\)&lt;/span&gt; (IID), &lt;span  class=&#34;math&#34;&gt;\(N=1000\)&lt;/span&gt;. (a) &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;, (b) last lag &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt;, (c) scatterplot.


&lt;img src=&#34;../post/ess-sampling/ess-phi0N1000.svg&#34; alt=&#34;Results with $$\phi=0$$ (IID), $$N=1000$$. (a) $$\tau$$, (b) last lag $$K$$, (c) scatterplot.&#34;&gt;
&lt;/p&gt;

&lt;p&gt;Results with &lt;span  class=&#34;math&#34;&gt;\(\phi=0\)&lt;/span&gt; (IID), &lt;span  class=&#34;math&#34;&gt;\(N=10000\)&lt;/span&gt;. (a) &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;, (b) last lag &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt;, (c) scatterplot.


&lt;img src=&#34;../post/ess-sampling/ess-phi0N10000.svg&#34; alt=&#34;Results with $$\phi=0$$ (IID), $$N=10000$$. (a) $$\tau$$, (b) last lag $$K$$, (c) scatterplot.&#34;&gt;
&lt;/p&gt;

&lt;p&gt;With &lt;span  class=&#34;math&#34;&gt;\(1000\)&lt;/span&gt; samples, there is a lot of variation in ESS: 800 could show up very easily in practice. &lt;span  class=&#34;math&#34;&gt;\(600\)&lt;/span&gt; is not improbable either. Using up to &lt;span  class=&#34;math&#34;&gt;\(10\)&lt;/span&gt; lags is not uncommon. For &lt;span  class=&#34;math&#34;&gt;\(10000\)&lt;/span&gt; samples, the precision is improved considerably, we commonly use &lt;span  class=&#34;math&#34;&gt;\(2\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(4\)&lt;/span&gt; lags. For both sample sizes, notice the high correlation between the last lag &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt;, and &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;: given the method above, using more lags increases &lt;span  class=&#34;math&#34;&gt;\(\tau^{-1}\)&lt;/span&gt;, so this is to be expected.&lt;/p&gt;

&lt;h2 id=&#34;ar1-samples-with-rho05&#34;&gt;AR(1) samples with &lt;span  class=&#34;math&#34;&gt;\(\rho=0.5\)&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;This is a more autocorrelated process, here theory tells us that &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;=1/3.&lt;/p&gt;

&lt;p&gt;Results with &lt;span  class=&#34;math&#34;&gt;\(\phi=0.5\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(N=1000\)&lt;/span&gt;. (a) &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;, (b) last lag &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt;, (c) scatterplot.


&lt;img src=&#34;../post/ess-sampling/ess-phi05N1000.svg&#34; alt=&#34;Results with $$\phi=0.5$$, $$N=1000$$. (a) $$\tau$$, (b) last lag $$K$$, (c) scatterplot.&#34;&gt;
&lt;/p&gt;

&lt;p&gt;Results with &lt;span  class=&#34;math&#34;&gt;\(\phi=0.5\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(N=10000\)&lt;/span&gt;. (a) &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;, (b) last lag &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt;, (c) scatterplot.


&lt;img src=&#34;../post/ess-sampling/ess-phi05N10000.svg&#34; alt=&#34;Results with $$\phi=0.5$$, $$N=10000$$. (a) $$\tau$$, (b) last lag $$K$$, (c) scatterplot.&#34;&gt;
&lt;/p&gt;

&lt;p&gt;Notice that &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt; is now more dispersed, compared to the IID case. Even with 10000 samples, the coefficient of variation is 6%, with 1000 it is around 1/6. In practice, expect effective sample sizes all over the place.&lt;/p&gt;

&lt;h2 id=&#34;ar1-samples-with-rho08&#34;&gt;AR(1) samples with &lt;span  class=&#34;math&#34;&gt;\(\rho=0.8\)&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;This is an even more autocorrelated process, here theory tells us that &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;=1/9.&lt;/p&gt;

&lt;p&gt;Results with &lt;span  class=&#34;math&#34;&gt;\(\phi=0.8\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(N=1000\)&lt;/span&gt;. (a) &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;, (b) last lag &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt;, (c) scatterplot.


&lt;img src=&#34;../post/ess-sampling/ess-phi08N1000.svg&#34; alt=&#34;Results with $$\phi=0.8$$, $$N=1000$$. (a) $$\tau$$, (b) last lag $$K$$, (c) scatterplot.&#34;&gt;
&lt;/p&gt;

&lt;p&gt;Results with &lt;span  class=&#34;math&#34;&gt;\(\phi=0.8\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(N=10000\)&lt;/span&gt;. (a) &lt;span  class=&#34;math&#34;&gt;\(\tau\)&lt;/span&gt;, (b) last lag &lt;span  class=&#34;math&#34;&gt;\(K\)&lt;/span&gt;, (c) scatterplot.


&lt;img src=&#34;../post/ess-sampling/ess-phi08N10000.svg&#34; alt=&#34;Results with $$\phi=0.8$$, $$N=10000$$. (a) $$\tau$$, (b) last lag $$K$$, (c) scatterplot.&#34;&gt;
&lt;/p&gt;

&lt;p&gt;There is now so much variation that in order to get an estimate for ESS that we can use for comparing various MCMC implementations, we need to run much more than &lt;span  class=&#34;math&#34;&gt;\(1000\)&lt;/span&gt; samples.&lt;/p&gt;

&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;For unit testing ESS calculations, I will need to use 10000 samples, with &lt;span  class=&#34;math&#34;&gt;\(\pm10\)&lt;/span&gt; or similar error bands.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;As a rule of thumb, I would ignore less than 1.5x variation in ESS for 1000 samples, or run longer chains: it may be just random noise.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;bibliography&#34;&gt;Bibliography&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Gelman, Andrew, et al. 2013. Bayesian data analysis. 3rd edition. Chapman &amp;amp; Hall/CRC.&lt;/li&gt;
&lt;li&gt;Stan Development Team. 2016. Stan Modeling Language Users Guide and Reference Manual, Version 2.15.0. &lt;a href=&#34;http://mc-stan.org&#34;&gt;http://mc-stan.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Blog redesign</title>
    <link href="https://tamaspapp.eu/post/blog-redesign/"/>
    <id>https://tamaspapp.eu/post/blog-redesign/</id>
    <published>2017-06-12T14:12:43+02:00</published>
    <updated>2017-06-12T14:12:43+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/blog-redesign/">&lt;p&gt;I am in the process of rebuilding my personal website using &lt;a href=&#34;http://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;. I tried various themes, including &lt;a href=&#34;https://github.com/gcushen/hugo-academic&#34;&gt;hugo-academic&lt;/a&gt;, but in the process of adapting them to my needs I realized that it is less work to write one from scratch.&lt;/p&gt;
&lt;p&gt;The result is now 80% ready (blog works, automatic listing of research papers will take some more work), and the &lt;a href=&#34;https://github.com/tpapp/tpapp.github.io-source&#34;&gt;source is on Github&lt;/a&gt;. It is available under the CC-BY-SA license, feel free to adapt parts from it, not that there is anything special in there.&lt;/p&gt;
&lt;p&gt;Hugo is really an excellent framework, it is clean, logical, and allows a lot of code reuse. I &lt;del&gt;wasted&lt;/del&gt; spent most of the time on fiddling with CSS, and I am still not 100% satisfied with the result, but at some point I decided to stop. &lt;a href=&#34;http://sass-lang.com/&#34;&gt;SCSS&lt;/a&gt; was extremely useful for writing organized CSS.&lt;/p&gt;
&lt;p&gt;I am especially satisfied with moving the code highlighting to the generator side. The only non-static parts are now &lt;a href=&#34;https://disqus.com/&#34;&gt;Disqus&lt;/a&gt; and &lt;a href=&#34;http://www.mathjax.org/&#34;&gt;MathJax&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Research</title>
    <link href="https://tamaspapp.eu/research/"/>
    <id>https://tamaspapp.eu/research/</id>
    <published>2017-06-11T14:48:06+02:00</published>
    <updated>2017-06-11T14:48:06+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/research/">&lt;h2 id=&#34;working-papers&#34;&gt;Working papers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Couples&amp;rsquo; times use and aggregate outcomes: evidence from a structural model. &lt;em&gt;Joint with Almut Balleer and Monika Merz.&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The structure of labor market flows. &lt;a href=&#34;../pdf/structure-of-labor-market-flows.pdf&#34;&gt;PDF&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Accounting for Idiosyncratic Wage Risk Over the Business Cycle. &lt;em&gt;Joint with Alisdair McKay&lt;/em&gt;. &lt;a href=&#34;../pdf/wage_vol.pdf&#34;&gt;PDF&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;short-notes&#34;&gt;Short notes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Consistent local approximation in continuous time. &lt;a href=&#34;../pdf/consistent-local-continuous.pdf&#34;&gt;PDF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;published-papers&#34;&gt;Published papers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Estimating Linearized Heterogeneous Agent Models Using Panel Data. &lt;em&gt;Joint with &lt;a href=&#34;https://myservice.ihs.ac.at/mreiter/&#34;&gt;Michael Reiter&lt;/a&gt;&lt;/em&gt;. &lt;a href=&#34;https://doi.org/10.1016/j.jedc.2020.103881&#34;&gt;&lt;em&gt;JEDC 2020&lt;/em&gt;&lt;/a&gt;, also &lt;a href=&#34;../pdf/HetAgEstimation_2019.pdf&#34;&gt;formatted for screen reading&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Frictional wage dispersion with Bertrand competition: an assessment. &lt;a href=&#34;https://www.sciencedirect.com/science/article/pii/S1094202513000094&#34;&gt;&lt;em&gt;RED 2013&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Getting a nice &#43;= in LaTeX math</title>
    <link href="https://tamaspapp.eu/post/latex-math-increment/"/>
    <id>https://tamaspapp.eu/post/latex-math-increment/</id>
    <published>2017-05-24T12:59:53+02:00</published>
    <updated>2017-05-24T12:59:53+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/latex-math-increment/">&lt;p&gt;I am working on an appendix for a paper that uses MCMC, and I decided to document some &lt;a href=&#34;https://tamaspapp.eu/post/jacobian-chain/&#34;&gt;change of varible calculations&lt;/a&gt; in the interest of reproducibility (they are quite complex, because of multivariate determinants). But how can I typeset them nicely in $\LaTeX$?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-latex&#34; data-lang=&#34;latex&#34;&gt;&lt;span class=&#34;k&#34;&gt;\mathtt&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{&lt;/span&gt;target&lt;span class=&#34;nb&#34;&gt;}&lt;/span&gt; += J&lt;span class=&#34;nb&#34;&gt;_&lt;/span&gt;f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;gives
$$
\mathtt{target} += J_f
$$
which is to be expected, as &lt;code&gt;+&lt;/code&gt; is a binary operator and &lt;code&gt;=&lt;/code&gt; is a relation, so $\LaTeX$ is not expecting them to show up this way.&lt;/p&gt;
&lt;p&gt;We can remedy this as&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-latex&#34; data-lang=&#34;latex&#34;&gt;&lt;span class=&#34;k&#34;&gt;\mathtt&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{&lt;/span&gt;target&lt;span class=&#34;nb&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;\mathrel&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{&lt;/span&gt;+&lt;span class=&#34;nb&#34;&gt;}&lt;/span&gt;= J&lt;span class=&#34;nb&#34;&gt;_&lt;/span&gt;f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which shows up as
$$
\mathtt{target} \mathrel{+}= J_f
$$
which is an improvement, but is still not visually appealing.&lt;/p&gt;
&lt;p&gt;Making the &lt;code&gt;+&lt;/code&gt; a bit smaller with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-latex&#34; data-lang=&#34;latex&#34;&gt;&lt;span class=&#34;k&#34;&gt;\mathrel&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;\raisebox&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{&lt;/span&gt;0.19ex&lt;span class=&#34;nb&#34;&gt;}{&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;\scriptstyle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;}}&lt;/span&gt;=&lt;span class=&#34;nb&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;yields
$$
\mathtt{target} \mathrel{\raise{0.19ex}{\scriptstyle+}} = J_f
$$
which looks OK enough to preclude further tweaking. Note that &lt;a href=&#34;http://www.mathjax.org/&#34;&gt;MathJax&lt;/a&gt; does not support &lt;code&gt;\raisebox&lt;/code&gt;, but you can use&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-latex&#34; data-lang=&#34;latex&#34;&gt;&lt;span class=&#34;k&#34;&gt;\mathrel&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;\raise&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{&lt;/span&gt;0.19ex&lt;span class=&#34;nb&#34;&gt;}{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;\scriptstyle&lt;/span&gt;+&lt;span class=&#34;nb&#34;&gt;}}&lt;/span&gt; = J&lt;span class=&#34;nb&#34;&gt;_&lt;/span&gt;f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which renders the as above.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Two tricks for change of variables in MCMC</title>
    <link href="https://tamaspapp.eu/post/jacobian-chain/"/>
    <id>https://tamaspapp.eu/post/jacobian-chain/</id>
    <published>2017-05-23T16:39:26+02:00</published>
    <updated>2017-05-23T16:39:26+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/jacobian-chain/">&lt;p&gt;Change of variables are sometimes advantageous, and occasionally inevitable for MCMC if you want efficient sampling, or to model a distribution that was obtained by a transformation. A classic example is the &lt;em&gt;lognormal distribution&lt;/em&gt;: when&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[\log(y) \sim N(\mu, \sigma^2)\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;one has to adjust the log posterior by &lt;span  class=&#34;math&#34;&gt;\(-\log y\)&lt;/span&gt; since&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[\frac{\partial \log(y)}{\partial y} = \frac{1}{y}\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[\log(1/y) = -\log(y).\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href=&#34;http://mc-stan.org/&#34;&gt;Stan&lt;/a&gt;, one would accomplish this as&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-stan&#34; data-lang=&#34;stan&#34;&gt;target += -log(y)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In general, when you transform using a multivariate function &lt;span  class=&#34;math&#34;&gt;\(f\)&lt;/span&gt;, you would adjust by&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[\log\det J_f(y)\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;which is the log of the determinant of the Jacobian — some texts
simply refer to this as &amp;quot;the Jacobian&amp;quot;.&lt;/p&gt;

&lt;p&gt;The above is well-known, but the following two tricks are worth mentioning.&lt;/p&gt;

&lt;h2 id=&#34;chaining-transformations&#34;&gt;Chaining transformations&lt;/h2&gt;

&lt;p&gt;Suppose that you are changing a variable by using a chain of two
functions &lt;span  class=&#34;math&#34;&gt;\(f \circ g\)&lt;/span&gt;. Then&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\log\det J_{f \circ g}(y) = \log \bigl(\det J_f(g(y)) \cdot \det J_g(y)\bigr) \\\\
= \log\det J_f(g(y)) + \log\det J_g(y)
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;which means that you can simply add (the log determinant of) the
Jacobians, of course evaluated at the appropriate points.&lt;/p&gt;

&lt;p&gt;This is very useful when &lt;span  class=&#34;math&#34;&gt;\(f \circ g\)&lt;/span&gt; is complicated and &lt;span  class=&#34;math&#34;&gt;\(J_{f\circ g}\)&lt;/span&gt;
is tedious to derive, or if you want to use multiple &lt;span  class=&#34;math&#34;&gt;\(f\)&lt;/span&gt;s or &lt;span  class=&#34;math&#34;&gt;\(g\)&lt;/span&gt;s and
economize on the algebra.  From the above, it is also easy to see that this
generalizes to arbitrarily long chains of functions &lt;span  class=&#34;math&#34;&gt;\(f_1 \circ f_2 \circ \dots\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;This trick turned out to be very useful when I was fitting a model
where a transformation was general to both equilibrium concepts I was
using (a noncooperative game and a social planner), so I could save on
code. Of course, since
&lt;a href=&#34;https://github.com/stan-dev/stan/issues/2224&#34;&gt;#2224&lt;/a&gt; is WIP, I had to
copy-paste the code, but still saved quite a bit of work.&lt;/p&gt;

&lt;h2 id=&#34;transforming-a-subset-of-variables&#34;&gt;Transforming a subset of variables&lt;/h2&gt;

&lt;p&gt;Suppose &lt;span  class=&#34;math&#34;&gt;\(x \in \mathbb{R}^m\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(y \in \mathbb{R}^n\)&lt;/span&gt; are vectors, and you are interested in transforming to&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
z = f(x,y)
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where &lt;span  class=&#34;math&#34;&gt;\(x\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(z\)&lt;/span&gt; have the same dimension. It is useful to think
about this transformation as&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
g(x,y) = [f(x,y), y]^\top
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where &lt;span  class=&#34;math&#34;&gt;\(g : \mathbb{R}^{m+n} \to \mathbb{R}^{m+n}\)&lt;/span&gt;. Since &lt;span  class=&#34;math&#34;&gt;\(y\)&lt;/span&gt; is mapped to itself,&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
J_g = \begin{bmatrix}
J_{f,x} &amp; J_{f,y} \\\\
0 &amp; I
\end{bmatrix}
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;has a block structure, where&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
J_{f,x} = \frac{\partial f(x,y)}{\partial x}
\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;and similarly for &lt;span  class=&#34;math&#34;&gt;\(J_{f,y}\)&lt;/span&gt;. For the calculation of the determinant, you can safely ignore the latter, and &lt;span  class=&#34;math&#34;&gt;\(\log \det I = 0\)&lt;/span&gt;, so&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[
\log\det J_g = \log\det J_{f,x}
\]&lt;/span&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Disabling Privacy Badger</title>
    <link href="https://tamaspapp.eu/post/privacy-badger/"/>
    <id>https://tamaspapp.eu/post/privacy-badger/</id>
    <published>2017-05-02T16:35:37+02:00</published>
    <updated>2017-05-02T16:35:37+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/privacy-badger/">&lt;p&gt;Firefox has been my primary browser for the last decade. I find it very fast and convenient, and use quite a few addons, including &lt;a href=&#34;https://addons.mozilla.org/en-gb/firefox/addon/google-scholar-button/&#34;&gt;Google Scholar Button&lt;/a&gt;, &lt;a href=&#34;https://addons.mozilla.org/en-gb/firefox/addon/noscript/?src=search&#34;&gt;NoScript&lt;/a&gt;,  and &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/&#34;&gt;uBlock Origin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I can&amp;rsquo;t recall exactly when, but about half a year ago various sites started to break. I have not bothered to debug what&amp;rsquo;s happening, suspecting it was was a combination of various plugins, but continued to use Firefox and installed &lt;a href=&#34;https://github.com/darktrojan/openwith&#34;&gt;openwith&lt;/a&gt; to open broken pages in Chromium (yes, I know, the ultimate kludge). More sites became broken, and I found that now I am spending 99% of my time in Chromium, which I don&amp;rsquo;t like that much, but moreover, it is a resource hog: while using the plugins above I can get the CPU load of Firefox to around 1&amp;ndash;2% when I am not using it, Chromium drains my laptop battery in effectively half the time. To make things worse, Chromium apparently can&amp;rsquo;t open links in the background like Firefox, and insists on raising the window every time I open a link from another process, which is distracting.&lt;/p&gt;
&lt;p&gt;Finally, &lt;a href=&#34;https://discourse.julialang.org/&#34;&gt;Julia&amp;rsquo;s Discourse forum&lt;/a&gt; started showing up empty, which was the last straw and I went through my plugins. It turns out hat &lt;a href=&#34;https://www.eff.org/privacybadger&#34;&gt;Privacy Badger&lt;/a&gt; was responsible for everything: apparently it relies on heavy-handed heuristics and breaks a lot of webpages. One can report this, but instead of reporting around 10&amp;ndash;20 pages which were broken, I simply removed the plugin. I have a lot of respect for what the Electronic Frontier Foundation does, but I am not sure that this plugin is very useful.&lt;/p&gt;
&lt;p&gt;So finally I got back the web the way I like it. Moral of the story: temporary workarounds become permanent, and bite back.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Blogging with Hugo, Julia, Weave.jl</title>
    <link href="https://tamaspapp.eu/post/blogging-weave-julia-hugo/"/>
    <id>https://tamaspapp.eu/post/blogging-weave-julia-hugo/</id>
    <published>2017-03-30T10:02:32+02:00</published>
    <updated>2017-03-30T10:02:32+02:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/blogging-weave-julia-hugo/">&lt;p&gt;I have made a PR to &lt;a href=&#34;https://github.com/mpastell/Weave.jl&#34;&gt;Weave.jl&lt;/a&gt; which Matti Pastell kindly merged recently. This allows a relatively smooth workflow for blogging using the static website generator &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;, and generating some pages with plots and evaluated Julia results. I made the source for my blog &lt;a href=&#34;https://github.com/tpapp/tpapp.github.io-source&#34;&gt;available&lt;/a&gt; so that others can use it for their own blogging about Julia. An example is &lt;a href=&#34;../post/hugo-julia-weave/&#34;&gt;this post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The gist of the workflow is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;for posts which do not need &lt;code&gt;Weave&lt;/code&gt;, just use &lt;code&gt;Hugo&lt;/code&gt;. Make sure you read their &lt;a href=&#34;https://gohugo.io/overview/introduction/&#34;&gt;excellent tutorial&lt;/a&gt;. &lt;strong&gt;This very fast&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;for posts which contain Julia code and generated plots, use a script to generate a skeleton file in a separate directory, and work on that. Call another script to generate the &lt;code&gt;.md&lt;/code&gt; file using &lt;code&gt;Weave.jl&lt;/code&gt;. &lt;strong&gt;This is the slow part&lt;/strong&gt;, so it is not automated.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/tpapp/tpapp.github.io-source&#34;&gt;README&lt;/a&gt; gives more details. Feel free to ask questions here. If you have a better workflow, I would like to hear about it.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Teaching a course using Julia</title>
    <link href="https://tamaspapp.eu/post/teaching-a-course/"/>
    <id>https://tamaspapp.eu/post/teaching-a-course/</id>
    <published>2017-03-24T14:34:22+01:00</published>
    <updated>2017-03-24T14:34:22+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/teaching-a-course/">&lt;p&gt;I just finished teaching a graduate course on practical aspects of dynamic optimization to our economics students. This year, for the first time, I taught the course using Julia, and this is a writeup of the experience. This was an intensive, 10-week course, with two classes per week, taught in the computer lab. A course on the theory of dynamic optimization was a prerequisite, this one was all about the actual numerical methods. The students had prior exposure to R and Matlab, and some of them have been using Julia for a while. In some classes, I talked about theory, sometimes I wrote code, ran it, and made improved versions, sometimes we treated the class as a practice session.&lt;/p&gt;
&lt;p&gt;I wanted to focus on the actual methods, so I decided to use a subset of the language, &amp;ldquo;Julia light&amp;rdquo;, using the following concepts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;scalars, algebra, arrays, indexing&lt;/li&gt;
&lt;li&gt;functions (with very basic dispatch, on an argument that contained problem parameters)&lt;/li&gt;
&lt;li&gt;control flow: &lt;code&gt;for&lt;/code&gt; and &lt;code&gt;if&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;comprehension, concatenation&lt;/li&gt;
&lt;li&gt;structures (only &lt;code&gt;immutable&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;docstrings&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The purpose of the course was to show that one can easily implement seemingly abstract methods encountered in textbooks, dissect them, look at the caveats, and possibly adapt them to particular problems. Writing what I think of as production code would have involved teaching many new concepts to a class coming with very heterogeneous experience in programming, so I decided to steer clear of the following topics:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;modules&lt;/li&gt;
&lt;li&gt;macros&lt;/li&gt;
&lt;li&gt;the type system&lt;/li&gt;
&lt;li&gt;writing efficient code (even though we ended up doing a bit on that, and benchmarking, could not resist)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We used &lt;a href=&#34;https://github.com/EconForge/NLsolve.jl&#34;&gt;NLsolve&lt;/a&gt;, &lt;a href=&#34;https://github.com/JuliaNLSolvers/Optim.jl&#34;&gt;Optim&lt;/a&gt;, and &lt;a href=&#34;https://github.com/JuliaPlots/Plots.jl&#34;&gt;Plots&lt;/a&gt; extensively, and &lt;a href=&#34;https://github.com/JuliaDiff/ForwardDiff.jl&#34;&gt;ForwardDiff&lt;/a&gt; under the hood. &lt;a href=&#34;https://github.com/mauro3/Parameters.jl&#34;&gt;Parameters&lt;/a&gt; was very useful for clean code.&lt;/p&gt;
&lt;h2 id=&#34;perspective-of-the-instructor&#34;&gt;Perspective of the instructor&lt;/h2&gt;
&lt;p&gt;Even when I wrote something in a suboptimal manner, it turned out to be fast enough. Julia is great in that respect. However, compilation time dominated almost everything that we did, especially for plots.&lt;/p&gt;
&lt;p&gt;I was using Jupyter notebooks, inspired by &lt;a href=&#34;https://math.mit.edu/classes/18.S096/iap17/&#34;&gt;18.S096&lt;/a&gt;. While I am much, much slower writing code in Jupyter compared to Emacs, I think that this turned out to be a benefit: jumping around between windows is very difficult to follow. &lt;a href=&#34;https://github.com/JuliaGizmos/Interact.jl&#34;&gt;Interact&lt;/a&gt; was just great.&lt;/p&gt;
&lt;p&gt;I made a small package for code we wrote in class, and distributed new code via &lt;code&gt;Pkg.update()&lt;/code&gt;. This worked well most of the time.&lt;/p&gt;
&lt;p&gt;We were using &lt;code&gt;v0.5.0&lt;/code&gt; and later transitioned to &lt;code&gt;v0.5.1&lt;/code&gt;, which was seamless.&lt;/p&gt;
&lt;p&gt;Since I was not using modules, sometimes the best way to extricate myself from a state was restarting the kernel. This became a running joke among the students (&amp;ldquo;when in doubt, restart the kernel&amp;rdquo;). This actually worked very well for the infamous &lt;a href=&#34;https://github.com/julialang/julia/issues/265&#34;&gt;#265&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Jupyter is great for interactive notes in class. I mixed a great deal of marked up text and LaTeX equations into the workbooks. Problem sets were handed in using Jupyter notebooks, and the exam (solving a dynamic programming problem) was also written in and graded as a notebook.&lt;/p&gt;
&lt;p&gt;Unicode specials are addictive. Once you learn about &lt;code&gt;α&lt;/code&gt;, you never name a variable &lt;code&gt;alpha&lt;/code&gt; again.&lt;/p&gt;
&lt;h2 id=&#34;perspective-of-the-students&#34;&gt;Perspective of the students&lt;/h2&gt;
&lt;p&gt;I talked to the class at the end of the course about their experience with Julia, and some of them individually. The biggest issue for them was lack of easily searchable answers to common questions: for R and Matlab, a &amp;ldquo;how do you &amp;hellip;&amp;rdquo; query turns up 100+ answers because many people have encountered the problem before. This was not the case for Julia. Lack of examples was an especially difficult issue for plots.&lt;/p&gt;
&lt;p&gt;Debugging in Jupyter was difficult, since it mostly amounted to debugging by bisection, isolation, and occasionally printing. Students found some of the error messages cryptic (especially when it was about not having a matching method, since we did not really go into the type system).&lt;/p&gt;
&lt;p&gt;The most puzzling transient bugs were because of &lt;a href=&#34;https://github.com/julialang/julia/issues/265&#34;&gt;#265&lt;/a&gt; (&amp;ldquo;but I recompiled that function!&amp;quot;). This was solved by restarting the kernel, so the latter became somewhat of a panacea. Since compilation time dominated everything, this slowed things down considerably.&lt;/p&gt;
&lt;h2 id=&#34;takeaway&#34;&gt;Takeaway&lt;/h2&gt;
&lt;p&gt;Would definitely do it again. Even with the issues, Julia was the most comfortable language to teach in.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Julia &#43; Weave.jl &#43; hugo test</title>
    <link href="https://tamaspapp.eu/post/hugo-julia-weave/"/>
    <id>https://tamaspapp.eu/post/hugo-julia-weave/</id>
    <published>2017-03-03T13:11:53+01:00</published>
    <updated>2017-03-03T13:11:53+01:00</updated>
    
    <content type="html" xml:base="https://tamaspapp.eu/post/hugo-julia-weave/">&lt;p&gt;Testing the &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; formatter for &lt;a href=&#34;https://github.com/mpastell/Weave.jl&#34;&gt;Weave.jl&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Testing inline code: &lt;code&gt;1+1=2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Testing math:
$$x^2+y^2 = \int_0^1 f(z) dz$$&lt;/p&gt;
&lt;p&gt;Testing code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Testing proper highlighting:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A plot:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.^&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;scatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure&gt;
    &lt;img src=&#34;../figures/hugo-julia-weave_4_1.svg&#34;/&gt; &lt;figcaption&gt;
            &lt;h4&gt;Caption for this plot&lt;/h4&gt;
        &lt;/figcaption&gt;
&lt;/figure&gt;

</content>
  </entry>
  
</feed>
