如何解决为什么 Sympy .Norm() 不将实值符号视为实数?为什么 Sympy 积分声称 0.25 不能以 a*x**b 的形式表示?
问题 1:
正如你在下面的代码中看到的,我想找到一个向量的范数,并将“t”和“L”声明为实数符号,但输出似乎将变量“t”和“L”视为尽管已将复杂变量声明为 Real。我该怎么做才能在使用 .norm() 函数时将变量视为实数?
代码:
from sympy import Symbol
from sympy import Matrix
from sympy import cos
from sympy import sin
from sympy import I
L=Symbol("L",real=True)
t=Symbol("t",real=True,nonnegative=True)
x=Matrix([[I*cos(2*t*L)/(sin(2*t*L)+1)],[1]]).norm()
print(x)
输出:
sqrt(Abs(cos(2*t*L)/(sin(2*t*L) + 1))**2 + 1)
结果应该是这个(或者至少是这个的简化版本):
sqrt(2)/sqrt(1+sin(2*t*L))
问题 2:
这是一个由两部分组成的问题。对于第一部分,我收到一条错误消息,指出当我尝试进行积分时,0.25 不能以 a*x**b
的形式表示,尽管 0.25 可以以 a*x**b
的形式表示,其中 a=1,x=2 且 b=-2;我该如何解决这个错误?当我将其应用于更广义的矩阵时,相同的积分实际上有效。对于特定情况,我将“a”设置为 0.1,否则“a”将是实非负符号。
广义矩阵:
x=Matrix([[-2*a*sin(t*L)**2+a+sin(t*L)**2,I*(2*a-1)*sin(2*t*L)/2],[I*(1- 2*a)*sin(2*t*L)/2,-2*a*cos(t*L)**2+a+cos(t*L)**2]])
具体矩阵(其中a=0.1):
x=Matrix([[0.5-0.4*cos(2*t*L),-0.4*I*sin(2*t*L)],[0.4*I*sin(2*t*L),0.4*cos(2*t*L)+0.5]])
具体矩阵的代码:
from sympy import Symbol
from sympy import Matrix
from sympy import cos
from sympy import sin
from sympy import exp
from sympy import I
from sympy import diff
from sympy import integrate
from sympy import oo
L=Symbol("L",nonnegative=True)
a=Symbol("a",nonnegative=True)
k=Symbol("k")
x=Matrix([[0.5-0.4*cos(2*t*L),0.4*cos(2*t*L)+0.5]])
y=diff(x,L)
z=2*integrate(exp(-x*k)*(y*exp(-x*k)),(k,oo))
print(z)
此特定情况下的结果矩阵“z”应为:
Matrix([[1.6*t*sin(2*t*L),-1.6*I*t*cos(2*t*L)],[1.6*I*t*cos(2*t*L),-1.6*t*sin(2*t*L)]])
但是,我收到以下错误消息:
Traceback (most recent call last):
File "/Users/mk/Documents/MD/P.py",line 39,in <module>
z=2*integrate(exp(-x*k)*(y*exp(-x*k)),oo))
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/integrals.py",line 1545,in integrate
return integral.doit(**doit_flags)
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/integrals.py",line 447,in doit
return function.applyfunc(
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/matrices/common.py",line 1862,in applyfunc
return self._eval_applyfunc(f)
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/matrices/common.py",line 1802,in _eval_applyfunc
out = self._new(self.rows,self.cols,[f(x) for x in self])
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/matrices/common.py",in <listcomp>
out = self._new(self.rows,[f(x) for x in self])
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/integrals.py",line 448,in <lambda>
lambda f: self.func(f,self.limits).doit(**hints))
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/integrals.py",line 577,in doit
ret = try_meijerg(function,xab)
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/integrals.py",line 549,in try_meijerg
res = meijerint_definite(function,x,a,b)
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/meijerint.py",line 1818,in meijerint_definite
res = _meijerint_definite_2(f,x)
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/meijerint.py",line 1927,in _meijerint_definite_2
res = _meijerint_definite_3(g,line 1944,in _meijerint_definite_3
ress = [_meijerint_definite_4(g,x) for g in f.args]
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/meijerint.py",in <listcomp>
ress = [_meijerint_definite_4(g,line 1997,in _meijerint_definite_4
gs = _rewrite2(f,line 1583,in _rewrite2
if any(_rewrite_single(expr,False) is None for expr in _mul_args(g)):
File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/meijerint.py",in <genexpr>
if any(_rewrite_single(expr,line 1471,in _rewrite_single
r1 = _get_coeff_exp(unpolarify(fac.subs(subs).subs(z,x),File "/Users/mk/opt/anaconda3/lib/python3.8/site-packages/sympy/integrals/meijerint.py",line 338,in _get_coeff_exp
raise _CoeffExpValueError('expr not of form a*x**b: %s' % expr)
_CoeffExpValueError: expr not of form a*x**b: 0.250000000000000
对于这个问题的第二部分,广义情况下的结果矩阵“z”仅简化为:
Matrix([I*t*(2*a*exp(4*I*t*L)-2*a-exp(4*I*t*L)+1)*exp(-2*I*t*L),I*t*(2*a*exp(4*I*t*L)+2*a-exp(4*I*t*L)-1)*exp(-2*I*t*L)],[I*t*(-2*a*exp(4*I*t*L)-2*a+exp(4*I*t*L)+1)*exp(-2*I*t*L),I*t*(-2*a*exp(4*I*t*L)+2*a+exp(4*I*t*L)-1)*exp(-2*I*t*L)]])
而不是一直简化到:
Matrix([[2*t*(1-2*a)*sin(2*t*L),2*I*t*(2*a-1)*cos(2*t*L)],[2*I*t*(1-2*a)*cos(2*t*L),2*t*(2*a-1)*sin(2*t*L)]])
当我使用另一个公式来查找“z”时,我收到了进一步简化的版本,但我想坚持使用这个公式,因为它更通用。有没有办法在仍然使用此公式的同时接收更简化的矩阵?
解决方法
您对假设一直很小心,但 SymPy 不会对表达式 sin(real) + 1
进行特殊处理以将其识别为非负。但是您可以通过用具有该假设的单个符号替换该表达式来微调它,让 Abs 自动简化,删除临时符号,然后进行trigsimp 以获得您预期的结果:
>>> from sympy import Dummy
>>> nn = Dummy(nonnegative=True)
>>> eq = sqrt(Abs(cos(2*L*t)/(sin(2*L*t) + 1))**2 + 1)
>>> eq.subs(sin(2*L*t) + 1,nn).subs(nn,sin(2*L*t) + 1)
sqrt(1 + cos(2*L*t)**2/(sin(2*L*t) + 1)**2)
>>> trigsimp(_)
sqrt(2)*sqrt(1/(sin(2*L*t) + 1))
在我为此行为打开的 issue 上提供了更强大的解决方案(变通方法)。但是对于您的特定情况,您似乎想要一个表达式,在它重要的上下文中(例如在 sqrt
和 abs
中),触发器函数永远不会采用它们的 +/-1 值。也许这将满足该要求:
def trig_ne1(q):
from sympy import cos,sin,tanh
t = [i for i in q.atoms(cos,tanh) if i.is_real]
reps = dict(zip(t,[Dummy(positive=1)-1 for i in t]))
qs = q.xreplace(reps)
qs = qs.xreplace({v+1:k+1 for k,v in reps.items()})
reps = dict(zip(t,[Dummy(negative=1)+1 for i in t]))
qs = q.xreplace(reps)
qs = qs.xreplace({v-1:k-1 for k,v in reps.items()})
return qs
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。