[sage-support] How convert sage matrix to numpy array?

1,502 views
Skip to first unread message

Bastian Weber

unread,
Apr 16, 2010, 6:41:50 AM4/16/10
to sage-s...@googlegroups.com
Hi,


what is the proper way to convert a sage matrix to a numpy 2d-array?

The obvious way, i.e.

a=np.array(matrix([3 4]))

produces a 0d-array (thus a.shape is an empty tuple) which is not what I
want.

If I use a sympy Matrix instead

b=np.array(sp.Matrix([3 4]))

it works as expected (b.shape == (2,1), i.e. a row vector)

Maybe there is an easy way to convert a sage matrix to a sympy matrix?

Just for explanation:
I use numpy arrays (with dtype=object) to perform things like element
wise multiplication and flattening.


Greetings,
Bastian

--
To post to this group, send email to sage-s...@googlegroups.com
To unsubscribe from this group, send email to sage-support...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-support
URL: http://www.sagemath.org

Harald Schilly

unread,
Apr 16, 2010, 6:53:32 AM4/16/10
to sage-support
On Apr 16, 12:41 pm, Bastian Weber <bastian.we...@gmx-topmail.de>
wrote:
> what is the proper way to convert a sage matrix to a numpy 2d-array?
>

Hi, well, basically, I don't think you have to convert it except you
need it for some special applications. Sage can do arithmetic over the
matrices. However, this short session should answer all your
questions:


sage: m = matrix(RDF, 2, range(4)); m
[0.0 1.0]
[2.0 3.0]
sage: type(m)
<type 'sage.matrix.matrix_real_double_dense.Matrix_real_double_dense'>

sage: n = m.numpy()
sage: type(n)
<type 'numpy.ndarray'>

# and back again:
sage: type(matrix(n))
<type 'sage.matrix.matrix_real_double_dense.Matrix_real_double_dense'>

sage: n
array([[ 0., 1.],
[ 2., 3.]])

sage: n*n
array([[ 0., 1.],
[ 4., 9.]])

# n*n is not the matrix product!
# but it is for sage matrices:

sage: m*m
[ 2.0 3.0]
[ 6.0 11.0]

# you need "dot" from numpy

sage: from numpy import dot
sage: dot(n,n)
array([[ 2., 3.],
[ 6., 11.]])

last note: RDF = real-double-field, i.e. the "pseudo" field of double
values the cpu and numpy uses by default.

H

Bastian Weber

unread,
Apr 17, 2010, 9:20:45 AM4/17/10
to sage-s...@googlegroups.com
Hello Harald,
Thanks a lot! The .numpy method was exactly what I was looking for.
(Where should I have looked in the documentation to find out by myself?,
Maybe there are more useful hints.)
Now I can do: sympy.Matrix(m.numpy()) for example. Or use numpys resize
and reshape facilities.

Thanks also for the hint with .dot and the note on RDF.

Greetings,
Bastian
Message has been deleted

Bastian Weber

unread,
Apr 19, 2010, 1:58:03 PM4/19/10
to sage-s...@googlegroups.com
Hi Minh,

Minh Nguyen wrote:
>
>> (Where should I have looked in the documentation to find out by myself?,
>> Maybe there are more useful hints.)
>
> The numpy() method you are referring to is in the file
>
> SAGE_ROOT/devel/sage-main/sage/matrix/matrix_real_double_dense.pyx

Thanks for that hint.

>
> Unfortunately, at the moment that file is not in the reference manual
> [1] so you can't find documentation for numpy() in the reference
> manual.

Thats a pity.

> However, you could still get the relevant documentation as
> demonstrated in the following command line transcript. Notice that the
> question mark "?" means to get the documentation of the relevant
> method, function, or class.
> <SNIP>

Thats clear. I love and use the "?"-feature of ipython since I the
beginning of my python usage some years ago.

The question is: Where should I have found the information about the
existence of .numpy? And where will the next one with that problem find
it? Is there something like the scipy cookbook for sage where this could
be added?

At least this thread is tracked by search engines, hence someone who
uses the right keywords will stumble on it.

Many Thanks again.

Bastian.

Jason Grout

unread,
Apr 19, 2010, 8:12:16 PM4/19/10
to sage-s...@googlegroups.com
On 04/19/2010 12:58 PM, Bastian Weber wrote:

> The question is: Where should I have found the information about the
> existence of .numpy? And where will the next one with that problem find
> it? Is there something like the scipy cookbook for sage where this could
> be added?


In Sage, you can use tab completion to discover methods:

sage: m=random_matrix(RDF,4,4)
sage: m.<tab>

will list all the methods of m, including m.numpy

I just found that adding this line in the class definition in
matrix_double_dense.pyx:

__array__=numpy

makes it so that this now works:

sage: m=random_matrix(RDF,4,4)
sage: numpy.array(m)
array([[ 0.95041375, -0.93413188, -0.34801206, -0.81931649],
[-0.83999126, -0.35074003, 0.26855088, -0.6917416 ],
[ 0.22118328, -0.24463205, 0.98608149, -0.52649223],
[-0.01629823, 0.22644043, -0.29993975, -0.46477457]])
sage: numpy.array(m).dtype
dtype('float64')

which is certainly more natural (for a numpy person) than m.numpy()

(note that numpy.array(m) worked before, but gave back an array with
python objects, while the float64 array is more natural for matrices
over RDF).

This patch is now up at http://trac.sagemath.org/sage_trac/ticket/8719
and is ready for review!

Thanks,

Jason

Jason Grout

unread,
Apr 19, 2010, 8:18:17 PM4/19/10
to sage-s...@googlegroups.com
On 04/16/2010 05:41 AM, Bastian Weber wrote:
> Hi,
>
>
> what is the proper way to convert a sage matrix to a numpy 2d-array?
>
> The obvious way, i.e.
>
> a=np.array(matrix([3 4]))
>
> produces a 0d-array (thus a.shape is an empty tuple) which is not what I
> want.
>

To answer your original question, I think if we defined __array__ in the
top-level Sage matrix class, we could get this to work.

However, it still seems odd, since "a" does print out okay.

sage: import numpy as np
sage: a=np.array(matrix([[3, 4]]))
sage: a
array([3 4], dtype=object)
sage: a.shape
()

So I can print a, and it looks okay. What is going on there? Is that a
bug in numpy?

Thanks,

Jason

Jason Grout

unread,
Apr 19, 2010, 8:57:24 PM4/19/10
to sage-s...@googlegroups.com
On 04/19/2010 07:18 PM, Jason Grout wrote:
> On 04/16/2010 05:41 AM, Bastian Weber wrote:
>> Hi,
>>
>>
>> what is the proper way to convert a sage matrix to a numpy 2d-array?
>>
>> The obvious way, i.e.
>>
>> a=np.array(matrix([3 4]))
>>
>> produces a 0d-array (thus a.shape is an empty tuple) which is not what I
>> want.
>>


The patch at http://trac.sagemath.org/sage_trac/ticket/8719 now fixes this:


sage: import numpy as np
sage: a=np.array(matrix([3, 4]))
sage: a.shape
(1, 2)
sage: a
array([[3, 4]])
sage: a.dtype
dtype('int64')
Reply all
Reply to author
Forward
0 new messages