2

Is it advisable, while working with arrays of symbolic expresions, to use numpy arrays?

Something like

u0=numpy.array([Number(1.0), Number(1.0), Number(1.0)])

I mean, is it faster to use numpy arrays instead of python lists?

If so, certain operations with numpy arrays seem to convert automatically to float symbolic expresions, for example:

u0=np.array([Number(1.0), Number(1.0), Number(1.0)]) u = np.zeros((10, 3)) u[0] = u0

Now while type(u0[0]) >> sympy.core.numbers.Float ,

type(u[0][0]) >> numpy.float64

How can I avoid numpy to convert the symbolic expresions copied to float64?

D1X
  • 5,025
  • 5
  • 21
  • 36
  • `u0` is a 1d array of `dtype=object`. It many ways it is just like a list. `u` as created is `float`. It can be initialized as a `dtype=object`. It too will be list like, except it will allow 2d indexing, e.g. `u[0,0]`. – hpaulj Dec 08 '16 at 17:09
  • It's really unclear what you are trying to achieve here. I've tried to answer for the most likely possibilities in my answer, but I may have misread your goals. – asmeurer Dec 09 '16 at 03:07

2 Answers2

5

I doubt there's much speed difference vs. a list, since using any non-NumPy data type (i.e., any SymPy data type) in a NumPy array results in dtype=object, meaning the array is just an array of pointers (which a list is too).

It's really unclear why you want to use a NumPy array?

The first question is, why don't you want to use float64? Assumedly you are using

  • Symbolic expressions (such as x**2 or pi),
  • Rational numbers, or
  • sympy.Float objects with higher precision

Those are the only reasons I can think of that you would want to prefer a SymPy type over a NumPy one.

The main advantage of using a NumPy array would be if you want to take advantage of NumPy's superior indexing syntax. As Stelios pointed out, you can get much of this by using SymPy's tensor module. This is really the only reason to use them, and you have to be careful and be aware of which NumPy methods/functions will work and which won't.

The reason is that any NumPy mathematical function will not work (or at best, will convert the array to float64 first). The reason is that NumPy functions are designed to work on NumPy data types. They don't know about the above data types. To get exact values (symbolic expressions or rational numbers), or higher precision floating point values (for the case of sympy.Float), you need to use SymPy functions, which do not work on NumPy arrays.

If on the other hand (again, it's not clear what exactly you are trying to do), you want to do calculations in SymPy and then use NumPy functions to numerically evaluate the expressions, you should use SymPy to create your expressions, and then lambdify (or ufuncify if performance becomes an issue) to convert the expressions to equivalent NumPy functions, which can operate on NumPy arrays of NumPy dtypes.

asmeurer
  • 86,894
  • 26
  • 169
  • 240
2

I think it is ok to work with numpy arrays, if necessary. You should bear in mind that arrays are fundamentally different from lists. Most importantly, all array elements have to be of the same type and you cannot change the type.

In particular, you define the array u0 which is per default an array of floats. That is why you cannot assign any sympy objects to it.

I myself use numpy arrays to accommodate sympy expressions. Most notably, in cases where I need more than 2 dimensions and therefore cannot use Sympy matrices.

If the only reason to use arrays instead of lists is speed, it might not be advisable. Especially, since you have to be a bit careful with types (as you find out) and there should be less surprises when using lists or rather sympy.Matrix.

In your example, you can fix the problem by defining a proper data type:

u = np.zeros((10, 3), dtype=sp.Symbol)
dnalow
  • 974
  • 4
  • 14
  • Thank you! The only reason is indeed speed. The question is, does using numpy arrays increase speed? – D1X Dec 08 '16 at 13:21
  • I think that depends on your specific problem. I tested adding and multiplying of large vectors. There, sympy.Matrix gives roughly the same speed as numpy.array. I also think that reducing sympy expressions is the bottleneck in most cases. If you tell more about your case, maybe it is possible to give a better answer – dnalow Dec 08 '16 at 15:38
  • 1
    @dnalow FYI, Sympy has a [Tensor module](http://docs.sympy.org/dev/modules/tensor/index.html), which can handle multidimensional arrays. – Stelios Dec 08 '16 at 15:49
  • Sounds great. Is that a new feature or how could I miss it :-/ – dnalow Dec 08 '16 at 16:12
  • Specifying `dtype=sp.Symbol` is the same as using `dtype=object`; the array now stores pointers to the objects (much like lists). But there are pitfalls in creating this kind of array, that have been discussed in many SO questions. – hpaulj Dec 08 '16 at 16:53