Is Julia reliable for solving ordinary and stochastic differential equations?

I got a bit worried about using Julia after reading Yuri Vishnevsky’s article (“Why I no longer recommend Julia”). I want to use this language for solving ordinary and stochastic differential equations. Besides this, I also want to use random number generator (this would already be embedded in the stochastic DE solver). Kindly, let me know if Julia is reliable for at least these tasks? That is, are those correctness and composability issues not present at all in the tasks mentioned above?

P.S.: I know C++, Matlab, and R. Matlab is too slow for solving ODEs (R would have a similar speed, haven’t tried). I could not get sufficient demo examples on how to use an ODE solver (say, Dopri5) in C++.

1 Like

The article started a lot of discussions and many opinions have been expressed on this matter. I am sure you can find them.

You are essentially asking whether Julia and a set of libraries written in Julia are bug-free.

EDIT: I should add that the Julian ecosystem around differential equations is one of the most mature ones, and you should expect no issues using it. See SciML Scientific Machine Learning Showcase

3 Likes

Thanks for the reply. Yes, I was asking if SciML/DifferentialEquations.jl (and random number generator) is bug free?

The answer to that is no - but I’m afraid the answer for any modestly complex piece of software will be no, e.g. here is the list of bug fixes for the next MATLAB release:

https://uk.mathworks.com/support/faq/pr_bugs.html

This is just a fact of life so you will have to think about ways to deal with it, which I presume mostly will revolve around testing results you’re producing against things you know to be true.

6 Likes

Thanks for the reply. Couldn’t believe that even Matlab could have so many bugs. In this respect, my question could be seen as [In comparison with Matlab] is Julia reliable…

Yes, Julia has one of the most advanced ODE and SDE framework, including both capabilities and reliability.

However, it is extremely important to always program defensively (write a ton of assertions and consistency checks) no matter the language or framework you use. You already saw the example about Matlab above. I have used (and contributed to some of) matlab, mathematica, maple, sympy, numpy, scipy, tensorflow, and pytorch – all of them occasionally have had terrible bugs and I would have wasted weeks or even published scientifically wrong results if I was not in the habit of programming defensively. Julia is truly not any more or less stable when averaging over a workload and its pitfalls (e.g. it has a younger ecosystem, but some of the ecosystem is better integrated, some parts of the ecosystem are in heavy development, but some are better than anything else in existence, it has fewer packages, but the package management and reproducibility story is better, etc – plenty pros and cons when you do an in-depth comparison).

4 Likes

Every software has bugs. That said, our solvers have one of the most active developer communities and a very strong bug tracker and test suite. See:

which tracks known issues (note that most of the issues are “new algorithm”, i.e. algorithms we are looking to implement). Along with our issue tracking, we have a test suite which currently takes around 25-30 hours to run which tests all sorts of numerical things. See for example:

That’s just for ODEs, and that’s a much larger test suite than what I can find in all of the other open source ODE solvers combined! Everything from convergence rates to high precision arithmetic (and convergence with high precision arithmetic) etc. are tracked and documented.

SDEs then have their own full set of tens of hours of tests:

(though some started timing out because we are trying to do very high precision weak convergence testing with GPUs where the original paper required an HPC, long story but we’re buying new hardware for that).

