Short answer - you need to provide full traceback and calling specification. And you need to call dblquad
correctly.
===
What are x,y
when you call with
integ.dblquad(prob(x,y), 0, 4, lambda x: 0, lambda x: 3)
Depnding on those 2 variables, the error might be rising before dblquad
is even called.
The first argument to dblquad
is supposed to be a function, not an array. Using prob
instead of prob(x,y)
might work.
Given 2 scalars prob
works:
In [674]: prob(1,2)
Out[674]: 0.4685835209054995
Given two arrays we get the ambiguity error:
In [675]: prob(np.arange(3),np.arange(1,4))
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-675-4b16a88f567e> in <module>
----> 1 prob(np.arange(3),np.arange(1,4))
<ipython-input-673-e31785dd54a5> in prob(x, y)
2 ch = np.sqrt((3-y)**2 + x**2)
3 hb = np.sqrt((4-x)**2 + y**2)
----> 4 if np.isclose(4 * y, 12 - 3 * x):
5 # Without the if statement, any x, y values that satisfy the condition will return nan
6 return 0.5
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
And the full traceback (which you should have given us) shows the problem is with the isclose
call:
In [676]: np.isclose(np.arange(3),np.arange(1,4))
Out[676]: array([False, False, False])
It produces a boolean array, which can't be used in an if
clause.
Using math.isclose
raises error because math
functions only accept scalars. They don't work with arrays (multivalued ones).
Using dblquad
correctly, it works:
In [678]: integ.dblquad(prob, 0,4,lambda x:0, lambda x:3)
Out[678]: (4.42854383700761, 1.8525461432365937e-08)
dblquad
passes scalar values to your function, so the use of isclose
(either numpy or math) isn't problem
Using math
functions with scalar inputs is faster:
def probm(x,y):
ch = math.sqrt((3-y)**2 + x**2)
hb = math.sqrt((4-x)**2 + y**2)
if math.isclose(4 * y, 12 - 3 * x):
# Without the if statement, any x, y values that satisfy the condition will return nan
return 0.5
else:
return (math.acos((ch**2 + hb**2 - 25) / (2 * ch * hb)))/(2*math.pi)
In [683]: integ.dblquad(probm, 0,4,lambda x:0, lambda x:3)
Out[683]: (4.428543836134556, 1.8890715880459652e-08)
much faster:
In [685]: timeit integ.dblquad(prob, 0,4,lambda x:0, lambda x:3)
11.7 s ± 24.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [686]: timeit integ.dblquad(probm, 0,4,lambda x:0, lambda x:3)
272 ms ± 1.12 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)