mathnet / mathnet-symbolics

Math.NET Symbolics
http://symbolics.mathdotnet.com
MIT License
352 stars 67 forks source link

"not supported" exception with divide by zero in equation #102

Open PaulSmart73 opened 1 year ago

PaulSmart73 commented 1 year ago

Hi,

I am trying to use the library to parse and the execute some math channels in my C# project. It works very well, but I receive an "not supported" exception which is very slow.

Having looked into the equation and data I have isolated it to effectively a sqrt(1/0) call that is causing the exception. fpower in the Evaluate module is being used for the division. This is returning PosInf for the 1/0 call and then this is not matched for the sqrt call.

I have found two options for how to remove the exception:

1) modify the Evaluate to return Undef if a divide by zero is found. 2) modify the Evaluate to handle PosInf as a match case

For my immediate problem, I have modified the fpower as below with both options, which allows my codes to run without any exceptions being raised

    let fpower u v =
    match u, v with
    | Real x, Real y when x < 0.0 && (y%1.0 <> 0.0) -> Complex (Complex.pow (complex y 0.0) (complex x 0.0))
    | Real x, Real y when x = 0.0 && y < 0 -> Undef
    | Real x, Real y -> Real (Math.Pow(x, y))
    | Complex x, Real y -> Complex (Complex.pow (complex y 0.0) x)
    | Real x, Complex y -> Complex (Complex.pow y (complex x 0.0))
    | Complex x, Complex y -> Complex (Complex.pow y x)
    | Undef, _ | _, Undef -> Undef
    | ComplexInf, Infinity | Infinity, ComplexInf -> ComplexInf
    | Infinity, PosInf -> ComplexInf
    | Infinity, NegInf -> Real (0.0)
    | PosInf, _ | _, PosInf -> PosInf
    | NegInf, _ | _, NegInf -> NegInf
    | _ -> failwith "not supported"

I do not know enough about the library ( or maths...) to understand if this is a valid thing to do though. It certainly works for my use-case.

What is the preferred method of handling divide by zero (undefined or infinity)? What should be the sqrt(PosInf)? I would guess its still PosInf.