# Why functions are much slower than var in some calculations?

Hi,

I am doing symbolic calculations using sage. I want to take derivatives thus I defined some general functions. But I found the functions made other symbolic calculations much more slowly. For example:

a = function('a',t,x,y,z)
var('a1 a2 a3 a4')

# case 1
time matrix(SR, 2, [a,a2,a3,a4]).inverse()
# Time: CPU 0.23 s, Wall: 0.23 s

# case 2
time matrix(SR, 2, [a1,a2,a3,a4]).inverse()
# Time: CPU 0.01 s, Wall: 0.01 s


There is a big time difference simply because in case 1 a is a variable. When considering 4x4 matrices, the difference becomes huge.

I believe there are a few other command slowed down greatly by defining functions, because of the performance difference in my code. I haven't factored out them yet.

Any ideas to improve speed in this case? Thank you very much!

edit retag close merge delete

Sort by » oldest newest most voted

Huh, that's weird. I tried it in several different ways and this is consistent.

I can tell you where the bottleneck is. It's in _echelon_in_place_classical. I called your matrices M and N, and:

sage: A1 = M.augment(M.parent().identity_matrix())
sage: time A1 = M.augment(M.parent().identity_matrix())
Time: CPU 0.00 s, Wall: 0.00 s
sage: time A2 = N.augment(N.parent().identity_matrix())
Time: CPU 0.00 s, Wall: 0.00 s
sage: time A1._echelon_in_place_classical()
Time: CPU 0.00 s, Wall: 0.01 s
sage: time A2._echelon_in_place_classical()
Time: CPU 0.24 s, Wall: 0.24 s


My (uninformed) guess is that there is a lot more Python that needs to be used with a "function" than with a "variable", slowing down the Cython. Anyone else?

more

My guess would be that the code tries to simplify the symbolic expression at one point, which means calling maxima via a pexpect interface. This is going to be much slower than just flinging the variables around.

@kcrisman: Thanks a lot for your result!

I am a new sage user thus I still have no idea how A2._echelon_in_place_classical() slows down cython and how to get it improved.

Just to mention, as a work around, now I use a 2d list instead of a matrix object, and hard-cored a formula for inverse matrix to avoid the problem (because I only use 4*4 symmetric matrix now).

On the other hand, it is still extremely interesting to find a solution to this problem :)

more