On Tue, 11 Jan 2022 at 12:30, Gerardo Suarez <[email protected]> wrote: > > Sure, sorry about the image, I was unaware of how easy is to generate python > code with the print methods
Thanks for that. I just wanted to test it to see if I could see what was slow or whether there is already a faster way to do this in SymPy. I think that the approach that is needed for this sort of thing is along the lines of what you see here: https://github.com/sympy/sympy/issues/21834 Basically there already is a faster matrix implementation that is used internally by each matrix but it's faster routines are not used most of the time yet. The faster implementation is called DomainMatrix and every Matrix has an internal _rep attribute that is a DomainMatrix: In [44]: M = randMatrix(17) In [45]: %time Mok = M.inv() CPU times: user 21.9 s, sys: 32 ms, total: 21.9 s Wall time: 21.9 s In [46]: %time Mok = M._rep.to_field().inv().to_Matrix() CPU times: user 20 ms, sys: 0 ns, total: 20 ms Wall time: 20.2 ms For this example you see that DomainMatrix is 1000x faster but the difference grows as the matrices get larger. See here for more about DomainMatrix and the domain system: https://docs.sympy.org/latest/modules/polys/domainmatrix.html https://docs.sympy.org/latest/modules/polys/domainsintro.html Note that usually the _rep for a Matrix is a DomainMatrix with the EXRAW domain. For faster results you really need a domain that is not EX or EXRAW. In your particular case the domain is more complicated so you need to do something like this to discover the domain automatically: In [50]: from sympy.polys.matrices import DomainMatrix In [51]: dM = DomainMatrix.from_Matrix(e) In [52]: dM.domain Out[52]: QQ_I[g,epsilon_c,epsilon_h,gamma_c,gamma_h,n_c,n_h] Unfortunately in this domain calculations are not faster and that's due to multivariate gcd being slow because it's based on dense multivariate polynomials which are very inefficient when you have many symbols. The gcd only comes in at the final step so basically what has been computed is the matrix of cofactors and you're dividing by the determinant. Each involves large polynomials and it is trying to cancel out common factors. It could be possible to skip that step and just return a matrix where every element has a large and complicated determinant expression in the denominator. The things that should be done to improve this are: 1. Add code in inv to check for domains that can be handled efficiently by DomainMatrix (e.g. at least ZZ, QQ, ZZ_I, QQ_I) and delegate to the lower-level methods. 2. Add the fraction-free methods for DomainMatrix that are referred to in the issue above. 3. Implement proper sparse polynomial gcd: https://github.com/sympy/sympy/issues/20874 4. Improve pivoting in the solver methods for inv, det etc. I had some ideas in this PR (although it is now out of date): https://github.com/sympy/sympy/pull/20483 5. Delegate the core polynomial manipulation and some matrix operations to a fast C library like flint: https://www.flintlib.org/ The other thing that is really needed is good benchmarks to be added to the benchmarks repo. We need to make sure that we can keep track of when things are getting faster or slower every time changes are made. Otherwise hard-won performance gains can disappear because of seemingly unimportant modifications in the codebase. There absolutely is interest in working on this. I plan to do some of these things but probably not for some time. If you want to have a go at any of this then I'm happy to help. -- Oscar > However, I care more about how to speed up matrix inversion in general, as it > was terribly fast in Mathematica and it never finished in sympy. I guess > there is a more efficient way than using > > e.inv() > El martes, 11 de enero de 2022 a las 3:21:33 UTC+1, Oscar escribió: >> >> On Monday, 10 January 2022 at 15:51:49 UTC [email protected] wrote: >>> >>> Hi, >>> >>> So I was working in some problem and I had to switch to mathematica due to >>> the time the inverse of a matrix was taking, in mathematica it was solved >>> in less than a second while the computation in sympy has been running for a >>> day and hasn't finished. >>> >>> Is there anyway to speed up matrix inversion in sympy? >>> >>> Given that it is so much faster in mathematica is there any interest in >>> implementing some method (maybe theirs) that yields the inverse of a matrix >>> faster? if so I'd like to do it maybe someone could give me some pointers >>> to get me started >>> >>> The matrix is 15*15 and attached as an image, but any example of how to >>> speed things up will do. Thanks a lot! >> >> >> The image is not a useful way to share this. Can you show simple code to >> make this matrix? >> >> (i.e. just the code to make the symbols and then something like the repr() >> of the matrix but make sure it's fully runnable code without any missing >> bits) >> >> -- >> Oscar > > -- > 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 [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sympy/5fb279aa-81e9-49ca-bbed-0a65e184c507n%40googlegroups.com. -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAHVvXxTSDDKaTkG3%2B7i5gm9h%2Bm1XDAniF8kK32e7BO9EOEPG1g%40mail.gmail.com.
