为什么当一个numpy数组里面有一个“ sympy.core.symbol.Symbol”时,它仍然仍然是<class'numpy.ndarray'>?

问题描述

当我声明一个符号和一个像这样的数组

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中对其进行更改?

解决方法

sympynumpy未集成。 sympy对象在数组中的工作范围可以视为“对象”,并具有适当的方法。否则,numpysympy对象不会做任何特殊的事情。

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  ⎦

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...