<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Programming on Chase the Devil</title>
		<link>https://31416.org/tags/programming/</link>
		<description>Recent content in Programming on Chase the Devil</description>
		<generator>Hugo</generator>
		<language>en-us</language>
		
		
		
		
			<lastBuildDate>Sun, 07 Jun 2026 03:43:00 +0000</lastBuildDate>
		
			<atom:link href="https://31416.org/tags/programming/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>A Bachelier Normal Implied Volatility Solver</title>
				<link>https://31416.org/post/a-faster-bachelier-normal-implied-volatility-solver/</link>
				<pubDate>Sun, 07 Jun 2026 03:43:00 +0000</pubDate>
				<guid>https://31416.org/post/a-faster-bachelier-normal-implied-volatility-solver/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://www.clarusft.com/bachelier-model-fast-accurate-implied-volatility/&#34;&gt;Around 2014&lt;/a&gt;, I &lt;a href=&#34;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2420757&#34;&gt;proposed&lt;/a&gt; a few Bachelier implied volatility &amp;ldquo;solvers&amp;rdquo;. The first one was inspired by Steven G. Johnson&amp;rsquo;s Faddeeva package for the complex error function: it used a piecewise Chebyshev polynomial representation to have a near machine accurate representation of the Bachelier implied volatility. Why did I put &amp;ldquo;solver&amp;rdquo; in quotes? Because the problem can be reduced to a 1D function representation (as originally shown by &lt;a href=&#34;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=990747&#34;&gt;Choi, Kim and Kwak&lt;/a&gt; in 2009). Then, I was encouraged by Gary Kennedy to find a simpler rational function approximation, I used 3 or 4 rational functions to cover the full range of the Bachelier implied volatility function.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The Role of Erfcx and Erfc in the Black-Scholes Formula</title>
				<link>https://31416.org/post/black-formula-erfcx-erfc-backends/</link>
				<pubDate>Sat, 30 May 2026 03:43:00 +0000</pubDate>
				<guid>https://31416.org/post/black-formula-erfcx-erfc-backends/</guid>
				<description>&lt;p&gt;This note compares special-function choices at the level that matters to the &lt;a href=&#34;https://31416.org/post/a-faster-monotone-implied-volatility-solver/&#34;&gt;implied volatility solvers&lt;/a&gt;: the normalized Black beta price, not &lt;a href=&#34;https://31416.org/post/erfcx-cody-commons-johnson/&#34;&gt;standalone &lt;code&gt;erfcx(x)&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;For &lt;code&gt;x = log(F/K) &amp;lt;= 0&lt;/code&gt; and total volatility &lt;code&gt;s = sigma sqrt(T)&lt;/code&gt;, the beta-space OTM call price is&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;B(x, s) = 0.5 * (exp(x/2) * erfc(q1) - exp(-x/2) * erfc(q2))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;q1 = -(x/s + s/2) / sqrt(2)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;q2 = -(x/s - s/2) / sqrt(2)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The corresponding forward-normalized OTM-call price is &lt;code&gt;c = B(x, s) / sqrt(ex)&lt;/code&gt;, with &lt;code&gt;ex = exp(x)&lt;/code&gt;.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Which erfcx?</title>
				<link>https://31416.org/post/erfcx-cody-commons-johnson/</link>
				<pubDate>Sun, 24 May 2026 03:43:00 +0000</pubDate>
				<guid>https://31416.org/post/erfcx-cody-commons-johnson/</guid>
				<description>&lt;p&gt;The &lt;a href=&#34;https://31416.org/post/a-faster-monotone-implied-volatility-solver/&#34;&gt;use of erfcx&lt;/a&gt; instead of direct erfc or CDF in a Black-Scholes implied volatility solver leads to gain in accuracy and performance in general. But which erfcx should we use?&lt;/p&gt;&#xA;&lt;p&gt;This note compares practical erfcx implementations for Rust implied volatility solvers:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Commons: the local Rust port of &lt;a href=&#34;https://github.com/apache/commons-numbers/blob/master/commons-numbers-gamma/src/main/java/org/apache/commons/numbers/gamma/BoostErf.java&#34;&gt;Apache Commons Numbers&lt;/a&gt; &lt;code&gt;BoostErf.erfcx&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Cody: the &lt;a href=&#34;https://docs.rs/jaeckel/latest/jaeckel/fn.erfcx_cody.html&#34;&gt;Cody rational approximation&lt;/a&gt; exposed by the &lt;code&gt;jaeckel = 0.2.0&lt;/code&gt; crate during this comparison, originally coming from   &lt;a href=&#34;https://www.netlib.org/slatec/src/&#34;&gt;Netlib SLATEC library&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Johnson: Steven G. Johnson&amp;rsquo;s Faddeeva implementation, as exposed by &lt;code&gt;errorfunctions = 0.2.0&lt;/code&gt;, &lt;a href=&#34;https://github.com/Cactus-proj/special-functions/tree/main/sys/faddeeva-sys&#34;&gt;&lt;code&gt;faddeeva-sys = 0.1.0&lt;/code&gt;&lt;/a&gt;, and Julia &lt;code&gt;SpecialFunctions.erfcx(::Float64)&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The Commons-style implementation is a local Rust port of the &lt;a href=&#34;https://issues.apache.org/jira/si/jira.issueviews:issue-html/NUMBERS-177/NUMBERS-177.html&#34;&gt;Apache Commons Numbers/BoostErf approach&lt;/a&gt;. It computes the small central region through the local &lt;code&gt;erf&lt;/code&gt; rational approximation and uses &lt;code&gt;exp_m1(x*x)&lt;/code&gt; to avoid cancellation in &lt;code&gt;exp(x^2) * erfc(x)&lt;/code&gt; near zero. For positive inputs it uses several rational subintervals: a central polynomial/rational &lt;code&gt;erf&lt;/code&gt; branch, erfc-style rational branches around &lt;code&gt;0.5..1.5&lt;/code&gt;, &lt;code&gt;1.5..2.5&lt;/code&gt;, and &lt;code&gt;2.5..4&lt;/code&gt;,  and a rational function taken from &lt;em&gt;Rational Chebyshev approximations for the error function&lt;/em&gt;  by W. J. Cody, Math. Comp., 1969, PP. 631-638 beyond that. For very large positive &lt;code&gt;x&lt;/code&gt;, it returns &lt;code&gt;1 / (sqrt(pi) * x)&lt;/code&gt;. For negative &lt;code&gt;x&lt;/code&gt;, it uses the reflected form with a split-square exponential, returns &lt;code&gt;Inf&lt;/code&gt; below the finite overflow cutoff, and otherwise computes &lt;code&gt;2 exp(x^2) - erfcx(|x|)&lt;/code&gt; in a way that preserves more bits near the overflow boundary.&lt;/p&gt;</description>
			</item>
			<item>
				<title>A Faster Monotone Implied Volatiltty Solver</title>
				<link>https://31416.org/post/a-faster-monotone-implied-volatility-solver/</link>
				<pubDate>Sat, 23 May 2026 03:43:00 +0000</pubDate>
				<guid>https://31416.org/post/a-faster-monotone-implied-volatility-solver/</guid>
				<description>&lt;p&gt;Choi, Huh and Su have &lt;a href=&#34;https://arxiv.org/pdf/2302.08758&#34;&gt;a very good paper&lt;/a&gt; entitled  &lt;em&gt;Tighter uniform bounds for Black–Scholes implied volatility and the applications to root-finding&lt;/em&gt;. What&amp;rsquo;s particularly great is that it gives both a decent lower bound and a proof a monotone convergence using Newton&amp;rsquo;s method starting from this lower bound.&lt;/p&gt;&#xA;&lt;p&gt;The industry standard for solving the Black-Scholes implied volatility is Peter Jäckel &lt;a href=&#34;http://www.jaeckel.org/LetsBeRational.pdf&#34;&gt;&lt;em&gt;Let&amp;rsquo;s be rational&lt;/em&gt;&lt;/a&gt;. I was wondering if one could not create a robust mathematically backed solver at least as fast and accurate as Jäckel&amp;rsquo;s algorithm.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Owen Scrambling a la Burley</title>
				<link>https://31416.org/post/burley_owen_scrambling/</link>
				<pubDate>Thu, 08 Jan 2026 17:27:00 +0000</pubDate>
				<guid>https://31416.org/post/burley_owen_scrambling/</guid>
				<description>&lt;p&gt;In my &lt;a href=&#34;https://31416.org/post/owen_scrambling_in_quantlib/&#34;&gt;last post&lt;/a&gt;, I had a look at Quantlib implementation of a new scrambling method for Sobol due to&#xA;Brent Burley of Walt Disney Studios &lt;a href=&#34;https://jcgt.org/published/0009/04/01/paper.pdf&#34;&gt;Practical Hash-based Owen Scrambling&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Because it originates from the CG community, I had assumed that this was faster than the more classic scrambling &lt;a href=&#34;https://dl.acm.org/doi/10.1145/779359.779360&#34;&gt;ACM Algorithm 823&lt;/a&gt; by Hickernell and Hong. I was wrong. It may be faster for specific use cases, but in general it is (much) slower, especially for the kind of (quasi) Monte-Carlo simulation that we use in quantitative finance.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Owen Scrambling in Quantlib</title>
				<link>https://31416.org/post/owen_scrambling_in_quantlib/</link>
				<pubDate>Wed, 17 Dec 2025 17:27:00 +0000</pubDate>
				<guid>https://31416.org/post/owen_scrambling_in_quantlib/</guid>
				<description>&lt;p&gt;The state of the art of Sobol scrambling has changed slightly recently, thanks to the paper from Brent Burley of Walt Disney Studios &lt;a href=&#34;https://jcgt.org/published/0009/04/01/paper.pdf&#34;&gt;Practical Hash-based Owen Scrambling&lt;/a&gt;.&#xA;Before that, &lt;a href=&#34;https://dl.acm.org/doi/10.1145/779359.779360&#34;&gt;ACM Algorithm 823&lt;/a&gt; by Hickernell and Hong was the usual reference. Brent Burley&amp;rsquo;s algorithm is &lt;strong&gt;supposedly&lt;/strong&gt; both faster and with better properties. In particular, it performs both shuffling and scrambling.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://quantlib.wordpress.com/2024/02/03/scrambled-sobol-sequences/&#34;&gt;Peter Caspers&lt;/a&gt; implemented the new algorithm in Quantlib. It&amp;rsquo;s neat to have some decent &lt;a href=&#34;https://github.com/lballabio/QuantLib/blob/master/ql/math/randomnumbers/burley2020sobolrsg.cpp&#34;&gt;implementation in CPP&lt;/a&gt;. In applying the algorithm of the paper, a few sub-optimal choices were made:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Deep Neural Networks and Julia</title>
				<link>https://31416.org/post/deep_neural_networks_and_julia/</link>
				<pubDate>Tue, 07 Oct 2025 17:27:00 +0000</pubDate>
				<guid>https://31416.org/post/deep_neural_networks_and_julia/</guid>
				<description>&lt;p&gt;Recently, I have spent some time on simple neural networks. The idea is to employ them as universal function approximators for some problems appearing in quantitative finance. There are some great papers on it such as the one from &lt;a href=&#34;https://mathematicsinindustry.springeropen.com/articles/10.1186/s13362-019-0066-7&#34;&gt;Liu et al. (2019)&lt;/a&gt; or &lt;a href=&#34;https://arxiv.org/abs/1901.09647&#34;&gt;Horvath et al. (2019) Deep Learning Volatility&lt;/a&gt; or &lt;a href=&#34;https://arxiv.org/abs/2107.01611&#34;&gt;Rosenbaum &amp;amp; Zhang (2021)&lt;/a&gt;.&#xA;Incidentally, I met Liu back when I was finishing my PhD in TU Delft around 2020.&lt;/p&gt;&#xA;&lt;p&gt;I thought I would try out what Julia offers in terms of library for neural networks. Being a very trendy subject, and Julia a modern language for the scientific community, I had imagined the libraris to be of good quality (like the many I have been using in the past). Surprisingly, I was wrong.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Monotonicity of the Black-Scholes Option Prices in Practice</title>
				<link>https://31416.org/post/vol_monotonicity_in_practice/</link>
				<pubDate>Sun, 29 Sep 2024 12:56:42 +0100</pubDate>
				<guid>https://31416.org/post/vol_monotonicity_in_practice/</guid>
				<description>&lt;p&gt;It is well known that vanilla option prices must increase when we increase the implied volatility. Recently, a post on the Wilmott forums wondered about the true accuracy of Peter Jaeckel implied volatility solver, whether it was truely IEEE 754 compliant. In fact, the author noticed some inaccuracy in the option price itself. Unfortunately I can not reply to the forum, its login process does not seem to be working anymore, and so I am left to blog about it.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Copilot vs ChatGPT on the Optimal Finite Difference Step-Size</title>
				<link>https://31416.org/post/copilot_vs_chatgpt_optimal_step_size/</link>
				<pubDate>Thu, 25 Jul 2024 12:56:42 +0100</pubDate>
				<guid>https://31416.org/post/copilot_vs_chatgpt_optimal_step_size/</guid>
				<description>&lt;p&gt;When computing the derivative of a function by finite difference, which step size is optimal? The answer depends on the kind of difference (forward, backward or central), and the degree of the derivative (first or second typically for finance).&lt;/p&gt;&#xA;&lt;p&gt;For the first derivative, the result is very quick to find (it&amp;rsquo;s on &lt;a href=&#34;https://en.wikipedia.org/wiki/Numerical_differentiation&#34;&gt;wikipedia&lt;/a&gt;). For the second derivative, it&amp;rsquo;s more challenging. The &lt;a href=&#34;https://paulklein.ca/newsite/teaching/Notes_NumericalDifferentiation.pdf&#34;&gt;Lecture Notes&lt;/a&gt; of Karen Kopecky provide an answer. I wonder if Copilot or ChatGPT would find a good solution to the question:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Princeton Fintech and Quant conference of December 2022</title>
				<link>https://31416.org/post/princeton_fintech_conference/</link>
				<pubDate>Sun, 04 Dec 2022 07:56:42 +0100</pubDate>
				<guid>https://31416.org/post/princeton_fintech_conference/</guid>
				<description>&lt;p&gt;I recently presented my latest published paper &lt;a href=&#34;https://wilmott.com/wilmott-magazine-november-2022-issue/&#34;&gt;On the Bachelier implied volatility at extreme strikes&lt;/a&gt; at the Princeton Fintech and Quant conference.&#xA;The presenters were of quite various backgrounds. The first presentations were much more business oriented with lots of AI keywords, but relatively little technical content while the last presentation was&#xA;about parallel programming. Many were a pitch to recruit to employees.&lt;/p&gt;&#xA;&lt;p&gt;The diversity was interesting: it was refreshing to hear about quantitative finance from vastly different perspectives. The presentation from Morgan Stanley about &lt;a href=&#34;https://github.com/morganstanley/optimus-cirrus&#34;&gt;their scala annotation framework&lt;/a&gt; to ease up&#xA;parallel programming was enlightening. The main issue they were trying to solve is the necessity for all the boilerplate code to handle concurrency, caching, robustness, which obfuscates significantly the business logic in the code.&#xA;This is an old problem. Decades ago, rule engines were the trend for similar reasons. Using the example of pricing bonds, the presenters put very well forward the issues in evidence, issues that I found&#xA;very relevant.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Monte-Carlo Parallelization: to vectorize or not?</title>
				<link>https://31416.org/post/monte-carlo-vectorization-or-not/</link>
				<pubDate>Sat, 09 Apr 2022 21:56:42 +0100</pubDate>
				<guid>https://31416.org/post/monte-carlo-vectorization-or-not/</guid>
				<description>&lt;p&gt;When writing a Monte-Carlo simulation to price financial derivative contracts, the most straightforward is to code a loop over the number of paths, in which each path is fully calculated. Inside the loop, a payoff function takes this path to compute the present value of the contract on the given path. The present values are recorded to lead to the Monte-Carlo statistics (mean, standard deviation).&#xA;I ignore here any eventual callability of the payoff which may still be addressed with some work-arounds in this setup. The idea can be schematized by the following go code:&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;for&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;i&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;:=&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;i&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;numSimulations;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;i&lt;span style=&#34;color:#666&#34;&gt;++&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;{&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#x9;&lt;/span&gt;pathGenerator.&lt;span style=&#34;color:#06287e&#34;&gt;ComputeNextPath&lt;/span&gt;(&lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;path)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#007020&#34;&gt;//path contains an array of n time-steps of float64.&lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#x9;&lt;/span&gt;pathEvaluator.&lt;span style=&#34;color:#06287e&#34;&gt;Evaluate&lt;/span&gt;(&lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;path,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;output)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#x9;&lt;/span&gt;statistics.&lt;span style=&#34;color:#06287e&#34;&gt;RecordValue&lt;/span&gt;(output)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#xA;A python programmer would likely not write a simulation this way, as the python code inside the large loop will not be fast. Instead, the python programmer will write a vectorized simulation, generating all paths at the same time.&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pathGenerator.&lt;span style=&#34;color:#06287e&#34;&gt;ComputeAllPaths&lt;/span&gt;(&lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;paths)&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;&lt;span style=&#34;color:#007020&#34;&gt;//paths contains an array of n time-steps of vectors of size numSimulations &lt;/span&gt;&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pathEvaluator.&lt;span style=&#34;color:#06287e&#34;&gt;EvaluateAll&lt;/span&gt;(&lt;span style=&#34;color:#666&#34;&gt;&amp;amp;&lt;/span&gt;paths,&lt;span style=&#34;color:#bbb&#34;&gt; &lt;/span&gt;output)&lt;span style=&#34;color:#bbb&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;statistics.&lt;span style=&#34;color:#06287e&#34;&gt;RecordValues&lt;/span&gt;(output)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
			</item>
			<item>
				<title>More Automatic Differentiation Awkwardness</title>
				<link>https://31416.org/post/more-automatic-differentiation-awkwardness/</link>
				<pubDate>Tue, 04 Jan 2022 21:56:42 +0100</pubDate>
				<guid>https://31416.org/post/more-automatic-differentiation-awkwardness/</guid>
				<description>&lt;p&gt;&lt;a href=&#34;https://quantsrus.github.io/post/exp_b_spline_collocation_autodiff/&#34;&gt;This blog post&lt;/a&gt; from Jherek Healy presents some not so obvious behavior of automatic differentiation, when a function is decomposed&#xA;into the product of two parts where one part goes to infinity and the other to zero, and we know the overall result must go to zero (or to some other specific number).&#xA;This decomposition may be relatively simple to handle for the value of the function, but becomes far less trivial to think of in advance, at the derivative level.&lt;/p&gt;</description>
			</item>
			<item>
				<title>More on random number generators</title>
				<link>https://31416.org/post/more-on-random-number-generators/</link>
				<pubDate>Sat, 10 Oct 2020 20:56:42 +0100</pubDate>
				<guid>https://31416.org/post/more-on-random-number-generators/</guid>
				<description>&lt;p&gt;My &lt;a href=&#34;https://31416.org/post/war-of-the-random-number-generators/&#34;&gt;previous post&lt;/a&gt; described the recent view on random number generators, with a focus on the Mersenne-Twister war.&lt;/p&gt;&#xA;&lt;p&gt;Since, I have noticed another front in the war of the random number generators:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://arxiv.org/abs/1806.05243&#34;&gt;An example in dimension 121 from K Savvidy&lt;/a&gt; where L&amp;rsquo;Ecuyer MRG32k3a fails to compute the correct result, regardless of the seed. This is a manufactured example, such that the vector, used in the example, falls in the dual lattice of the generator. Similar examples can be constructed for other variants.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://pubsonline.informs.org/doi/abs/10.1287/ijoc.2018.0878&#34;&gt;Spectral Analysis of the MIXMAX Random Number Generator&lt;/a&gt; (by L&amp;rsquo;Ecuyer et al.) shows defects in MIXMAX, for some parameters that were advised in earlier papers of K. Savvidy. MIXMAX is a RNG popularized by K. Savvidy, used &lt;a href=&#34;https://cdcvs.fnal.gov/redmine/projects/g4/wiki/RNDM-Geant4104&#34;&gt;in CLHEP at Fermilab&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Also, I found interesting that Monte-Carlo simulations run at the Los Alamos National Laboratory relied on a relatively simple linear congruential generator (LCG) producing 24- or 48-bits integers &lt;a href=&#34;https://mcnp.lanl.gov/pdf_files/la-ur-11-04859.pdf&#34;&gt;for at least 40 years&lt;/a&gt;. LCGs are today touted as some of the worst random number generators, exhibiting strong patterns in 2D projections. Also the period chosen was very small by today&amp;rsquo;s standards: 7E13.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The war of the random number generators</title>
				<link>https://31416.org/post/war-of-the-random-number-generators/</link>
				<pubDate>Thu, 17 Sep 2020 20:56:42 +0100</pubDate>
				<guid>https://31416.org/post/war-of-the-random-number-generators/</guid>
				<description>&lt;p&gt;These days, there seems to be some sort of small war to define what is a modern good random number generators to advise for simulations.&#xA;Historically, the Mersenne-Twister (MT thereafter) won this war. It is used by default in many scientific libraries and software, even if there has been a few issues with it:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;A bad initial seed may make it generate a sequence of low quality for at least as many as 700K numbers.&lt;/li&gt;&#xA;&lt;li&gt;It is slow to jump-ahead, making parallelization not so practical.&lt;/li&gt;&#xA;&lt;li&gt;It fails some TestU01 Bigcrush tests, mostly related to the F2 linear algebra, the algebra of the Mersenne-Twister.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;It turns out, that before MT (1997), a lot of the alternatives were much worse, except, perhaps, &lt;a href=&#34;https://arxiv.org/abs/hep-lat/9309020&#34;&gt;RANLUX&lt;/a&gt; (1993), which is quite slow due to the need of skipping many points of the generated sequence.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Sobol with 64-bits integers</title>
				<link>https://31416.org/post/sobol-64-bits/</link>
				<pubDate>Wed, 09 Sep 2020 20:56:42 +0100</pubDate>
				<guid>https://31416.org/post/sobol-64-bits/</guid>
				<description>&lt;p&gt;A while ago, I wondered how to make some implementation of Sobol support 64-bits integers (long) and double floating points. &lt;a href=&#34;https://en.wikipedia.org/wiki/Sobol_sequence&#34;&gt;Sobol&lt;/a&gt; is the most used&#xA;quasi random number generator (QRNG) for (quasi) Monte-Carlo simulations.&lt;/p&gt;&#xA;&lt;p&gt;The standard Sobol algorithms are all coded with 32-bits integers and lead to double floating point numbers which can not be smaller than&#xA;\( 2^{-31} \). I was recently looking back at the internals at Sobol generators, and noticed that generating with 64-bits integers would not help much.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Intel failure and the future of computing</title>
				<link>https://31416.org/post/intel-failures-and-the-future/</link>
				<pubDate>Fri, 24 Jul 2020 20:56:42 +0100</pubDate>
				<guid>https://31416.org/post/intel-failures-and-the-future/</guid>
				<description>&lt;p&gt;What has been happening to the INTC stock today may be revealing of the future. The stock dropped more than 16%, mainly because they announced that their 7nm process does not work (well) and they may rely on an external foundry for their processors. Initially, in 2015, they thought they would have 8nm process by 2017, and 7nm by 2018. They are more than 3 years late.&lt;/p&gt;&#xA;&lt;p&gt;Intel used to be a leader in the manufacturing process for microprocessor. While the company has its share of internal problems, it may also be that we are starting to hit the barrier, where it becomes very difficult to improve on the existing. The end of Moore’s law has been announced many times, it was already a subject 20 years ago. Today, it may be real, if there is only a single company capable of manufacturing processor using a 5nm process (TSMC).&lt;/p&gt;</description>
			</item>
			<item>
				<title>Numba, Pypy Overrated?</title>
				<link>https://31416.org/post/python-numba-overrated/</link>
				<pubDate>Tue, 12 Feb 2019 20:56:42 +0100</pubDate>
				<guid>https://31416.org/post/python-numba-overrated/</guid>
				<description>&lt;p&gt;Many benchmarks show impressive performance gains with the use&#xA;of &lt;a href=&#34;https://numba.pydata.org/&#34;&gt;Numba&lt;/a&gt; or &lt;a href=&#34;https://www.pypy.org/&#34;&gt;Pypy&lt;/a&gt;. Numba allows to compile just-in-time some specific methods, while Pypy takes&#xA;the approach of compiling/optimizing the full python program: you use it just like the standard&#xA;python runtime. From those benchmarks, I imagined that those  tools would improve my 2D Heston PDE solver&#xA;performance easily. The initialization part of my program contains embedded for loops over several 10Ks elements.&#xA;To my surprise, numba did not improve anything (and I had to isolate the code, as it would&#xA;not work on 2D numpy arrays manipulations that are vectorized). I surmise it does not play well&#xA;with scipy sparse matrices.&#xA;Pypy did not behave better, the solver became actually slower than with the standard python&#xA;interpreter, up to twice as slow, for example, in the case of the main solver loop which only does matrix multiplications and LU solves sparse systems. I did not necessarily expect any performance improvement in this specific loop, since it only consists in a few calls to expensive scipy calculations. But I did not expect a 2x performance drop either.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Fixing NaNs in Quadprog</title>
				<link>https://31416.org/post/quadprog-nans/</link>
				<pubDate>Sun, 07 Oct 2018 20:56:42 +0100</pubDate>
				<guid>https://31416.org/post/quadprog-nans/</guid>
				<description>&lt;p&gt;Out of curiosity, I tried &lt;a href=&#34;https://github.com/cran/quadprog&#34;&gt;quadprog&lt;/a&gt; as &lt;a href=&#34;https://quantsrus.github.io/post/state_of_convex_quadratic_programming_solvers/&#34;&gt;open-source quadratic programming convex optimizer&lt;/a&gt;, as it is looks fast, and the code stays relatively simple. I however stumbled on cases where the algorithm would return NaNs even though my inputs seemed straighforward. Other libraries such as CVXOPT did not have any issues with those inputs.&lt;/p&gt;&#xA;&lt;p&gt;Searching on the web, I found that I was not the only one to stumble on this kind of issue with quadprog. In particular, in 2014, Benjamen Tyner &lt;a href=&#34;http://r.789695.n4.nabble.com/quadprog-solve-QP-sometimes-returns-NaNs-td4697548.html&#34;&gt;gave a simple example in R&lt;/a&gt;, where solve.QP returns NaNs while the input is very simple: an identity matrix with small perturbations out of the diagonal. Here is a copy of his example:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Senior Developers Don&#39;t Know OO Anymore</title>
				<link>https://31416.org/post/senior-developers-dont-know-oo-anymore/</link>
				<pubDate>Thu, 08 Mar 2018 20:56:42 +0100</pubDate>
				<guid>https://31416.org/post/senior-developers-dont-know-oo-anymore/</guid>
				<description>&lt;p&gt;It has been a while since the good old object-oriented (OO) programming is not trendy anymore. Functional programming or more dynamic programming (Python-based) have been the trend, with an excursion in template based programming for C++ guys. Those are not strict categories: Python can be used in a very OO way, but it&amp;rsquo;s not how it is marketed or considered by the community.&lt;/p&gt;&#xA;&lt;p&gt;Recently, I have seen some of the ugliest refactoring in my life as a programmer, done by someone with at least 10 years of experience programming in Java. It is a good illustration because the piece of code is particularly simple (although I won&amp;rsquo;t bother with implementation details). The original code was a simple boolean method on an object such as&lt;/p&gt;</description>
			</item>
			<item>
				<title>SVN is dead</title>
				<link>https://31416.org/post/svn_is_dead/</link>
				<pubDate>Tue, 26 Sep 2017 23:56:42 +0100</pubDate>
				<guid>https://31416.org/post/svn_is_dead/</guid>
				<description>&lt;p&gt;A few years ago, when &lt;a href=&#34;https://git-scm.com/&#34;&gt;Git&lt;/a&gt; was rising fast and &lt;a href=&#34;https://subversion.apache.org/&#34;&gt;SVN&lt;/a&gt; was already not hype anymore, a friend thought that SVN was for many organizations better suited than Git, with the following classical arguments, which were sound at the time:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Who needs decentralization for a small team or a small company working together?&lt;/li&gt;&#xA;&lt;li&gt;‎SVN is proven, works well and is simple to use and put in place.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Each argument is in reality not so strong. It becomes clear now that Git is much more established.&lt;/p&gt;</description>
			</item>
			<item>
				<title>The Neural Network in Your CPU</title>
				<link>https://31416.org/post/the_neural_network_in_your_cpu/</link>
				<pubDate>Sun, 06 Aug 2017 23:56:42 +0100</pubDate>
				<guid>https://31416.org/post/the_neural_network_in_your_cpu/</guid>
				<description>&lt;p&gt;Machine learning and artificial intelligence are the current hype (again). In their new Ryzen processors, &lt;a href=&#34;http://www.anandtech.com/Gallery/Album/5197#18&#34;&gt;AMD advertises the Neural Net Prediction&lt;/a&gt;. It turns out this is was already used in their older (2012) Piledriver architecture used for example in the &lt;a href=&#34;http://www.anandtech.com/show/5831/amd-trinity-review-a10-4600m-a-new-hope&#34;&gt;AMD A10-4600M&lt;/a&gt;. It is also present in recent Samsung processors such as &lt;a href=&#34;https://www.theregister.co.uk/2016/08/22/samsung_m1_core/&#34;&gt;the one powering the Galaxy S7&lt;/a&gt;. What is it really?&lt;/p&gt;&#xA;&lt;p&gt;The basic idea can be traced to a paper from Daniel Jimenez and Calvin Lin &lt;a href=&#34;https://www.cs.utexas.edu/~lin/papers/hpca01.pdf&#34;&gt;&amp;ldquo;Dynamic Branch Prediction with Perceptrons&amp;rdquo;&lt;/a&gt;, more precisely described in the subsequent paper &lt;a href=&#34;http://taco.cse.tamu.edu/pdfs/tocs02.pdf&#34;&gt;&amp;ldquo;Neural methods for dynamic branch prediction&amp;rdquo;&lt;/a&gt;. Branches typically occur  in &lt;code&gt;if-then-else&lt;/code&gt; statements. &lt;a href=&#34;https://en.wikipedia.org/wiki/Branch_predictor&#34;&gt;Branch prediction&lt;/a&gt; consists in guessing which code branch, the &lt;code&gt;then&lt;/code&gt; or the &lt;code&gt;else&lt;/code&gt;, the code will execute, thus allowing to precompute the branch in parallel for faster evaluation.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Benham disc in web canvas</title>
				<link>https://31416.org/post/benham_disc_in_web_canvas/</link>
				<pubDate>Mon, 10 Jul 2017 23:56:42 +0100</pubDate>
				<guid>https://31416.org/post/benham_disc_in_web_canvas/</guid>
				<description>&lt;p&gt;Around 15 years ago, I wrote a small Java applet to try and show the &lt;a href=&#34;https://en.wikipedia.org/wiki/Benham%27s_top&#34;&gt;Benham disk&lt;/a&gt; effect. Even back then applets were already passé and Flash would have been more appropriate. These days, no browser support Java applets anymore, and very few web users have Java installed. Flash also mostly disappeared. The &lt;a href=&#34;https://www.w3schools.com/html/html5_canvas.asp&#34;&gt;web canvas&lt;/a&gt; is today&amp;rsquo;s standard allowing to embbed animations in a web page.&#xA; &#xA;&#xA;This effect shows color perception from a succession of black and white pictures. It is a computer reproduction from the Benham disc with ideas borrowed from &#34;Pour La Science Avril/Juin 2003&#34;.&#xA;Using a delay between 40 and 60ms, the inner circle should appear &lt;font color=&#34;#770000&#34;&gt;red&lt;/font&gt;, the one in the middle &#xA;&lt;font color=&#34;#000077&#34;&gt;blue&lt;/font&gt; and the outer one &lt;font color=&#34;#007700&#34;&gt;green&lt;/font&gt;. When you reverse the rotation direction,&#xA;blue and red circles should be inverted.&#xA;&#xA;&lt;form&gt;&#xA;  Delay: &lt;input type=&#34;number&#34; name=&#34;delay&#34; value=&#34;60&#34; id=&#34;delayInput&#34;&gt; Reverse &lt;input type=&#34;checkbox&#34; value=&#34;false&#34; id=&#34;reverseInput&#34; onclick=&#34;javascript:reverse()&#34;&gt; &lt;input type=&#34;button&#34; value=&#34;Start&#34; onclick=&#34;javascript:startStop()&#34; id=&#34;startButton&#34;&gt;&#xA;&lt;/form&gt;&#xA;&#xA;&lt;canvas id=&#34;myCanvas&#34; width=&#34;480&#34; height=&#34;480&#34; style=&#34;border:1px solid #000000;&#34;&gt;&#xA;&lt;/canvas&gt; &#xA;&#xA;&lt;script type=&#34;text/javascript&#34;&gt;&#xA;var c = document.getElementById(&#34;myCanvas&#34;);&#xA;  c.style.width =&#39;100%&#39;;&#xA;  c.style.height=&#39;100%&#39;;&#xA;  // ...then set the internal size to match&#xA;  c.width  = c.offsetWidth;&#xA;  c.height = c.offsetWidth;&#xA;var x=c.width/2;&#xA;var y=x;&#xA;linewidth = c.width / 100;&#xA;var g = c.getContext(&#34;2d&#34;);&#xA;&#xA;function paintImage(g, x,y,startArcAngle) {&#xA;var radius = 0.9;&#xA;var r = radius*x; endAngle = 2*Math.PI/3+startArcAngle;&#xA;g.beginPath();&#xA;g.arc(x, y, r, Math.PI/3+startArcAngle, endAngle, false);&#xA;g.lineWidth = linewidth;&#xA;g.strokeStyle = &#34;black&#34;;&#xA;g.stroke();&#xA;&#xA;radius = 0.8; r = radius*x;&#xA;g.beginPath();&#xA;g.arc(x, y, r + 1, Math.PI/3+startArcAngle, endAngle, false);&#xA;g.stroke();&#xA;&#xA;radius = 0.7; r = radius*x;&#xA;g.beginPath();&#xA;g.arc(x, y, r + 1, Math.PI/3+startArcAngle, endAngle, false);&#xA;g.stroke();&#xA;&#xA;radius = 0.6; r = radius*x; endAngle = Math.PI/3+startArcAngle;&#xA;g.beginPath();&#xA;g.arc(x, y, r + 1, 0+startArcAngle, endAngle, false); &#xA;g.stroke();&#xA;&#xA;radius = 0.5; r = radius*x;&#xA;g.beginPath();&#xA;g.arc(x, y, r + 1, 0+startArcAngle, endAngle, false); &#xA;g.stroke();&#xA;&#xA;radius = 0.4; r = radius*x;&#xA;g.beginPath();&#xA;g.arc(x, y, r + 1, 0+startArcAngle, endAngle, false);&#xA;g.stroke();&#xA;&#xA;//  paintImage(g, startArcAngle, 60, 0.3); //red -180 to -60&#xA;radius = 0.3; r = radius*x; endAngle = Math.PI+startArcAngle;// if (endAngle &gt; Math.PI*2) endAngle = endAngle - 2*Math.PI &#xA;g.beginPath();&#xA;g.arc(x, y, r + 1,  2*Math.PI/3+startArcAngle, endAngle, false); &#xA;g.stroke();&#xA;        &#xA;radius = 0.2; r = radius*x;&#xA;g.beginPath();&#xA;g.arc(x, y, r + 1,  2*Math.PI/3+startArcAngle, endAngle, false); &#xA;g.stroke();&#xA;&#xA;radius = 0.1; r = radius*x;&#xA;g.beginPath();&#xA;g.arc(x, y, r + 1,  2*Math.PI/3+startArcAngle, endAngle, false); &#xA;g.stroke();&#xA;&#xA;g.beginPath();&#xA;g.arc(x, y, x,  Math.PI+startArcAngle, Math.PI*2+startArcAngle, false); &#xA;g.fill();&#xA;}&#xA;&#xA;var delay = 40;&#xA;var currentAnimate = 0;&#xA;var animationStartTime = window.performance.now();&#xA;var currentIndex = 3;&#xA;var angles = [0.0, 2*Math.PI/3, 4*Math.PI/3];&#xA;&#xA;var offscreenCanvas = [document.createElement(&#39;canvas&#39;),document.createElement(&#39;canvas&#39;),document.createElement(&#39;canvas&#39;)];&#xA;for (var i in offscreenCanvas) {&#xA;  offscreenCanvas[i].width = c.offsetWidth;&#xA;  offscreenCanvas[i].height = c.offsetWidth;&#xA;  g = offscreenCanvas[i].getContext(&#34;2d&#34;);&#xA;  paintImage(g, x, y, angles[i]);&#xA;}&#xA;g = c.getContext(&#34;2d&#34;);&#xA;&#xA;//function animate0() {&#xA;//  g.clearRect(0,0,c.width, c.height);&#xA;//  paintImage(g,x, y,  0.0);&#xA;//  currentAnimate = setTimeout(animate1, delay);&#xA;//}&#xA;//function animate1() {&#xA;//  g.clearRect(0,0,c.width, c.height);&#xA;//  paintImage(g,x, y,  2*Math.PI/3);&#xA;//  currentAnimate = setTimeout(animate2, delay);&#xA;//}&#xA;//function animate2() {&#xA;//  g.clearRect(0,0,c.width, c.height);&#xA;//  paintImage(g,x, y, 4*Math.PI/3);&#xA;//  currentAnimate= setTimeout(animate0, delay);&#xA;//}&#xA;&#xA;window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||&#xA;                              window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;&#xA;&#xA;&#xA;function animateContinuous(time) {&#xA;  var index = Math.floor(((time - animationStartTime) % (3*delay))/delay);&#xA;  if (index &lt; 0) index = 0&#xA;  if (index != currentIndex) {&#xA;    //g.clearRect(0,0,c.width, c.height);&#xA;    //paintImage(g, x, y, angles[index]);&#xA;    var offscreenContext = offscreenCanvas[index].getContext(&#39;2d&#39;);&#xA;    var image = offscreenContext.getImageData(0,0,c.width,c.height); &#xA;    g.putImageData(image, 0, 0);       &#xA;    currentIndex = index;&#xA;  }&#xA;  currentAnimate = requestAnimationFrame(animateContinuous);&#xA;}&#xA;&#xA;function reverse() {&#xA;  //tmp = angles[2]; angles[2] = angles[0]; angles[0] = tmp;&#xA;  tmp = offscreenCanvas[2]; offscreenCanvas[2] = offscreenCanvas[0]; offscreenCanvas[0] = tmp;&#xA;}&#xA;&#xA;function startStop() {&#xA;  var elem = document.getElementById(&#34;startButton&#34;);&#xA;  var delayElem = document.getElementById(&#34;delayInput&#34;);&#xA; if (elem.value==&#34;Stop&#34;) {&#xA;    elem.value = &#34;Start&#34;;&#xA;    //clearTimeout(currentAnimate);&#xA;    window.cancelAnimationFrame(currentAnimate);&#xA;    currentAnimate = 0;&#xA;  } else {&#xA;    elem.value = &#34;Stop&#34;;&#xA;    delay = delayElem.value;&#xA;    animationStartTime = window.performance.now();&#xA;    //animate0();&#xA;    currentAnimate = requestAnimationFrame(animateContinuous);&#xA;  }&#xA;}&#xA;&lt;/script&gt;&#xA;&#xA;&lt;/p&gt;</description>
			</item>
			<item>
				<title>Carmack &amp; GPGPU programming</title>
				<link>https://31416.org/post/carmack--gpgpu-programming/</link>
				<pubDate>Sun, 14 Aug 2011 10:20:00 +0000</pubDate>
				<guid>https://31416.org/post/carmack--gpgpu-programming/</guid>
				<description>&lt;p&gt;Finally someone who shares the same opinion on the current state of GPGPU programming.&lt;/p&gt;&#xA;&lt;p&gt;John Carmack: On the other hand, we have converted all of our offline processing stuff to ray tracing. For years, the back-end MegaTexture generation for Rage was done with&amp;hellip; we had a GPGPU cluster with NVIDIA cards and it was such a huge pain to keep. It was an amazing pain where one system would be having heat problems and would be behaving weird even though we thought they had identical drivers. Something would always be wrong with render farm 12, and whenever we wanted to put in new features it was like “Okay, writing new fragment programs to go into this.” Now, granted I did this just when CUDA was in its infancy. If I did re-implement it with OpenCL or CUDA we wouldn’t have some of these problems, but when I converted all these over to ray tracing there was a number of things that got a lot better. Things that we deal with, for example shadows and reflections that have to be approximated, and were so used to doing with rasterization&amp;hellip; we sometimes forget how big of hacks these are. To be able to say I really just want that ray, and tell me what it hit; not do a projection with feathering shadowed edges and whatever the heck else we’re doing there, so much of the code got so much easier. If it’s a choice of&amp;hellip; now that we have these awesome multi-core x86 CPUs where we can get 24 threads in commodity boxes&amp;hellip; it’s true that one GPU card can do more ray tracing than one 24 thread x86 box, but it’s not multiples more and if it’s just a matter of buying more $2000 boxes, it makes the development, maintenance, and upkeep much better. While everyone in high performance computing is all “rah-rah” GPUs right now, I’ve come full circle back around to saying the fact that we can get massive amounts of x86 cores and threads&amp;hellip; it wont win on FLOPS/watt or FLOPS/volume, but in terms of results per developer hour it is much, much better.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Interesting Plug-In Framework - DPML Transit</title>
				<link>https://31416.org/post/interesting-plug-in-framework---dpml-transit/</link>
				<pubDate>Thu, 29 Sep 2005 15:20:00 +0000</pubDate>
				<guid>https://31416.org/post/interesting-plug-in-framework---dpml-transit/</guid>
				<description>&lt;p&gt;Today, I just found out about  &lt;a href=&#34;http://dpml.net/transit/latest/overview.html&#34;&gt;DPML Transit&lt;/a&gt;, it is a small framework that helps you build plug-ins based software. It seems to work a bit with &lt;a href=&#34;http://dpml.net/magic/latest/index.html&#34;&gt;DPML Magic&lt;/a&gt;, their build system based upon Ant. Both are quite interesting, since in big projects, you often end up with a packaging per component (which DPML Magic seems to make very simple) and a versioning of those components. DPML Transit allows then for an efficient way to look up a particular version of one component.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Is Prolog Better Suited Than SQL?</title>
				<link>https://31416.org/post/is-prolog-better-suited-than-sql/</link>
				<pubDate>Mon, 26 Sep 2005 15:36:00 +0000</pubDate>
				<guid>https://31416.org/post/is-prolog-better-suited-than-sql/</guid>
				<description>&lt;p&gt;I am currently reading a Prolog book &lt;em&gt;Artificial Intelligence Through Prolog&lt;/em&gt;, I have been doing a bit of Prolog when I was very young and wanted to refresh my memory a bit. It is a very interesting read, especially when I take the viewpoint of our current application where no ACID compliance is required.&lt;/p&gt;&#xA;&lt;p&gt;It seems to me that all the logic we coded to parametrize SQL queries and construct them dynamically could have been avoided if we had chosen Prolog as Prolog expressions would have been very natural to use in our project. With Prolog, there is no need to think about joins, type of joins, SQL syntax. It is at the level just higher. I wonder very much why Prolog did not become more mainstream as it seems to solve some problems in a much nicer, natural way.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Java is more productive than Ruby/Rails</title>
				<link>https://31416.org/post/java-is-more-productive-than-rubyrails/</link>
				<pubDate>Tue, 26 Jul 2005 13:26:00 +0000</pubDate>
				<guid>https://31416.org/post/java-is-more-productive-than-rubyrails/</guid>
				<description>&lt;p&gt;I have been doing some Ruby On Rails, for 2 small projects. While I think it is good, I think it is overhyped as well. It is well designed, has good ideas (easy configuration), and focus on the right problem, architecture. But my conclusion is that I am not more productive with it than with Java.&lt;/p&gt;&#xA;&lt;p&gt;I think most of the development time is not spent coding, but thinking. It is a very obvious statement, and yet too often ignored.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
