how do detect a complex function?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

how do detect a complex function?

nrjank
Administrator
regarding https://savannah.gnu.org/bugs/index.php?58636

integral calls quadcc, quadgk, quadv.  quadcc is the 'default' when there's nothing special, as i think it's faster than the others and generally applicable. it can't handle complex functions or limits, though, and integral fails to check for that.  the complex limit check is trivial, but I'm not sure how one would check for a complex function.

absent the ability to check, I could abandon use of quadcc (boo slow), or let quadcc try, catch the error, and if it's a complex related error redirect it to quadgk.  that seems messy and inefficient. 

suggestions?  


Reply | Threaded
Open this post in threaded view
|

Re: how do detect a complex function?

BGreen
On Sat, Jun 20, 2020 at 4:29 PM Nicholas Jankowski <[hidden email]> wrote:
regarding https://savannah.gnu.org/bugs/index.php?58636

integral calls quadcc, quadgk, quadv.  quadcc is the 'default' when there's nothing special, as i think it's faster than the others and generally applicable. it can't handle complex functions or limits, though, and integral fails to check for that.  the complex limit check is trivial, but I'm not sure how one would check for a complex function.

absent the ability to check, I could abandon use of quadcc (boo slow), or let quadcc try, catch the error, and if it's a complex related error redirect it to quadgk.  that seems messy and inefficient. 

suggestions?  


How inefficient would it be? It seems to me that for most cases, complex numbers would be returned at the first function evaluation.

Perhaps a start would be to evaluate the function at the limits of integration and check whether either returned value is complex. If either is, use quadgk. If not, try quadcc. If quadcc throws an error, then you can catch it and redirect to quadgk.

Obviously this check wouldn't catch every complex function, but it should get most. The error-catching approach then becomes a failsafe rather than the default.


Reply | Threaded
Open this post in threaded view
|

Re: how do detect a complex function?

nrjank
Administrator
How inefficient would it be? It seems to me that for most cases, complex numbers would be returned at the first function evaluation.

Perhaps a start would be to evaluate the function at the limits of integration and check whether either returned value is complex. If either is, use quadgk. If not, try quadcc. If quadcc throws an error, then you can catch it and redirect to quadgk.

Obviously this check wouldn't catch every complex function, but it should get most. The error-catching approach then becomes a failsafe rather than the default.

Yeah, it'll fail on anything with limits evaluating on the real axis.  and checking the integrand isn't trivial.  e.g, integral (sqrt(x), -1,1) would pass both a limit and integrand check unless you had some complex domain check.  

added limit and f(limit) checks to function attached to the bug. 

but it still doesn't catch complex functions with real limits that eval to real answers at those limits.  eg:

integral (exp(i*x), 0,pi) = 2i
--> f(0) = 1, f(pi) = -1,  but f(pi/2) = i

(easiest would be to just abandon quadcc. but the others are slooooooow.)


Reply | Threaded
Open this post in threaded view
|

Re: how do detect a complex function?

nrjank
Administrator
On Sat, Jun 20, 2020 at 5:27 PM Nicholas Jankowski <[hidden email]> wrote:
How inefficient would it be? It seems to me that for most cases, complex numbers would be returned at the first function evaluation.

Perhaps a start would be to evaluate the function at the limits of integration and check whether either returned value is complex. If either is, use quadgk. If not, try quadcc. If quadcc throws an error, then you can catch it and redirect to quadgk.

so, I want to catch any error messages related to complex errors and let any others pass through as normal. 

the two error messages in quadcc come from:

if (fvals.length () != 1 || ! fvals(0).is_real_matrix ())
      error ("quadcc: integrand F must return a single, real-valued vector")
...

and 

else if (! (args(4).is_real_scalar () || args(4).is_real_matrix ()))
    error ("quadcc: list of singularities (SING) must be a vector of real values");
 
The second one is straightforward, but I'm pretty sure integral is not set up to pass a list of singularities, so that should never appear, but can still include it in the check.  The first one is annoyingly a combination of two errors.  I want it to pass to quadgk if the real check fails but not if it's the length check.  Might need someone who works with the C code to split that into two checks with two diff errors for this to work unless we want both failures to try quadgk first.