markrogoyski / math-php

Powerful modern math library for PHP: Features descriptive statistics and regressions; Continuous and discrete probability distributions; Linear algebra with matrices and vectors, Numerical analysis; special mathematical functions; Algebra
MIT License
2.33k stars 240 forks source link

Dealing with NANs #435

Closed Beakerboy closed 2 years ago

Beakerboy commented 2 years ago

The R sources that I've been reviewing spend a fair amount of code in each function managing how to handle NAN as input, and when to properly output NAN. It seems we use exceptions instead of NAN on the output side. Is this best long term when IEEE 754 already defines a way to deal with this in floating point numbers? Is this something worth considering? Since NAN is a float, typesetting on inputs will not prevent NAN from entering some of our functions, so we should probably decide how to handle these situations.

markrogoyski commented 2 years ago

There are pros and cons to both approaches.

Returning a NAN is nice in terms of types that NAN is kind of a float and you can have a return type declaration of float which works for real numbers and NANs. However, there is immense complexity in every function needing to check every other function, and you will have a lot of conditional logic anytime you call a function because you can't trust that you got an actual answer back. You also push this complexity onto any clients using our code, in that they also can't trust return values if NAN comes back.

Throwing exceptions is nice because you can go back to trusting return values. Parts of the code that explicitly expects and knows how to deal with NANs can try/catch and deal with it, and other parts of the code can ignore it and pretend that only the happy path exists, because it basically only does for them. The downside is client code will crash if the exception is not handled, but as long as it is documented, it basically becomes the client's responsibility to handle it.

I have not researched what other math libraries do and could spend some time looking at some OO math libraries like Apache Commons Math and the like. But my initial thoughts without thinking too much is that for now maybe a MathPHP\Exception\NanException is all that we need and make sure the few places it is expected is checked and we throw this new exception rather than letting a NAN return value infect other parts of the code that are not expecting or prepared to handle it.

Beakerboy commented 2 years ago

MathPHP\Exception\NanException Sounds like a great compromise.

markrogoyski commented 2 years ago

Version 2.5.0 implemented NanException as discussed.