Интеграция функций возвращает «только массивы длины 1 могут быть преобразованы в скаляры Python».

Я пытаюсь интегрировать функцию в заданный диапазон, которая показывает поток частиц в направлении нулевого угла (тета) в зависимости от энергии E частиц. Я пробовал несколько способов и получил разные ошибки, но в конце остались две. Мои знания Python ограничены, я пытаюсь изучать новые способы делать вещи по мере необходимости, но я безуспешно работал с этой функцией в течение нескольких дней.

Моя функция на данный момент выглядит так:

from numpy import radians, cos, arange
from scipy.integrate import quad

def integral(self):
    theta=0
    E = arange(1, 5000, 1)
    costh = cos(radians(theta))
    a = 18 / (E * costh + 145)
    b = (E + 2.7 / costh)**-2.7
    c = (E + 5) / (E + 5 / costh)
    return a*b*c*1**4


A = quad(integral, 500, 1000)

Применение «quad» к такой функции возвращает:

TypeError: только массивы длины 1 могут быть преобразованы в скаляры Python

Если я не поставлю «я» в качестве аргумента в функцию, она вернет:

TypeError: Integer() принимает 0 позиционных аргументов, но был задан 1

У кого-нибудь есть идея, как это обойти?


person Pedro Paxton    schedule 20.05.2018    source источник
comment
quad принимает функцию, которая принимает одно значение и возвращает одно значение. Похоже, ваш intergral ничего не делает с аргументом и возвращает массив со значениями более 5000 точек. Возможно, вам придется перечитать документацию quad и поэкспериментировать с некоторыми ее примерами.   -  person hpaulj    schedule 20.05.2018


Ответы (1)


integral должен иметь одну из подписей, описанных в scipy документация. В вашем случае функция, принимающая двойное значение в качестве аргумента и возвращающая двойное значение, кажется подходящей.

self используется только для функций-членов класса. Это не имеет смысла вне определения класса. Замените его простым именем, скажем, x, которое будет входным аргументом интегрируемой функции.

Функция должна возвращать double. Поскольку E является массивом, и вы, кажется, выполняете вычисления с ним, то вычисленное возвращаемое значение, вероятно, также будет массивом. Это должен быть скаляр. Исправьте это и все заработает. Когда вы заменяете свою функцию чем-то вроде:

def integral(x):
    return x * x

тогда это работает. Конечно, это не то, что вам нужно, но именно такие аргументы и возвращаемые значения необходимы для работы quad().

Вы можете посмотреть здесь пример использования quad().

Некоторые рекомендации:

  • используйте четыре пробела для отступа (а не 5, как в примере)
  • скобки вокруг результата не требуются. Удалите для большей ясности.
person Adrian W    schedule 20.05.2018
comment
Спасибо за отзыв, он мне очень помог. Я подумал, как мне получить скаляр, и нашел решение. E может быть функцией теты, поэтому я обошел это, перестроив функцию так, чтобы она зависела только от теты. Поэтому я создал лямбда-функцию тета только с этим уравнением, и с ним сработало четверное интегрирование. Это не то же самое, что функция выше, потому что в приведенном выше случае я хочу интегрировать диапазон энергий, а не угловой диапазон, но как только я получил один, я мог получить другой, просто изменив уравнение. Очень признателен! - person Pedro Paxton; 22.05.2018