Сообщение TypeError при выполнении метода четырехъядерной интеграции scipy.integrate с функциями mpmath

Я пытаюсь вычислить два интеграла, используя scipy.integrate.quad. Однако, поскольку гамма функции с отрицательным первым параметром не определены в scipy, мне пришлось выбрать версию из mpmath. После запуска следующего кода

from scipy.integrate import *
from mpmath import *



low, up  = 5.630e5, 1.167e12
alpha, threshold = 1.05   , 2.15e10 
beta = 274

def g(x, beta, low, up):
    return gamma(-2/3) * (gammainc(-2/3, beta*(x/low)**3) - gammainc(-2/3, beta*(x/up)**3))

def Integrand1(x, low, threshold, alpha):
    return pow(x/threshold, alpha) * g

def Integrand2(x, up, threshold):
    return g

Integral1 = quad(Integrand1, low, threshold, args=(low, up, threshold, alpha, beta))
Integral2 = quad(Integrand2, threshold, up, args=(low, up, threshold, beta))

print(Integral1)
print(Integral2)

Вот сообщение об ошибке, с которым я не знаю, как справиться, и мне нужна помощь:

Трассировка (последний последний вызов): файл "test.py", строка 19, в Integral1 = quad(Integrand1, low, threshold, args=(low, up, threshold, alpha, beta)) File "/home/username/ anaconda3/lib/python3.6/site-packages/mpmath/calculus/quadrature.py", строка 748, в quad points[0], prec, epsilon, m, verbose) File "/home/username/anaconda3/lib/ python3.6/site-packages/mpmath/calculus/quadrature.py", строка 215, в сумме для i в xrange(len(points)-1): TypeError: объект типа 'float' не имеет len()

Я могу только догадываться, что причина может быть в том, что quad функция несовместима с интегралами, определенными с помощью mpmath.


person Ash    schedule 20.11.2017    source источник


Ответы (1)


Операторы импорта

Не импортируйте * из двух мест, это рецепт конфликта имен. В MpMath есть собственный метод quad, который заменяет метод SciPy. quad в вашем коде.

from scipy.integrate import quad
from mpmath import gamma, gammainc 

Параметры функции

Если вы вызываете функцию g, вы должны предоставить ей аргументы. Итак, напишите * g(x, beta, low, up) вместо * g.

Конечно, эти аргументы также должны быть доступны функции, вызывающей g. Как это:

def Integrand1(x, low, up, threshold, alpha, beta):
    return pow(x/threshold, alpha) * g(x, beta, low, up)

def Integrand2(x, low, up, threshold, alpha, beta):
    return g(x, beta, low, up)

Integral1 = quad(Integrand1, low, threshold, args=(low, up, threshold, alpha, beta))
Integral2 = quad(Integrand2, threshold, up, args=(low, up, threshold, alpha, beta))

Обратите внимание, что аргументы, передаваемые функциям Integrand, соответствуют тому, что они ожидают получить. Они получают x и все, что указано в параметре args квадрацикла.

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

person Community    schedule 20.11.2017
comment
@спасибо, изначально у меня была функция g, записанная явно как функция параметров. Но да, у меня были слишком главные вопросы. Постановка и включение параметров на всех этапах. - person Ash; 21.11.2017