简体   繁体   中英

Why a numpy array is still a <class 'numpy.ndarray'> when it has a “sympy.core.symbol.Symbol” inside?

When I declare a symbol and an array like these

t  = symbols('t')
v1 = np.array([[1, 2, 3, 4, 5, ]])

print( type(v1) )

and I put a symbol inside the array

v2 = v1.dot(t)

print( type(v2) )

Question 1: Why is v2 still a numpy.ndarray if now it has a symbol inside?

When I try to integrate this array I cannot do it

# I1 = integrate( v2 , t ) # this cannot be integrate because...

# AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_poly'

Then, I have to do this

v3 = smp.Matrix( v2 )

I2 = integrate( v3 , t )

Question 2:

Is there another way to integrate v2, without to change it in a sympy Matrix?

sympy and numpy are not integrated. sympy objects work in arrays to the extent that they can be treated as 'objects', and have the appropriate methods. Otherwise numpy does not do anything special with sympy objects.

In an isympy session:

In [200]: t                                                                                          
Out[200]: t

In [201]: tau                                                                                        
Out[201]: τ

An array with symbols will be object dtype. That's like a list, with references to those numbers and objects. It's not a special array dtype:

In [202]: arr = np.array([1,2,tau,t])                                                                

In [203]: arr                                                                                        
Out[203]: array([1, 2, tau, t], dtype=object)

np.dot works because the symbols can be added and multiplied:

In [204]: np.dot(arr,arr)                                                                            
Out[204]: 
 2    2    
t  + τ  + 5

In [205]: type(_)                                                                                    
Out[205]: sympy.core.add.Add

dot with two matching 1d arrays returns a "scalar", in this case a sympy object.

Same for a dot with matching size list of numbers:

In [206]: np.dot([1,2,3,4],arr)                                                                      
Out[206]: 4⋅t + 3⋅τ + 5

In [207]: type(_)                                                                                    
Out[207]: sympy.core.add.Add

But dot of the 3 element list with scalar tau produces an array:

In [208]: np.array([1,2,3]).dot(tau)                                                                 
Out[208]: array([tau, 2*tau, 3*tau], dtype=object)

dot of a (3,4) with (4,) produces a (3,) array:

In [210]: np.ones((3,4),int).dot(arr)                                                                
Out[210]: array([t + tau + 3, t + tau + 3, t + tau + 3], dtype=object)

sympy also does not "know" about numpy , so it shouldn't be surprising that integrate(ndarray, ...) does not work.

The error # AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_poly' indicates that the array has been converted into an ImmutableDenseNDimArray sympy object. Without getting into details, that apparently is the wrong type of sympy object for this purpose.

With your 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

Neither of these has an as_poly method, but integrate might be doing some further processing. numpy has one main class, ndarray , with a well known set of methods and attributes. sympy defines many more classes, so we (I) need to pay a lot more attention to the docs. The class hierarchy of these two classes ( type(...).__mro__ ) is totally different.


With Matrix the integrate runs and produces:

In [235]: integrate(Matrix(v2),t)                                                                    
Out[235]: 
⎡ 2         2           2⎤
⎢t    2  3⋅t      2  5⋅t ⎥
⎢──  t   ────  2⋅t   ────⎥
⎣2        2           2  ⎦

It would have been nice (polite.) if you'd provided this output.

And for the case that doesn't work, the FULL traceback might instructive:

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'

We need to dig into this code (that 922 line) to find out why it's trying f.as_poly . Did it also try that with Matrix , or did it take a different route? There's a lot going on in sympy code like this!


You didn't need to use np.array in the first place. Stick with sympy :

In [249]: integrate(Matrix([[1,2,3,4,5]])*t,t)                                                       
Out[249]: 
⎡ 2         2           2⎤
⎢t    2  3⋅t      2  5⋅t ⎥
⎢──  t   ────  2⋅t   ────⎥
⎣2        2           2  ⎦

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM