Я бы хотел использовать Numba , чтобы украсить подынтегральное выражение для кратного интеграла, чтобы его можно было вызвать с помощью функции SciPy Nquad как LowLevelCallable . В идеале декоратор должен учитывать произвольное количество переменных и произвольное количество дополнительных параметров из аргумента args в Nquad. Это построено из превосходных вопросов и ответов, полученных ранее в этом году , но распространено на случай нескольких переменных и параметров.
В качестве примера предположим следующий кратный интеграл с N переменными и K параметрами:
Следующий код работает, но только для двух переменных и двух параметров (N = 2, K = 2). Это не работает для более общего случая. Это связано с тем, что некоторые аргументы в декораторе нумеруются вручную (xx [0], xx [1], xx [2], xx [3] внутри функции wrapped ). Декоратор должен быть отредактирован для каждого различного числа переменных или параметров. Я хотел бы избежать этого, если это возможно. Обратите внимание, что сама функция integrand использует преимущества объектов и методов Numpy и поэтому не имеет этой проблемы.
import numpy as np
import scipy.integrate as si
import numba
from numba import cfunc,carray
from numba.types import intc, CPointer, float64
from scipy import LowLevelCallable
def jit_integrand_function(integrand_function):
jitted_function = numba.jit(integrand_function, nopython=True)
@cfunc(float64(intc, CPointer(float64)))
def wrapped(n, xx):
return jitted_function(xx[0], xx[1], xx[2], xx[3])
#xx = carray(xx,len(xx))
#return jitted_function(xx)
return LowLevelCallable(wrapped.ctypes)
@jit_integrand_function
def integrand(*args):
d = np.array([args])
return -np.exp(d.prod())
#Two variable, two parameter example
parms = np.array([2,3])
print si.nquad(integrand,[[0,1],[0,1]],parms)
Идеальный код будет использовать только один декоратор для функции integrand для запуска:
#Three variable, three parameter example
parms2 = np.array([1,2,3])
print si.nquad(integrand,[[0,1],[0,1],[0,1]],parms2)
Документы Numba относятся к функции carray , которая должна возвращать массив Numpy, если в обратном вызове задан указатель низкого уровня и размер массива. Возможно, это можно использовать для обобщения кода за пределами случая с двумя переменными и двумя параметрами. Моя (неудачная) попытка реализовать это в двух закомментированных строках кода.
Помощь будет принята с благодарностью. Действительно, один из разработчиков Numba указал , что интеграция SciPy была одной из причин написания Numba, но что документации и примеров в этой области не хватает.