On Mon, Aug 21, 2023 at 1:55 PM David Bailey <d...@dbailey.co.uk> wrote:
>
> Oscar,
>
> Thanks for your very detailed reply.
>
> However, I do wonder if inversions of integer matrices of increasing
> size is the best test of the speed of SymPy vs another product.
>
> Maybe some messy algebra is better. For example:
>
> series(cos(k*x/(1-k*(1-k*x**2)/(1-x))),x,0,n)
>
> Where n is successively replaced by
> 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,etc might be a bit more realistic.

The main reason Oscar benchmarked matrices is that that's the part of
SymPy that he's focused on making faster so far. Actually, matrices
are more important than you'd think. They end up being used internally
in many calculations, in places like the solvers or integrals, so
making matrices faster will also make other parts of SymPy faster.

But actually, matrix inverse and your series example are very similar.
They both produce unwieldy expressions when computed naively. But
these expressions are much simpler if they are simplified:

>>> series(cos(k*x/(1-k*(1-k*x**2)/(1-x))),x,0,10)
1 + x**4*(k**4/(24*(1 - k)**4) - k**2*(2*k**2/(k - 1) + 3*k**2/(k -
1)**2 - 2*k/(k - 1))/(2*(1 - k)**2)) + x**5*(-k**5/(6*(1 - k)**4*(k -
1)) - k**2*(-4*k**3/(k - 1)**3 + 2*k**2/(k - 1) + 6*k*(-k**2/(k - 1) +
k/(k - 1))/(k - 1) - 2*k/(k - 1))/(2*(1 - k)**2)) +
x**6*(-k**6/(720*(1 - k)**6) + k**4*(4*k**2/(k - 1) + 10*k**2/(k -
1)**2 - 4*k/(k - 1))/(24*(1 - k)**4) - k**2*(5*k**4/(k - 1)**4 +
2*k**2/(k - 1) - 12*k**2*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**2 +
6*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) - 2*k/(k - 1) + 3*(-k**2/(k -
1) + k/(k - 1))**2)/(2*(1 - k)**2)) + x**7*(k**7/(120*(1 - k)**6*(k -
1)) + k**4*(-20*k**3/(k - 1)**3 + 4*k**2/(k - 1) + 20*k*(-k**2/(k - 1)
+ k/(k - 1))/(k - 1) - 4*k/(k - 1))/(24*(1 - k)**4) - k**2*(-6*k**5/(k
- 1)**5 + 20*k**3*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**3 + 2*k**2/(k -
1) - 4*k**2*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**2 - 8*k*(-k**2/(k -
1) + k/(k - 1))**2/(k - 1) + 6*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) -
4*k*(2*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) + (-k**2/(k - 1) + k/(k -
1))**2)/(k - 1) - 2*k/(k - 1) + 6*(-k**2/(k - 1) + k/(k -
1))**2)/(2*(1 - k)**2)) + x**8*(k**8/(40320*(1 - k)**8) -
k**6*(6*k**2/(k - 1) + 21*k**2/(k - 1)**2 - 6*k/(k - 1))/(720*(1 -
k)**6) + k**4*(35*k**4/(k - 1)**4 + 4*k**2/(k - 1) - 60*k**2*(-k**2/(k
- 1) + k/(k - 1))/(k - 1)**2 + 20*k*(-k**2/(k - 1) + k/(k - 1))/(k -
1) - 4*k/(k - 1) + 10*(-k**2/(k - 1) + k/(k - 1))**2)/(24*(1 - k)**4)
- k**2*(7*k**6/(k - 1)**6 - 30*k**4*(-k**2/(k - 1) + k/(k - 1))/(k -
1)**4 + 5*k**3*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**3 + 2*k**2/(k - 1)
+ 15*k**2*(-k**2/(k - 1) + k/(k - 1))**2/(k - 1)**2 - 4*k**2*(-k**2/(k
- 1) + k/(k - 1))/(k - 1)**2 - 8*k*(-k**2/(k - 1) + k/(k - 1))**2/(k -
1) + 6*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) - 4*k*(2*k*(-k**2/(k - 1)
+ k/(k - 1))/(k - 1) + 2*(-k**2/(k - 1) + k/(k - 1))**2)/(k - 1) +
5*k*(k**2*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**2 + 2*k*(-k**2/(k - 1)
+ k/(k - 1))**2/(k - 1) + k*(2*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) +
(-k**2/(k - 1) + k/(k - 1))**2)/(k - 1))/(k - 1) - 2*k/(k - 1) +
9*(-k**2/(k - 1) + k/(k - 1))**2 - 4*(-k**2/(k - 1) + k/(k -
1))*(2*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) + (-k**2/(k - 1) + k/(k -
1))**2))/(2*(1 - k)**2)) + x**9*(-k**9/(5040*(1 - k)**8*(k - 1)) -
k**6*(-56*k**3/(k - 1)**3 + 6*k**2/(k - 1) + 42*k*(-k**2/(k - 1) +
k/(k - 1))/(k - 1) - 6*k/(k - 1))/(720*(1 - k)**6) + k**4*(-56*k**5/(k
- 1)**5 + 140*k**3*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**3 + 4*k**2/(k
- 1) - 20*k**2*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**2 - 40*k*(-k**2/(k
- 1) + k/(k - 1))**2/(k - 1) + 20*k*(-k**2/(k - 1) + k/(k - 1))/(k -
1) - 20*k*(2*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) + (-k**2/(k - 1) +
k/(k - 1))**2)/(k - 1) - 4*k/(k - 1) + 20*(-k**2/(k - 1) + k/(k -
1))**2)/(24*(1 - k)**4) - k**2*(-8*k**7/(k - 1)**7 + 42*k**5*(-k**2/(k
- 1) + k/(k - 1))/(k - 1)**5 - 6*k**4*(-k**2/(k - 1) + k/(k - 1))/(k -
1)**4 - 24*k**3*(-k**2/(k - 1) + k/(k - 1))**2/(k - 1)**3 +
5*k**3*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**3 + 2*k**2/(k - 1) +
15*k**2*(-k**2/(k - 1) + k/(k - 1))**2/(k - 1)**2 - 4*k**2*(-k**2/(k -
1) + k/(k - 1))/(k - 1)**2 - 8*k*(-k**2/(k - 1) + k/(k - 1))**2/(k -
1) + 6*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) - 4*k*(2*k*(-k**2/(k - 1)
+ k/(k - 1))/(k - 1) + 3*(-k**2/(k - 1) + k/(k - 1))**2)/(k - 1) -
6*k*(k**3*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**3 + 3*k**2*(-k**2/(k -
1) + k/(k - 1))**2/(k - 1)**2 + k*(k**2*(-k**2/(k - 1) + k/(k - 1))/(k
- 1)**2 + 2*k*(-k**2/(k - 1) + k/(k - 1))**2/(k - 1) +
k*(2*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) + (-k**2/(k - 1) + k/(k -
1))**2)/(k - 1))/(k - 1))/(k - 1) + 5*k*(k**2*(-k**2/(k - 1) + k/(k -
1))/(k - 1)**2 + 2*k*(-k**2/(k - 1) + k/(k - 1))**2/(k - 1) +
k*(2*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) + 2*(-k**2/(k - 1) + k/(k -
1))**2)/(k - 1) + (-k**2/(k - 1) + k/(k - 1))*(2*k*(-k**2/(k - 1) +
k/(k - 1))/(k - 1) + (-k**2/(k - 1) + k/(k - 1))**2))/(k - 1) - 2*k/(k
- 1) + 12*(-k**2/(k - 1) + k/(k - 1))**2 - 4*(-k**2/(k - 1) + k/(k -
1))*(2*k*(-k**2/(k - 1) + k/(k - 1))/(k - 1) + (-k**2/(k - 1) + k/(k -
1))**2) - 4*(-k**2/(k - 1) + k/(k - 1))*(2*k*(-k**2/(k - 1) + k/(k -
1))/(k - 1) + 2*(-k**2/(k - 1) + k/(k - 1))**2) + 5*(-k**2/(k - 1) +
k/(k - 1))*(k**2*(-k**2/(k - 1) + k/(k - 1))/(k - 1)**2 +
2*k*(-k**2/(k - 1) + k/(k - 1))**2/(k - 1) + k*(2*k*(-k**2/(k - 1) +
k/(k - 1))/(k - 1) + (-k**2/(k - 1) + k/(k - 1))**2)/(k - 1)))/(2*(1 -
k)**2)) - k**2*x**2/(2*(1 - k)**2) + k**3*x**3/((1 - k)**2*(k - 1)) +
O(x**10)
>>> series(cos(k*x/(1-k*(1-k*x**2)/(1-x))),x,0,10).simplify()
(-40320 + 362880*k - 1451520*k**2 + 20160*k**2*x**2 + 3386880*k**3 -
141120*k**3*x**2 + 40320*k**3*x**3 + 40320*k**3*x**4 + 40320*k**3*x**5
+ 40320*k**3*x**6 + 40320*k**3*x**7 + 40320*k**3*x**8 +
40320*k**3*x**9 - 5080320*k**4 + 423360*k**4*x**2 - 241920*k**4*x**3 -
223440*k**4*x**4 - 161280*k**4*x**5 - 100800*k**4*x**6 -
40320*k**4*x**7 + 20160*k**4*x**8 + 80640*k**4*x**9 + 5080320*k**5 -
705600*k**5*x**2 + 604800*k**5*x**3 + 552720*k**5*x**4 +
194880*k**5*x**5 - 67200*k**5*x**6 - 248640*k**5*x**7 -
349440*k**5*x**8 - 369600*k**5*x**9 - 3386880*k**6 + 705600*k**6*x**2
- 806400*k**6*x**3 - 823200*k**6*x**4 + 107520*k**6*x**5 +
581336*k**6*x**6 + 685440*k**6*x**7 + 527520*k**6*x**8 +
208320*k**6*x**9 + 1451520*k**7 - 423360*k**7*x**2 + 604800*k**7*x**3
+ 823200*k**7*x**4 - 564480*k**7*x**5 - 1024968*k**7*x**6 -
651504*k**7*x**7 + 30576*k**7*x**8 + 679056*k**7*x**9 - 362880*k**8 +
141120*k**8*x**2 - 241920*k**8*x**3 - 552720*k**8*x**4 +
672000*k**8*x**5 + 984648*k**8*x**6 + 53088*k**8*x**7 -
865033*k**8*x**8 - 1208256*k**8*x**9 + 40320*k**9 - 20160*k**9*x**2 +
40320*k**9*x**3 + 223440*k**9*x**4 - 369600*k**9*x**5 -
621656*k**9*x**6 + 430416*k**9*x**7 + 1073353*k**9*x**8 +
711752*k**9*x**9 - 40320*k**10*x**4 + 80640*k**10*x**5 +
268800*k**10*x**6 - 389760*k**10*x**7 - 675696*k**10*x**8 +
75936*k**10*x**9 - 60480*k**11*x**6 + 120960*k**11*x**7 +
278880*k**11*x**8 - 309120*k**11*x**9 - 80640*k**12*x**8 +
161280*k**12*x**9 + O(x**10))/(40320*(k**9 - 9*k**8 + 36*k**7 -
84*k**6 + 126*k**5 - 126*k**4 + 84*k**3 - 36*k**2 + 9*k - 1))

By computing matrix inverse (or series) using the polys, you can avoid
the enormous expressions because the polys can only represent
polynomials in the more simplified "expanded" form. So cancellation of
terms happens automatically rather than being buried in the large
expression in a way that can never actually reveal itself until you
expand everything out. So the exact same principles that Oscar has
been talking about apply to this series expansion. The main difference
is that series expansions aren't used by as many other algorithms
(they are used in limits, but that's about it), whereas matrices are
used all over the place, so focusing on matrices for now can lead to
bigger performance wins.

Aaron Meurer

>
> It might be best if the result is assigned to a variable so as to
> exclude the cost of converting it to a string.
>
> I am sure I am teaching my grandmother to suck eggs (not that either of
> them ever did), but I hope you can see my point.
>
> David
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sympy+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sympy/c4796186-9cfd-d0de-6e0e-5de3ad5c343f%40dbailey.co.uk.

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sympy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/CAKgW%3D6%2BrwXYPHVwQ37fZq%2B%2BUM4xtUnnaGRwLhGZhqs11bUEZkg%40mail.gmail.com.

Reply via email to