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.