SymPy中lambdify无法处理共轭函数的导数问题求助
问题描述
我有一些复杂的符号函数,希望对其执行若干操作后通过lambdify转换为可调用函数。计算共轭函数的导数时遇到问题:单独求导、单独取共轭操作都能正常工作,但尝试对共轭函数的导数进行lambdify转换时,会触发以下错误:
PrintMethodNotImplementedError: Unsupported by <class 'sympy.printing.numpy.SciPyPrinter'>: <class 'sympy.core.function.Derivative'> Set the printer option 'strict' to False in order to generate partially printed code.
详情及示例
基础函数(可正常运行)
import sympy as sp a, b = sp.symbols('a b') def myfunction(x,y): return x + 1j * y myfunctionval = myfunction(a,b) myfunction_lam = sp.lambdify((a,b), myfunctionval) print(myfunction_lam(1,2)) # 输出: (1+2j)
共轭函数(可正常运行)
def myfunctionConjugate(x,y): return sp.conjugate(x + 1j * y) myfunctionConjugateval = myfunctionConjugate(a,b) myfunctionConjugate_lam = sp.lambdify((a,b), myfunctionConjugateval) print(myfunctionConjugate_lam(1,2)) # 输出: (1-2j)
导数(可正常运行)
def myfunctionDerivative(x,y): return sp.diff(x + 1j * y, x) myfunctionDerivativeval = myfunctionDerivative(a,b) myfunctionDerivative_lam = sp.lambdify((a,b), myfunctionDerivativeval) print(myfunctionDerivative_lam(1,2)) # 输出: 1
导数的共轭(可正常运行)
def myfunctionDerivativeConjugate(x,y): return sp.conjugate(sp.diff(x + 1j * y,x)) myfunctionDerivativeConjugateval = myfunctionDerivativeConjugate(a,b) myfunctionDerivativeConjugate_lam = sp.lambdify((a,b), myfunctionDerivativeConjugateval) print(myfunctionDerivativeConjugate_lam(1,2)) # 输出: 1
共轭函数的导数(无法运行)
def myfunctionConjugateDerivative(x,y): return sp.diff(sp.conjugate(x + 1j * y),x) myfunctionConjugateDerivativeval = myfunctionConjugateDerivative(a,b) myfunctionConjugateDerivative_lam = sp.lambdify((a,b), myfunctionConjugateDerivativeval) myfunctionConjugateDerivative_lam(1,2)
触发的错误信息
--------------------------------------------------------------------------- PrintMethodNotImplementedError Traceback (most recent call last) /tmp/ipykernel_13914/1657192206.py in <module> 3 4 myfunctionConjugateDerivativeval = myfunctionConjugateDerivative(a,b) ----> 5 myfunctionConjugateDerivative_lam = sp.lambdify((a,b), myfunctionConjugateDerivativeval) 6 myfunctionConjugateDerivative_lam(1,2) ~/anaconda3/lib/python3.9/site-packages/sympy/utilities/lambdify.py in lambdify(args, expr, modules, printer, use_imps, dummify, cse, docstring_limit) 878 else: 879 cses, _expr = (), expr ---> 880 funcstr = funcprinter.doprint(funcname, iterable_args, _expr, cses=cses) 881 882 # Collect the module imports from the code printers. ~/anaconda3/lib/python3.9/site-packages/sympy/utilities/lambdify.py in doprint(self, funcname, args, expr, cses) 1169 funcbody.append('{} = {}'.format(self._exprrepr(s), self._exprrepr(e))) 1170 -> 1171 str_expr = _recursive_to_string(self._exprrepr, expr) 1172 1173 if '\n' in str_expr: ~/anaconda3/lib/python3.9/site-packages/sympy/utilities/lambdify.py in _recursive_to_string(doprint, arg) 964 965 if isinstance(arg, (Basic, MatrixBase)): ---> 966 return doprint(arg) 967 elif iterable(arg): 968 if isinstance(arg, list): ~/anaconda3/lib/python3.9/site-packages/sympy/printing/codeprinter.py in doprint(self, expr, assign_to) 170 self._number_symbols = set() 171 ---> 172 lines = self._print(expr).splitlines() 173 174 # format the output ~/anaconda3/lib/python3.9/site-packages/sympy/printing/printer.py in _print(self, expr, **kwargs) 329 printmethod = getattr(self, printmethodname, None) 330 if printmethod is not None: ---> 331 return printmethod(expr, **kwargs) 332 # Unknown object, fall back to the emptyPrinter. 333 return self.emptyPrinter(expr) ~/anaconda3/lib/python3.9/site-packages/sympy/printing/codeprinter.py in _print_not_supported(self, expr) 580 def _print_not_supported(self, expr): 581 if self._settings.get('strict', False): ---> 582 raise PrintMethodNotImplementedError("Unsupported by %s: %s" % (str(type(self)), str(type(expr))) + \ 583 "\nSet the printer option 'strict' to False in order to generate partially printed code.") 584 try: PrintMethodNotImplementedError: Unsupported by <class 'sympy.printing.numpy.SciPyPrinter'>: <class 'sympy.core.function.Derivative'> Set the printer option 'strict' to False in order to generate partially printed code.
解决方案
方法1:化简表达式后再转换
SymPy对共轭函数求导后会得到未计算的Derivative对象,SciPyPrinter无法直接处理。调用lambdify前用sp.simplify()化简表达式,让导数计算完成:
def myfunctionConjugateDerivative(x,y): return sp.diff(sp.conjugate(x + 1j * y),x) # 先化简求导结果 myfunctionConjugateDerivativeval = sp.simplify(myfunctionConjugateDerivative(a,b)) myfunctionConjugateDerivative_lam = sp.lambdify((a,b), myfunctionConjugateDerivativeval) print(myfunctionConjugateDerivative_lam(1,2)) # 输出: 1
方法2:手动展开共轭再求导
对于简单的复数表达式,可直接展开共轭形式(sp.conjugate(x+1j*y)等价于x-1j*y),再对展开后的式子求导:
def myfunctionConjugateDerivative(x,y): # 直接对展开后的共轭表达式求导 return sp.diff(x - 1j * y, x) myfunctionConjugateDerivativeval = myfunctionConjugateDerivative(a,b) myfunctionConjugateDerivative_lam = sp.lambdify((a,b), myfunctionConjugateDerivativeval) print(myfunctionConjugateDerivative_lam(1,2)) # 输出: 1
方法3:关闭严格模式(不推荐)
在lambdify中设置printer={'strict': False}可绕过错误,但可能生成无效代码,仅适合调试场景:
myfunctionConjugateDerivative_lam = sp.lambdify((a,b), myfunctionConjugateDerivativeval, printer={'strict': False})
内容的提问来源于stack exchange,提问作者Reflets de Lune
相关产品推荐
相关产品推荐

