При выполнении мультиинтеграции "принимает 0 позиционных аргументов, но 1 был задан"

Я делаю мультиинтеграл с 4 переменными, среди которых 2 имеют ограничения в качестве функций. Однако ошибка появляется в одной из моих переменных с постоянным пределом. На самом деле не могу понять, почему. Большое спасибо за ваш совет!

from numpy import sqrt, sin, cos, pi, arcsin, maximum
from sympy.functions.special.delta_functions import Heaviside
from scipy.integrate import nquad

def bmax(x):
    return 1.14*10**9/sin(x/2)**(9/7)

def thetal(x,y,z):
    return arcsin(3.7*10**15*sqrt(cos(x/2)**2/10**6-1.23*10**10/z+0.003*sin(x/2)**2*(2.51*10**63/sin(x/2)**9/y**7-1))/(z*sin(x/2)**2*cos(x/2)*(2.51*10**63/sin(x/2)**9/y**7-1)))

def rt(x,y):
    return 3.69*10**12/(2.5*10**63/sin(x/2)**7*y**7-sin(x/2)**2)

def rd(x,y):
    return maximum(1.23*10**10,rt(x,y))

def rl(x,y):
    return rd(x,y)*(sqrt(1+5.04*10**16/(rd(x,y)*cos(x/2)**2))-1)/2

def wbound():
    return [1.23*10**10,3.1*10**16]

def zbound():
    return [10**(-10),pi-10**(-10)]

def ybound(z):
    return [0,bmax(z)-10**(-10)]

def xbound(z,y,w):
    return [thetal(z,y,w),pi-thetal(z,y,w)]

def f(x,y,z,w):
    return [5.77/10**30*sin(z)*sin(z/2)*y*sin(x)*Heaviside(w-rl(z,y))*Heaviside(w-rd(z,y))/w**2]

result = nquad(f, [xbound, ybound,zbound,wbound])

2 ответа

Решение

Причина этой ошибки в том, что хотя вы не хотите, чтобы эти границы зависели от переменных, nquad по-прежнему передает переменные в функции, которые вы предоставляете ему. Таким образом, связанные функции должны принимать правильное количество переменных:

def wbound():
    return [1.23*10**10,3.1*10**16]

def zbound(w_foo):
    return [10**(-10),pi-10**(-10)]

def ybound(z, w_foo):
    return [0,bmax(z)-10**(-10)]

def xbound(z,y,w): 
    return [thetal(z,y,w),pi-thetal(z,y,w)]

Теперь функции zbound а также ybound принять дополнительные переменные, но просто игнорировать их.

Я не уверен насчет последней границы, xbound(...): Вы хотите переменные y а также z быть обманутым? Предположительно правильный порядок согласно определению scipy.integrate.nquad было бы

def xbound(y,z,w):
    ... 

Редактировать: Как указывало Каземакасе, функция f должен вернуть float вместо списка так скобки [...] в операторе возврата должно быть удалено.

nquad ожидает последовательность bounds для второго аргумента, с довольно строгим синтаксисом.

Если подынтегральное f зависит от x, y, z, w и это порядок определения, термины в bounds должно быть, в последовательности, xb, yb, zb а также wbгде каждая из границ может быть либо 2-кортежем, например, xb = (xmin, xmax)или функция, которая возвращает 2-кортеж.

Критическая точка, аргументы этих функций... когда мы выполняем внутреннюю интеграцию, в dxу нас есть в наличии y, z а также w для вычисления границ в xтак что должно быть
def xb(y,z,w): return(..., ...) - аналогичноdef yb(z,w): return (..., ...) а также
def zb(w): return (..., ...),
Границы относительно последней переменной интегрирования должны быть постоянными.

Подвести итоги

# DEFINITIONS

def f(x, y, z, w): return ..  . # x inner integration, ..., w outer integration
def xb(y,z,w): return (...,...) # or simply xb=(...,...) if it's a constant
def yb(z,w): return (...,...)   # or yb=(...,...)
def zb(w): return (...,...)     # or zb=(...,...)
wb = (...,...)

# INTEGRATION

result, _ = nquad(f, [xb, yb, zb, wb])
Другие вопросы по тегам