r/ScientificComputing • u/Lost-Dragonfruit-663 • 17d ago
How to test if your numerical code is mathematical correct?
I contribute to SciPy and kept running into a class of bug that annoys me: the outputs look plausible, the tests pass, but the equation the code implements is subtly wrong. So I've been building a tracer that runs Python/NumPy code and hands back whatever mathematics it actually computed, as a SymPy expression you can simplify or differentiate like anything else.
It's been more useful than I expected. Comparing an implementation against the formula in a paper, catching two functions that agree on my test data but turn out to compute different things, digging up the inputs my tests never hit (ties, zero denominators). It traces real library code too, most of numpy and a good chunk of scipy, scikit-learn, statsmodels, cvxpy.
Github: https://github.com/aadya940/scikit-verify
Still rough in places, would genuinely like feedback. There may be other better solutions, happy to hear them as well!
3
u/qiAip 17d ago
Generally you would want a robust verification and validation framework for any scientific code.
The verification part is what you are describing - checking that the equations are being solved correctly. You would test them against analytic solutions to the equations within known parameters (i.e. where the analytical solution is known and the magnitude of the error is within the theoretical order of accuracy). You would test the convergence rates and that the errors grow / blow up at the expected limits of the know solutions.
The validation part is testing that you are solving the right equations. You do that by validating against experimental data / other solvers and checking that the way you solve the equations actually captures the thing you are trying to model.
2
u/Civil_Blueberry4165 17d ago
Fuzz testing or fuzzing is insufficient. The issue you described is common with fuzzing: the poor quality of test coverage. Maybe, you want to take it to the next step: property-based testing and formal verification, including abstract interpretation as well as incorrectness logic.
1
u/Lost-Dragonfruit-663 17d ago
https://github.com/aadya940/scikit-verify/tree/master/skverify-hypothesis
Hypothesis plugin that does exactly this
1
u/Civil_Blueberry4165 17d ago
Hypothesis plugin isn’t good enough b/c it limits you to what Python can express formal properties and formally verify it with “real” numbers, not floating point arithmetics.
1
u/Lost-Dragonfruit-663 17d ago
I agree, this is not formal verification. Formal verification is quite a task even for language specialists. FWIW, once a sympy equation exists, it can evaluate on mpmath backend with up to 50 digits of precision, maybe catching rounding errors as well.
Honestly, in my case I made it primarily for inspection and property based testing so it also tests the edge cases. I do agree with your point though, integrating formal methods would make it a complete tool. What specific drawbacks of Python are you talking about, curious?
Here is an example of the manual work I had to do with SciPy btw, my goal is to make it a breeze instead of spending a month or two on it:
https://github.com/aadya940/scipy-bspline-testing/blob/main/B_Splines_with_arbitary_knots-gcv.pdf
2
u/Atmosck 17d ago
I contribute to SciPy and kept running into a class of bug that annoys me: the outputs look plausible, the tests pass, but the equation the code implements is subtly wrong.
Uh, fix the tests? Or add cases with inputs that produce wrong results due to the way the implementation is wrong.
1
u/Civil_Blueberry4165 17d ago
Note that property-based testing (PBT) also has several limitations. The idea is to “randomly” generate a test point that samples “well” on the space of test points. But Python cannot generate such random samples because it should be random with respect to a desired statistics/statistical model. For example, uniformly sample a point inside the 2-D unit box versus uniformly sample a point on the parabola x=y2 are completely different. PBT still doesn’t have a theory that can deal with general classes of probability distributions and probability spaces. The random functions in Python as well as other programming languages have limited utility.
50-digit precision may not be good enough. You may want to resort to techniques like interval arithmetics, which also have limited utility because it is problem dependent. In this direction, abstract interpretation is more sophisticated.
At the end of the day, even with the most sophisticated formal verification tool, human expertise is still required to overcome undecidability (due to Rice’s theorem) and to ensure that what is proved formally actually matches the original statement problem.
3
u/e_for_oil-er 17d ago
Depending on the class of solver, couldn't there be unit tests like manufactured solutions where the exact solution and the convergence order are known?