Редукция n-производной, например, в интегралы полиномов Эрмита с использованием SymPy - PullRequest
0 голосов
/ 25 сентября 2019

Я пытаюсь получить SymPy , чтобы уменьшить выражения с n '-й производной, где n является символом, а не значением.Тем не менее, SymPy , по-видимому, настаивает на том, чтобы порядок дифференцирования был исправлен для редукции к работе.

Предположим, вы хотите показать, что полиномы Эрмита, заданные

и мы хотим показать, что они ортогональны на с внутренним произведением, определяемым как

То есть нам нужно показать, что

Чтобы сделать это в SymPy , я делаю следующее

from sympy import *  # Bad practise, I know
init_printing 

x = symbols('x',real=True)
n, k, l = symbols('n k l',integer=True,negative=False)

HN = (-1)**n*exp(x**2)*Derivative(exp(-x**2),(x,n))

Можно оценить это для различных n и получите правильное расширение, например

[HN.subs(n,nn).doit() for nn in range(5)] 

При оценке внутреннего произведения H k с H l

integrate(HN.subs(n,k)*HN.subs(n,l)*exp(-x**2),(x,-oo,oo))

можно ожидать результата некоторой константы, когда k и l одинаковы, и 0 во всех других случаях.

Однако SymPy вызывает исключение

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-52-87b3d9a96dec> in <module>()
----> 1 integrate(PH.subs(dict(n=k,y=x))*PH.subs(dict(n=l,y=x))*exp(-x**2))

/usr/lib/python3/dist-packages/sympy/integrals/integrals.py in integrate(*args, **kwargs)
   1463     if isinstance(integral, Integral):
   1464         return integral.doit(deep=False, meijerg=meijerg, conds=conds,
-> 1465                              risch=risch, manual=manual)
   1466     else:
   1467         return integral

/usr/lib/python3/dist-packages/sympy/integrals/integrals.py in doit(self, **hints)
    536                 else:
    537                     antideriv = self._eval_integral(
--> 538                         function, xab[0], **eval_kwargs)
    539                     if antideriv is None and meijerg is True:
    540                         ret = try_meijerg(function, xab)

/usr/lib/python3/dist-packages/sympy/integrals/integrals.py in _eval_integral(self, f, x, meijerg, risch, manual, conds)
   1001                 # rewrite using G functions
   1002                 try:
-> 1003                     h = meijerint_indefinite(g, x)
   1004                 except NotImplementedError:
   1005                     from sympy.integrals.meijerint import _debug

/usr/lib/python3/dist-packages/sympy/integrals/meijerint.py in meijerint_indefinite(f, x)
   1618 
   1619     results = []
-> 1620     for a in sorted(_find_splitting_points(f, x) | {S(0)}, key=default_sort_key):
   1621         res = _meijerint_indefinite_1(f.subs(x, x + a), x)
   1622         if not res:

/usr/lib/python3/dist-packages/sympy/integrals/meijerint.py in _find_splitting_points(expr, x)
    403             compute_innermost(arg, res)
    404     innermost = set()
--> 405     compute_innermost(expr, innermost)
    406     return innermost
    407 

/usr/lib/python3/dist-packages/sympy/integrals/meijerint.py in compute_innermost(expr, res)
    394         if not isinstance(expr, Expr):
    395             return
--> 396         m = expr.match(p*x + q)
    397         if m and m[p] != 0:
    398             res.add(-m[q]/m[p])

/usr/lib/python3/dist-packages/sympy/core/basic.py in match(self, pattern, old)
   1539         """
   1540         pattern = sympify(pattern)
-> 1541         return pattern.matches(self, old=old)
   1542 
   1543     def count_ops(self, visual=None):

/usr/lib/python3/dist-packages/sympy/core/add.py in matches(self, expr, repl_dict, old)
    395 
    396     def matches(self, expr, repl_dict={}, old=False):
--> 397         return AssocOp._matches_commutative(self, expr, repl_dict, old)
    398 
    399     @staticmethod

/usr/lib/python3/dist-packages/sympy/core/operations.py in _matches_commutative(self, expr, repl_dict, old)
    250                         if free:
    251                             did.update(free)
--> 252                             expr = collect(expr, free)
    253                     if expr != was:
    254                         i += 0

/usr/lib/python3/dist-packages/sympy/simplify/radsimp.py in collect(expr, syms, func, evaluate, exact, distribute_order_term)
    329             return expr.func(*[
    330                 collect(term, syms, func, True, exact, distribute_order_term)
--> 331                 for term in expr.args])
    332         elif expr.is_Pow:
    333             b = collect(

/usr/lib/python3/dist-packages/sympy/simplify/radsimp.py in <listcomp>(.0)
    329             return expr.func(*[
    330                 collect(term, syms, func, True, exact, distribute_order_term)
--> 331                 for term in expr.args])
    332         elif expr.is_Pow:
    333             b = collect(

/usr/lib/python3/dist-packages/sympy/simplify/radsimp.py in collect(expr, syms, func, evaluate, exact, distribute_order_term)
    332         elif expr.is_Pow:
    333             b = collect(
--> 334                 expr.base, syms, func, True, exact, distribute_order_term)
    335             return Pow(b, expr.exp)
    336 

/usr/lib/python3/dist-packages/sympy/simplify/radsimp.py in collect(expr, syms, func, evaluate, exact, distribute_order_term)
    354         c, nc = product.args_cnc(split_1=False)
    355         args = list(ordered(c)) + nc
--> 356         terms = [parse_term(i) for i in args]
    357         small_first = True
    358 

/usr/lib/python3/dist-packages/sympy/simplify/radsimp.py in <listcomp>(.0)
    354         c, nc = product.args_cnc(split_1=False)
    355         args = list(ordered(c)) + nc
--> 356         terms = [parse_term(i) for i in args]
    357         small_first = True
    358 

/usr/lib/python3/dist-packages/sympy/simplify/radsimp.py in parse_term(expr)
    249                 sexpr, rat_expo = exp(tail), coeff
    250         elif isinstance(expr, Derivative):
--> 251             sexpr, deriv = parse_derivative(expr)
    252 
    253         return sexpr, rat_expo, sym_expo, deriv

/usr/lib/python3/dist-packages/sympy/simplify/radsimp.py in parse_derivative(deriv)
    187         # scan derivatives tower in the input expression and return
    188         # underlying function and maximal differentiation order
--> 189         expr, sym, order = deriv.expr, deriv.variables[0], 1
    190 
    191         for s in deriv.variables[1:]:

IndexError: tuple index out of range

Насколько я могу судить, виновником является то, что при уменьшении Derivative(exp(-x**2),(x,n)) код под ним(sympy.simplify.radsimp.parse_derivative) видит (x,n) как свободные символы и не может распознать, что x является переменной, а n является свободным символом.

Тогда возникает вопрос

Я что-то не так делаю?Возможно ли такое уменьшение с помощью * SymPy *?

Кстати, оно также не работает с предопределенной специальной функцией hermite .То есть

integrate(hermite(k,x)*hermite(l,x)*exp(-x**2),(x,-oo,oo))

не дает масштабированной дельты Кронекера.

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...