Я пытаюсь получить 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))
не дает масштабированной дельты Кронекера.
Спасибо