But I think the right way to say it is, the SciML organization has a very big history of mixing integration testing with downstream testing, including integrating tests from proprietary software like Pumas that’s used in locked down clinical settings (https://pumas.ai/), and over time this monster of a test set has become pretty robust.

I think the robustness of the test set is best explained with an anecdote. For the development of DP5, we wanted a version that would exactly match the Fortran dopri5 code (and same with DP8 with dop853). When doing the regression testing, we found we can only match if we set the inital dt… so something was up. When we dug around, we realized that the original dopri5 code actually has a bug in it, where it’s missing a /length(u) in the second norm calculation and thus makes the init dt guess dependent on the size of the ODE (i.e. if you have the same ODE and keep repeating it, you do not get a constant init dt guess but instead it converges to zero). This of course is in comparison to the formula stated in Hairer’s book, and the one in dop853, so we reported it and confirmed that it is the case that the 1970’s dopri5 everyone wraps did have a bug in it. It’s pretty harmless, but :person_shrugging: it can’t pass our tests haha.

Another fun anecdote is that the C wrapped lsoda implementation that many use (scipy, R) is actually 1-based. In order to ensure the calculation it gives back is correct, it allocates its arrays with one slot extra and then returns an array with the pointer shifted one over. This is an artifact of the fact that it’s a Fortran translation:

This is why it has some issues with some BLAS wrappers. We found this out when doing performance tests of QNDF and building the wrapper GitHub - rveltz/LSODA.jl: A julia interface to the LSODA solver, finding that it was allocating more memory than it should.

So is our code bug free? No, but what we are doing is making sure it gets better everyday and are open about every issue we have. In fact, it’s probably easier to write such a blog post about SciML tools than most other tools simply because we are open and will tell you what tests are failing. If you want to write an inflammatory blog post that bugs exists, here’s the materials right here! Issues · SciML/OrdinaryDiffEq.jl · GitHub . However, the fact that it’s very difficult to write such a blog post about the current known bugs with MATLAB’s solvers is not indicative of it not having bugs, it’s indicative of the current issues not clearly communicated.

Also, as you can see from the tracker, most of the issues have a clear exit or warn.

24 Likes

Thanks. Yes, this is why I’ve decided to write the same code in Matlab also, as a way of comparing.

Thanks for such a detailed explanation.

The very first bug of that list is quite impressive

Aerospace Toolbox [2748178]
In certain cases, pointAt method of satellite scenario Satellite class interprets Euler angle inputs in radians rather than degrees

2 Likes

You might know this, but putting it out here: Writing to separate implementations in two different languages is (1) a lot of work and (2) it usually uncovers superficial typo-like errors, not modeling errors. It is extremely valuable to put in some more fundamental checks (and that is frequently less work): e.g. check that energy or other invariants are conserved, check simple cases with analytical solutions, check reproducibility and statistical properties of the solutions, etc.

2 Likes

I see from last month:
2023: MIT Center for Computational Science & Engineering MathWorks Prize for Outstanding Master’s Research in Computational Science & Engineering. For Songchen Tan (MIT Julia Lab) for his work on TaylorDiff.jl for use NeuralPDE.jl physics-informed neural networks (PINNs)

So it’s a Prize (also) in the name of MathWorks, i.e. the maker of MATLAB. The SciML ecosystem if for sure doing something (well man things) right. The only language (of those) potentially competing on speed with Julia is C++. The others not unless you can wrap fast libraries from other fast languages, and that can be done for e.g. BLAS, but I understand more challenging for solving equations.

I believe all the issues Yuri brought up, are solvable, if not already, and the only really interesting intriguing issue he brought up that time was OffsetArrays.jl, that I very much doubt is an issue for solving your equations:

There is a lot of problems with OffsetArrays.jl but most other languages do not even something like OffsetArrays.jl or the expectation that most code written would automatically work with custom indexes.

I (still) have full confidence in Julia core developers and e.g. Chris, for math/technical computing, such as you bring up. Julia however isn’t bug-free (no software ever will be), but issues are handled well.

Yuri no longer has any open PR in Julia, all of his 11 have been merged or closed. But he also has open issues, including 2 from 2 weeks ago, rather interesting:

Issues · JuliaLang/julia · GitHub [after clicking the link the + needs to be changed to a space; I’m not sure how to put in a correct link for Discource, it breaks if I do it, so I’m not sure it’s possible…]

Note, I think all integer and floating-point division is correct in Julia for all types (handled by CPU instructions, i.e. assuming correctly), from his issue, it’s about floored division (e.g. div)

That error rate suggests that this bug manifests once out of every ~1,700 randomly chosen Float16 divisions
[…]
Based on a billion samples, the bug manifests once out of every ~10,000 randomly chosen Float32 divisions and once out of every ~74,000 Float64 divisions.

Division (and e.g. square root) CAN be correct, in general, can only be correctly rounded, so you always have a small error. According to chaos theory, small errors can blow up. I don’t think this is too worrying, i.e. to have a tiny bit smaller error, than the correctly rounded result. If you’re sensitive to it, then most likely the small error in the correctly rounded error too?

I’m curious, for differential equations, you can have arbitrary operators, e.g. division common, but would you have floored division often (or ever), or div? If not, then you don’t need to worry about that issue at least.

Since Yuri was posting new issues recently, he at least cares about Julia, and likely still uses, or why would he even have know or posted those two weeks ago.

1 Like

Thanks for the input. Yes, I do believe that eventually all the concerns raised by Yuri will get sorted out. I wouldn’t have wasted a few months on Matlab and C++ if I had not got disillusioned by Yuri’s article (though I believe that his criticism turned out to be highly valuable for the language) and this need of knowing a few guidelines for writing efficient Julia codes, which otherwise can give much slower performance than, say, Python.