Ask Your Question
0

construct a structure

asked 2013-11-26 03:09:38 -0500

gundamlh gravatar image

Dear all,

I want to construct a structured array which has 2 fields storing 2 different data type, one is a float number and the other is a polynomial matrix.

Structured Arrays (and Record Arrays) Can I use this NumPy method or any other else? NumPy doesn't know/understand the data type of a polynomial matrix defined in SAGE.

sage: R.<s> = PolynomialRing(QQ); R
Univariate Polynomial Ring in s over Rational Field
sage: H = matrix(1,2, [(s+5)**2, s]); H
[s^2 + 10*s + 25               s]
sage: H.parent()
Full MatrixSpace of 1 by 2 dense matrices over Univariate Polynomial Ring in s over Rational Field
sage: type(H[0,0])
<type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>
sage: sys = np.zeros(1, dtype=[('TF','sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint',(1,2)),('Ts','f4')])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/xxx/Programs/sage-5.10-linux-64bit/local/lib/python2.7/site-packages/sage/all_cmdline.pyc in <module>()
----> 1 sys = np.zeros(Integer(1), dtype=[('TF','sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint',(Integer(1),Integer(2))),('Ts','f4')])

TypeError: data type "sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint" not understood

Thanks in advance!

edit retag flag offensive close merge delete

3 answers

Sort by ยป oldest newest most voted
1

answered 2013-11-29 02:24:06 -0500

niles gravatar image

Unless you need something special about structured arrays, you could just define a new object class:

sage: class UsefulData(SageObject):
....:     def __init__(self,my_float,my_matrix):
....:         self.float = my_float
....:         self.matrix = my_matrix
....:

(I did this at a sage command prompt, but it's better in a notebook cell or in a separate file attached to the sage session. That way you can easily edit and update the class as you do more and more sophisticated things with it.)

sage: R.<s> = PolynomialRing(QQ); R
Univariate Polynomial Ring in s over Rational Field

sage: d1 = UsefulData(pi.n(),matrix([[1, s],[s^2, -1]]))
sage: d1.float
3.14159265358979
sage: d1.matrix
[  1   s]
[s^2  -1]

sage: d2 = UsefulData(e.n(),matrix([[s^2, s^3],[s^5, s^7]]))
sage: d2.float
2.71828182845905
sage: d2.matrix
[s^2  s^3]
[s^5  s^7]

There is a further advantage here: if you want to do something with this data, you can attach functions (methods) to the object class too. If computational time or space is an issue, you can convert the expensive parts to cython classes/attributes.

edit flag offensive delete link more

Comments

wow! Thanks! >convert the expensive parts to cython classes/attributes.< http://docs.cython.org/src/tutorial/cdef_classes.html .... just use "cpdef" instead of "def" ?

gundamlh gravatar imagegundamlh ( 2013-11-29 07:06:26 -0500 )edit

using cpdef does give some speedup, but there is a lot more you can do too. Just remember that premature optimization is a terrible mistake. Optimization without profiling is usually a waste of time too.

niles gravatar imageniles ( 2013-12-02 01:26:28 -0500 )edit
1

answered 2013-11-29 04:13:43 -0500

nbruin gravatar image

If you just want to package several data items together and refer to them by a name rather than a numerical index (in which case you could use a list), you can use the python library namedtuple:

http://docs.python.org/2/library/coll...

You'd end up with something like:

sage: from collections import namedtuple
sage: T=namedtuple('T',['scalar','M'])
sage: t=T(2.0,H)
sage: t
T(scalar=2.00000000000000, M=[s^2 + 10*s + 25               s])
sage: t.scalar
2.00000000000000
sage: t.M
[s^2 + 10*s + 25               s]

It's meant to be a variant of a tuple so it's immutable (after creation you can't change the attributes). If you need that, you can just write your own class, as Niles points out.

You could also make it a dictionary if you don't mind referring to the field names by string:

sage: d=dict(scalar=2.0,M=H)
sage: d
{'M': [s^2 + 10*s + 25               s], 'scalar': 2.00000000000000}
sage: d['M']
[s^2 + 10*s + 25               s]
edit flag offensive delete link more

Comments

Thanks! It is a good idea!

gundamlh gravatar imagegundamlh ( 2013-11-29 06:59:57 -0500 )edit
0

answered 2013-11-28 22:59:57 -0500

tmonteil gravatar image

Why don't you simply use python lists ?

sage: sys = [my_float, my_matrix]
edit flag offensive delete link more

Comments

I'd like to giive a name to each entry. for example, sys.a, sys.b, sys.c, sys.d, sys.ts, sys,x0, sys.size, sys.idelay, ....

gundamlh gravatar imagegundamlh ( 2013-11-28 23:05:03 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2013-11-26 03:09:38 -0500

Seen: 112 times

Last updated: Nov 29 '13