问题描述
t = symbols('t')
v1 = np.array([[1,2,3,4,5,]])
print( type(v1) )
然后我在数组中放入一个符号
v2 = v1.dot(t)
print( type(v2) )
问题1:如果现在v2里面有一个符号,为什么它仍然是numpy.ndarray?
当我尝试集成此数组时,我无法做到
# I1 = integrate( v2,t ) # this cannot be integrate because...
# AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_poly'
然后,我必须这样做
v3 = smp.Matrix( v2 )
I2 = integrate( v3,t )
问题2:
是否有另一种集成v2的方法,而无需在sympy Matrix中对其进行更改?
解决方法
sympy
和numpy
未集成。 sympy
对象在数组中的工作范围可以视为“对象”,并具有适当的方法。否则,numpy
对sympy
对象不会做任何特殊的事情。
在isympy
会话中:
In [200]: t
Out[200]: t
In [201]: tau
Out[201]: τ
带有符号的数组将为object
dtype。这就像一个列表,其中引用了这些数字和对象。它不是特殊的数组dtype:
In [202]: arr = np.array([1,2,tau,t])
In [203]: arr
Out[203]: array([1,t],dtype=object)
np.dot
之所以有效,是因为可以添加和乘以符号:
In [204]: np.dot(arr,arr)
Out[204]:
2 2
t + τ + 5
In [205]: type(_)
Out[205]: sympy.core.add.Add
dot
具有两个匹配的1d数组,将返回一个“标量”,在这种情况下为sympy
对象。
与具有匹配的数字大小列表的点相同:
In [206]: np.dot([1,3,4],arr)
Out[206]: 4⋅t + 3⋅τ + 5
In [207]: type(_)
Out[207]: sympy.core.add.Add
但是标量为tau
的3元素列表的点会产生一个数组:
In [208]: np.array([1,3]).dot(tau)
Out[208]: array([tau,2*tau,3*tau],dtype=object)
(3,4)与(4,)的点产生一个(3,)数组:
In [210]: np.ones((3,4),int).dot(arr)
Out[210]: array([t + tau + 3,t + tau + 3,t + tau + 3],dtype=object)
sympy
也不“了解” numpy
,因此integrate(ndarray,...)
不起作用也就不足为奇了。
错误# AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_poly'
表示该数组已转换为ImmutableDenseNDimArray
sympy对象。无需详细说明,显然这是为此目的错误的sympy对象类型。
使用您的v2
:
In [220]: v2
Out[220]: array([[t,2*t,3*t,4*t,5*t]],dtype=object)
In [222]: Matrix(v2)
Out[222]: [t 2⋅t 3⋅t 4⋅t 5⋅t]
In [225]: type(_222)
Out[225]: sympy.matrices.dense.MutableDenseMatrix
In [227]: ImmutableDenseNDimArray(v2)
Out[227]: [[t 2⋅t 3⋅t 4⋅t 5⋅t]]
In [228]: type(_)
Out[228]: sympy.tensor.array.dense_ndim_array.ImmutableDenseNDimArray
这两个方法都不具有as_poly
方法,但是integrate
可能正在做一些进一步的处理。 numpy
有一个主类ndarray
,它具有一组众所周知的方法和属性。 sympy
定义了更多的类,因此我们(I)需要更加关注文档。这两个类(type(...).__mro__
)的类层次结构完全不同。
使用Matrix
,集成程序运行并产生:
In [235]: integrate(Matrix(v2),t)
Out[235]:
⎡ 2 2 2⎤
⎢t 2 3⋅t 2 5⋅t ⎥
⎢── t ──── 2⋅t ────⎥
⎣2 2 2 ⎦
如果提供了此输出,那就太好了(礼貌!)。
对于无法正常工作的情况,FULL回溯可能具有启发性:
In [236]: integrate(ImmutableDenseNDimArray(v2),t)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-236-fbba47abf5a1> in <module>
----> 1 integrate(ImmutableDenseNDimArray(v2),t)
/usr/local/lib/python3.6/dist-packages/sympy/integrals/integrals.py in integrate(*args,**kwargs)
1543
1544 if isinstance(integral,Integral):
-> 1545 return integral.doit(**doit_flags)
1546 else:
1547 new_args = [a.doit(**doit_flags) if isinstance(a,Integral) else a
/usr/local/lib/python3.6/dist-packages/sympy/integrals/integrals.py in doit(self,**hints)
592 else:
593 antideriv = self._eval_integral(
--> 594 function,xab[0],**eval_kwargs)
595 if antideriv is None and meijerg is True:
596 ret = try_meijerg(function,xab)
/usr/local/lib/python3.6/dist-packages/sympy/integrals/integrals.py in _eval_integral(self,f,x,meijerg,risch,manual,heurisch,conds)
921
922 # try to convert to poly(x) and then integrate if successful (fast)
--> 923 poly = f.as_poly(x)
924 if poly is not None and not (manual or meijerg or risch):
925 return poly.integrate().as_expr()
AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_poly'
我们需要深入研究这段代码(922行)以找出其为什么尝试f.as_poly
的原因。是否也使用Matrix
尝试了此操作,还是采用了其他方法?像这样的sympy
代码中有很多事情!
首先不需要使用np.array
。坚持使用sympy
:
In [249]: integrate(Matrix([[1,4,5]])*t,t)
Out[249]:
⎡ 2 2 2⎤
⎢t 2 3⋅t 2 5⋅t ⎥
⎢── t ──── 2⋅t ────⎥
⎣2 2 2 ⎦