With such small matrices (and elements), you're essentially measuring
overhead rather than arithmetic here. Of course if you have lots of
small matrices, that may be a relavant thing to measure. As the matrix
size grows, they should be the same, as multiplying CDF matrices
simply defers to multiplying numpy matrices.
sage: A= MatrixSpace(CDF, 200).random_element()
sage: B= MatrixSpace(CDF, 200).random_element()
sage: %timeit A*B
125 loops, best of 3: 7.31 ms per loop
sage: AA= numpy.array(A); BB= numpy.array(B)
sage: %timeit AA.dot(BB)
125 loops, best of 3: 7.34 ms per loop
- Robert
You might consider using Cython and writing a custom 2x2 matrix class.
It wouldn't be difficult... so I'll write one right now and respond
with the benchmarks.
-- William
> --
> 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
--
William Stein
Professor of Mathematics
University of Washington
http://wstein.org
+1, exactly what I was going to consider. Depending on how naturally
it fits your problem, you could also consider packing your 2x2
matrices into larger arrays (e.g. representing n 2x2 matrices by a 4 x
n matrix and manually doing the multiplication) so you can your
computations in a "vectorized" form.
sage: import numpy
sage: m = numpy.matrix([[1,2],[3,4]])
sage: m[:,0]
matrix([[1, 3]])
sage: m[:,int(0)]
matrix([[1],
[3]])
That is, if you use a Sage integer to index a numpy matrix, you don't
get the expected shape back. I know exactly why this happens --
http://trac.sagemath.org/sage_trac/ticket/10928 -- but ideally it
should be patched upstream.
Doug
Here it is: http://480.sagenb.org/home/pub/97/
I ended up using GSL's complex matrix data type and the BLAS level 3
routine to do the multiplication. I did not add any other
convenience functions to the class, so some more will probably be
needed for your application.
The results:
sage: timeit('a*a2')
625 loops, best of 3: 643 ns per loop
sage: timeit('b*b2')
625 loops, best of 3: 25.8 µs per loop
sage: timeit('c.dot(c2)')
625 loops, best of 3: 2.52 µs per loop
sage: 2.52/.643
3.91912908242613
sage: 25.8/.643
40.1244167962675
So, my one off GSL based class is 4 times faster than numpy and 40
times faster than Sage at matrix squaring.
http://480.sagenb.org/home/pub/97/
I'm curious why you didn't just store the 4 complex numbers in C. I
tried it and got a much bigger speedup: 17x faster than numpy and 150x
faster than Sage. See http://sagenb.org/home/pub/4303/
Thanks,
Jason
I was concerned about "numerical stability" and figured BLAS would
deal with that. But maybe that doesn't matter.
Most importantly, I forgot about Cython's complex type, which I now
remember Robert Bradshaw wrote for his thesis work. I wasn't looking
forward to writing your line:
res.m00=self.m00*right.m00+self.m01*right.m10
but against the gsl library. But using the cython type in complex,
you get the above at C speed with easy notation, which is pretty
awesome.
> I tried
> it and got a much bigger speedup: 17x faster than numpy and 150x faster than
> Sage. See http://sagenb.org/home/pub/4303/
Nice.
>
> Thanks,
>
> Jason
cimport gives access to the underlying C-level data structure.
> ** and why do these imports anyway, are they necessary for "cdef
> complex..." to work?
Nope! If you just want to use Python's complex data type you could
rewrite the code
to not use any imports.
> ** I didn't know PY_NEW. What is the difference between res=
> PY_NEW(Matrix2) and simply res= Matrix2(0,0,0,0) (say) ? and what
> about using PY_NEW with a class that *requires* parameters to its
> __init__?
PY_NEW is a macro that creates the class without calling __init__.
This is an optimization.
> ** more generally, is there a Cython tutorial that would be (just)
> sufficiently advanced to cover such an example?
You may find chapter 3 of this book I'm writing helpful:
http://wstein.org/books/sagebook/sagebook.pdf
You can do all that -- it just costs you about 2 hours of background
education and practice. You have to use a .pyx file, probably a
setup.py file, and follow the standard instructions at cython.org:
http://docs.cython.org/src/quickstart/index.html
-- William
I had them because I was copying and modifying William's code and didn't
ever delete them.
Thanks,
Jason