Функция SymPy с невычисленным аргументом

Как новичок в SymPy, я рассматриваю следующее выражение SymPy (которое должно быть равно 1, если 0<x<1):

f = Sum((2/(lambda_m*besselj(1, lambda_m)))*besselj(0,x*lambda_m), (m, 1, oo))

где lambda_mm-й ноль числа besselj(0,x).

Теперь у mpmath есть функция besseljzero(0,m,0), которая вычисляет именно это.

К сожалению, если я заменю (вручную, я имею в виду...) lambda_m на besseljzero(0,m,0) в верхней формуле, SymPy выдаст мне ошибку, потому что m не является целым числом...

Я представляю решение этой проблемы путем создания функции, которая должна:

  • вернуть j0(m), если m не равно целому числу
  • вернуть besseljzero(0,m,0), если это так

Но я не знаю, как поступить.

Это хорошая идея, и может ли кто-нибудь мне помочь?


person P. Weiss    schedule 01.05.2017    source источник


Ответы (1)


Проблема в том, что MPMath предназначен для числовых вычислений и обычно дает численные приближения, в то время как SymPy работает символически: произвольная точность — это не то же самое, что бесконечная точность. Вы не можете вычислить бесконечную сумму выходных данных из MPMath, так как на самом деле вам пришлось бы иметь дело с бесконечным количеством слагаемых.

Чтобы символически вычислить вашу сумму, SymPy должен иметь представления всех аргументов и знать описываемую вами личность (f(x)==1, если 0<x<1) или иметь возможность ее получить. Похоже, это не так.

Таким образом, все, что вы можете сделать, это численно аппроксимировать результат, например, используя реализации из MPMath:

from mpmath import besseljzero, besselj
from itertools import count

threshold = 1e-5
min_m = 100

def f(x):
    Sum = 0
    for m in count(1):
        lambda_m = besseljzero(0,m,0)
        summand = 2/(lambda_m*besselj(1, lambda_m))*besselj(0,x*lambda_m)
        Sum += summand
        if m>min_m and abs(summand)<threshold:
            break
    return Sum
person Wrzlprmft    schedule 01.05.2017
comment
Извините - последняя часть моего комментария была удалена системой. Очевидно, что эту функцию можно запрограммировать явно - это не моя точка зрения... если бы besselzero(0,m,0) вел бы себя точно так же, как besselj(0,x ), все будет хорошо. У меня был вопрос: можно ли написать симпатичную функцию, которая ведет себя как besselj(0,x) (или, например, sin(x)? Вероятно, в его коде используется besseljzero(0,m,0)... Надеюсь, это понятнее... С уважением - person P. Weiss; 02.05.2017
comment
Если я правильно понимаю ваше желание, это должно быть рассмотрено во втором абзаце моего ответа. - person Wrzlprmft; 02.05.2017
comment
Что ж... Цель всего этого упражнения — показать, что выражение igven фактически равно 1 между 0 и 1. Таким образом, тождество f(x)==1, если 0‹x‹1 не имеет отношения к моей проблеме. - person P. Weiss; 04.05.2017
comment
Конечно, но чтобы показать это, SymPy должен иметь возможность вычислять бесконечную сумму. И это может работать только в том случае, если слагаемые чисто символические (и понятны SymPy). Так что, по крайней мере, должно быть абстрактное представление нулей (которое может обрабатывать SymPy) или должно быть аналитическое выражение. Оба, кажется, не существуют. - person Wrzlprmft; 04.05.2017
comment
Постараюсь объяснить получше... Эта формула (другие подобные ей...) получается символически с помощью sympy. Итак, мой вывод правильный? Как быстро сумма сходится? Я вполне осознаю, что sympy не сможет вычислить сумму до m = бесконечность. Однако я хотел бы заменить бесконечность, скажем, на 100, и сделать сумму. Это должно хорошо работать. Только я не могу ввести besselj0(0,m,0) в общую формулу - я должен подставить их в цикле ПОСЛЕ фиксации m. - person P. Weiss; 05.05.2017
comment
@P.Weiss: Только я не могу ввести besselj0(0,m,0) в общую формулу - я должен подставить их в цикле ПОСЛЕ фиксирования m. – Точно. Кажется, вы решили свою проблему (если нет, я не понимаю, что это такое). - person Wrzlprmft; 05.05.2017