Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: dblquad and args kwarg #17776

Closed
RichardAFrazin opened this issue Jan 12, 2023 · 19 comments
Closed

BUG: dblquad and args kwarg #17776

RichardAFrazin opened this issue Jan 12, 2023 · 19 comments
Labels
defect A clear bug or issue that prevents SciPy from being installed or used as expected scipy.integrate
Milestone

Comments

@RichardAFrazin
Copy link

Describe your issue.

There is a bug with scipy.dblquad that seems to be involved with using the args kwarg. The example below is the integral of a 2D Normal distribution, which should be unity. I am using the args kwarg to pass the coords of the center of the Normal. Note that the boundary of the integral is also using the same variable that are passed in args (although I don't know why that might matter).

Reproducing Code Example

< import numpy as np; from scipy.integrate import dblquad
< sig = 1.3; x0=5.; y0=-3.;
< g = lambda x,y,xc,yc : (1/(2*np.pi*sig*sig))*np.exp(- ((x-xc)**2 + (y-yc)**2)/(2*sig*sig) )
< print([g(x0,y0,x0,y0), g(x0+1,y0+1,x0,y0)])
[0.09417452253958304, 0.05211400420209555]
< print([g(x0,y0,x0-5*sig,y0), g(x0+5*sig,y0,x0,y0)])
[3.509557831511321e-07, 3.509557831511321e-07]

< dblquad(g,x0-5*sig,x0+5*sig,y0-5*sig,y0+5*sig,args=(x0,y0))
> (0.015445922091068943, 6.2668582074865746e-09)
this answer is not close enough to unity for my taste.

Error message

no error message, just the wrong answer!

SciPy/NumPy/Python version information

np 1.16.2 scipy 1.2.1

@RichardAFrazin RichardAFrazin added the defect A clear bug or issue that prevents SciPy from being installed or used as expected label Jan 12, 2023
@tupui
Copy link
Member

tupui commented Jan 12, 2023

Hi @RichardAFrazin, thank you for reporting. Boundaries and tolerances are very important as it will impact how the domain is discretised and walked through. See #17554.

Unrelated (I think), consider updating SciPy and NumPy. These are very old versions and we pushed in both literally thousands of bug fixes and improvements.

@tupui
Copy link
Member

tupui commented Jan 12, 2023

Seeing this is exactly the same case/distribution as the other issue. I did not check your formula, there might as well be an issue there.

Closing for now as I am pretty certain there is no bug. If you still find something I am happy to reopen. Thanks again 😃

@tupui tupui closed this as not planned Won't fix, can't repro, duplicate, stale Jan 12, 2023
@tupui tupui added this to the 1.11.0 milestone Jan 12, 2023
@RichardAFrazin
Copy link
Author

RichardAFrazin commented Jan 12, 2023 via email

@tupui
Copy link
Member

tupui commented Jan 12, 2023

Did you try adjusting the tolerance and other parameters of the function?

@RichardAFrazin
Copy link
Author

RichardAFrazin commented Jan 12, 2023 via email

@mdhaber
Copy link
Contributor

mdhaber commented Jan 12, 2023

I modified your code so that:

def g(x,y,xc,yc):
    print(xc, yc)
    return (1/(2*np.pi*sig*sig))*np.exp(- ((x-xc)**2 + (y-yc)**2)/(2*sig*sig) )

It prints lots of (5.0, -3.0). So I don't think args is the problem.
However, I haven't gotten the correct result from the integral yet.

@RichardAFrazin
Copy link
Author

RichardAFrazin commented Jan 12, 2023 via email

@mdhaber
Copy link
Contributor

mdhaber commented Jan 12, 2023

< dblquad(g,x0-5*sig,x0+5*sig,y0-5*sig,y0+5*sig,args=(x0,y0))

Check the order of your arguments:
image

Here is code that shows that dblquad is not the problem here:

import numpy as np
from scipy import stats, integrate
sig, x0, y0 = 1.3, 5., -3
cov = stats.Covariance.from_diagonal([sig**2, sig**2])

def g(y, x, xc, yc):
    z = [x, y]
    mean = [xc, yc]
    return stats.multivariate_normal(mean, cov).pdf(z)    

res = integrate.dblquad(g, x0-5*sig, x0+5*sig, y0-5*sig, y0+5*sig, 
                        args=(x0, y0))
print(res)  # (0.9999988533940415, 8.668315648607816e-10)

I find the order (y, x) surprising, too, but it's not something we can change.

@RichardAFrazin
Copy link
Author

RichardAFrazin commented Jan 12, 2023 via email

@mdhaber
Copy link
Contributor

mdhaber commented Jan 12, 2023

Make it g = lambda y, x,xc,yc : (1/(2*np.pi*sig*sig))*np.exp(- ((x-xc)**2 + (y-yc)**2)/(2*sig*sig) ). Reverse x and y.

@tupui
Copy link
Member

tupui commented Jan 12, 2023

I am pretty sure the function is not correct. I tried to plotted it and it's flat.

@mdhaber
Copy link
Contributor

mdhaber commented Jan 12, 2023

I think the function is fine:

g(y0, x0, x0, y0) - stats.multivariate_normal([x0, y0], cov=np.eye(2)*sig**2).pdf([x0, y0])  # -1.3877787807814457e-17

The main problem is the order that x and y are passed into the function. dblquad expects y, x, but the original code was x, y.

@RichardAFrazin
Copy link
Author

RichardAFrazin commented Jan 12, 2023 via email

@tupui
Copy link
Member

tupui commented Jan 12, 2023

Screenshot 2023-01-12 at 21 25 13

@RichardAFrazin
Copy link
Author

RichardAFrazin commented Jan 12, 2023 via email

@tupui
Copy link
Member

tupui commented Jan 12, 2023

Actually, if you have no correlation, shouldn't the right term just be exp(.../2)? As 1-p **2 would be 1.

@mdhaber
Copy link
Contributor

mdhaber commented Jan 12, 2023

I was missing that cov should have been np.eye(2) * sig**2 instead of np.eye(2) * sig before. Not sure what is going wrong with the plot @tupui but the function is OK aside from the argument order.

@RichardAFrazin
Copy link
Author

RichardAFrazin commented Jan 12, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
defect A clear bug or issue that prevents SciPy from being installed or used as expected scipy.integrate
Projects
None yet
Development

No branches or pull requests

3 participants