Краткий ответ - вам необходимо предоставить полную трассировку и спецификацию вызова.И вам нужно правильно вызвать dblquad
.
===
Что такое x,y
, когда вы звоните с
integ.dblquad(prob(x,y), 0, 4, lambda x: 0, lambda x: 3)
В зависимости от этих двух переменных,ошибка может возрастать до того, как dblquad
даже будет вызван.
Первый аргумент dblquad
должен быть функцией, а не массивом.Использование prob
вместо prob(x,y)
может работать.
Учитывая 2 скаляра prob
работает:
In [674]: prob(1,2)
Out[674]: 0.4685835209054995
Учитывая два массива, мы получаем ошибку неоднозначности:
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()
И полная обратная трассировка (которую вы должны были предоставить нам) показывает, что проблема заключается в вызове isclose
:
In [676]: np.isclose(np.arange(3),np.arange(1,4))
Out[676]: array([False, False, False])
. Он создает логический массив, который нельзя использовать в if
предложение.
Использование math.isclose
вызывает ошибку, поскольку функции math
принимают только скаляры.Они не работают с массивами (многозначными).
При правильном использовании dblquad
это работает:
In [678]: integ.dblquad(prob, 0,4,lambda x:0, lambda x:3)
Out[678]: (4.42854383700761, 1.8525461432365937e-08)
dblquad
передает скалярные значения в вашу функцию, поэтому использованиеisclose
(либо числовой, либо математический) не проблема
Использование math
функций со скалярными входами быстрее:
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)
намного быстрее:
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)