Функция Python Scipy dblquad, дающая неправильный ответ на коротком расстоянии

#python #scipy

Вопрос:

Я хочу интегрировать следующий двойной интеграл:

Определенный интеграл, подлежащий вычислению

Я хочу использовать метод dblquad из пакета scipy.integrate, который позволяет выполнять двойные интегралы с ограничениями внутреннего интеграла в зависимости от внешней интегральной переменной:

 import scipy.integrate as spi import numpy as np  x_limit = 0 y_limit = lambda x: np.arccos(np.cos(x))  integrand = lambda x, y: np.exp(-(2 np.cos(x)-np.cos(y))) low_limit_y = 0 # inner integral up_limit_y = y_limit low_limit_x = x_limit # outer integral up_limit_x = 2*np.pi-x_limit  integral = spi.dblquad(integrand, low_limit_x, up_limit_x, low_limit_y, up_limit_y)  print(integral)  

Выход:

 (0.6934912861906996, 2.1067956428653226e-12)  

Код запускается, но не дает мне правильного ответа. Используя Wolfram Alpha, я получаю правильный ответ: 3.58857

«arccos(cos(x))»amp;assumption={«F», «DoubleIntegral», «rangeend1»} ->»2pi»amp;assumption={«F», «DoubleIntegral», «integrand»} ->»exp(-(2+cos(x)-cos(y)))»amp;assumption={«F», «DoubleIntegral», «intvariable1»} ->»x»amp;assumption={«F», «DoubleIntegral», «rangestart1»} ->»0″amp;assumption={«F», «DoubleIntegral», «intvariable2»} ->»y»amp;assumption={«F», «DoubleIntegral», «rangestart2″} ->»0″» rel=»nofollow noreferrer»>Альфа-метод Вольфрама

Единственное, что я заметил, это то, что значения двух методов совпадают, когда знаки на косинусах переключаются с на — и наоборот:

«arccos(cos(x))»amp;assumption={«F», «DoubleIntegral», «rangeend1»} ->»2pi»amp;assumption={«F», «DoubleIntegral», «integrand»} ->»exp(-(2-cos(x)+cos(y)))»amp;assumption={«F», «DoubleIntegral», «intvariable1»} ->»x»amp;assumption={«F», «DoubleIntegral», «rangestart1»} ->»0″amp;assumption={«F», «DoubleIntegral», «intvariable2»} ->»y»amp;assumption={«F», «DoubleIntegral», «rangestart2″} ->»0″» rel=»nofollow noreferrer»>Метод Вольфрама Альфа с заменой знаков на косинусах

Однако у меня нет убедительной причины, по которой это должно быть так. Кто — нибудь имеет хоть малейшее представление о том, что здесь происходит? Я могу разделить функцию на внутренний интеграл, зацикливающийся на всех значениях x, а затем суммировать результаты, которые дают правильный ответ, но это действительно довольно медленно.

Ответ №1:

Взгляните еще раз на строку документа dblquad ; там написано

 Return the double (definite) integral of ``func(y, x)`` from ``x = a..b`` and ``y = gfun(x)..hfun(x)``.  

Обратите внимание на порядок аргументов func(y, x) : y сначала, затем x .

Если вы измените свое определение integrand на

 integrand = lambda y, x: np.exp(-(2 np.cos(x)-np.cos(y)))  

вы получите ожидаемый ответ. Это также (по сути) то, что вы сделали, когда изменили знаки cos терминов в подынтегральном выражении.

(Вы не первый, кого сбивает с толку ожидаемый порядок аргументов func .)

Комментарии:

1. Большое спасибо! Я трижды проверил документы и границы, но, должно быть, полностью пропустил эту часть документа.