Search code examples
pythonpython-3.xscipy

Scipy.integrate gives odd results


I am still struggling with scipy.integrate.quad.

Sparing all the details, I have an integral to evaluate. The function is of the form of the integral of a product of functions in x, like so:

Z(k) = f(x) g(k/x) / abs(x)

I know for certain the range of integration is between tow positive numbers. Oddly, when I pick a wide range that I know must contain all values of x that are positive - like integrating from 1 to 10,000,000 - it intgrates fast and gives an answer which looks right. But when I fingure out the exact limits - which I know sice f(x) is zero over a lot of the real line - and use those, I get another answer that is different. They aren't very different, though I know the second is more accurate.

After much fiddling I got it to work OK, but then needed to add in an exopnentiation - I was at least getting a 'smooth' answer for the computed function of z. I had this working in an OK way before I added in the exponentiation (which is needed), but now the function that gets generated (z) becomes more and more oscillatory and peculiar.

Any idea what is happening here? I know this code comes from an old Fortran library, so there must be some known issues, but I can't find references.

Here is the core code:

def normal(x, mu, sigma) :
    return (1.0/((2.0*3.14159*sigma**2)**0.5)*exp(-(x-
                                      mu)**2/(2*sigma**2)))

def integrand(x, z, mu, sigma, f) : 
return np.exp(normal(z/x, mu, sigma)) * getP(x, f._x, f._y) / abs(x)




    for _z in range (int(z_min), int(z_max) + 1, 1000):
        z.append(_z)
        pResult = quad(integrand, lb, ub,
                       args=(float(_z), MU-SIGMA**2/2, SIGMA, X),
                       points = [100000.0],
                       epsabs = 1, epsrel = .01)    # drop error estimate of tuple 
        p.append(pResult[0])   # drop error estimate of tuple 

By the way, getP() returns a linearly interpolated, piecewise continuous,but non-smooth function to give the integrator values that smoothly fit between the discrete 'buckets' of the histogram.


Solution

  • As with many numerical methods, it can be very sensitive to asymptotes, zeros, etc. The only choice is to keep giving it 'hints' if it will accept them.