Luke wrote:
> I also check the GSL (GNU Scientific Library).  They have a nice
> numerical integrator, but it doesn't allow for a mass matrix.
> ~Luke
> On Sep 29, 4:44 pm, Luke <hazelnu...@gmail.com> wrote:
>   
>> Yes, this is something I should look into.  I am pretty sure that the
>> Netlib codes have this functionality, but it hasn't been wrapped into
>> the Python scientific packages that I know of, at least not yet.
>> scipy.integrate has odeint and ode, but both need everything in first
>> order form, no mass matrix is allowed.
>>
>> I figured that if I was going to work symbolically, I may as well go
>> as far as I can go, so if I can invert the matrices symbolically, I'd
>> prefer that.  This would also be nice because then the equations could
>> be integrated with any numerical integrator out there, as the ode
>> formulation would be as generic as possible.
>>
>> ~Luke
>>
>> On Sep 29, 4:15 pm, Alan Bromborsky <abro...@verizon.net> wrote:
>>
>>
>>
>>     
>>> Luke wrote:
>>>       
>>>> On Sep 29, 1:09 pm, Ondrej Certik <ond...@certik.cz> wrote:
>>>>         
>>>>> On Tue, Sep 29, 2009 at 12:49 PM, Luke <hazelnu...@gmail.com> wrote:
>>>>>           
>>>>>> I'm using Sympy from within PyDy to generate the equations of motion for
>>>>>> mechanical systems.  At the end of the day,  the equations can be most
>>>>>> generally written as:
>>>>>> M(x) * x'' = F(x, x', t)
>>>>>> M(x) is what is known as the mass matrix, and will in general depend on 
>>>>>> the
>>>>>> configuration of the system (positions and angles).  This matrix needs 
>>>>>> to be
>>>>>> inverted in order to solve for x'', which then will allow for numerical
>>>>>> integration or stability analysis.
>>>>>> I am generating M(x) symbolically, and in some case is it sparse, but in
>>>>>> many cases, it isn't.  Each entry of the matrix is a Sympy expression, 
>>>>>> but
>>>>>> instead of trying to invert a matrix of Sympy expressions, I introduce a
>>>>>> dummy symbol for each non-zero entries and then invert the matrix of 
>>>>>> dummy
>>>>>> symbols.  Humble systems might have 5 degrees of freedom (so a 5x5 needs 
>>>>>> to
>>>>>> be inverted), so this inversion isn't so bad, but beyond this, the matrix
>>>>>> inversions take a really long time, especially when the matrices are full
>>>>>> (no zero entries).
>>>>>> I was thinking that it might be nice to have pre-computed matrix inverses
>>>>>> for n x n matrices.  Matrix inversion is O(n^3), so it would be nice to 
>>>>>> have
>>>>>> all this precomputed symbolically, and this would greatly speed up 
>>>>>> Sympy's
>>>>>> matrix capabilities.  Inverses up to say 100x100 could be computed (or 
>>>>>> maybe
>>>>>> something smaller), and then when you need an inverse, everything would 
>>>>>> be
>>>>>> fast.  This could also be used behind the scenes (by introduction of
>>>>>> symbolic substitution dictionaries) for inverting a matrix full of sympy
>>>>>> expressions.
>>>>>>             
>>>>> The inversion of a 100x100 dense matrix would be quite a big mess, 
>>>>> wouldn't it?
>>>>>           
>>>> Yes, it would be disaster.
>>>>         
>>>>> But I see what you mean, and I think it makes sense to cache it, if it
>>>>> speeds things up. But see below.
>>>>>           
>>>>>> Does anybody know if this has been done by somebody somewhere, or have 
>>>>>> any
>>>>>> other ideas on how it could be done better than the way I suggested?
>>>>>>             
>>>>> I would first try to profile the inversion code to see why it is slow.
>>>>> Because for example the adjoint method is just a ratio of two
>>>>> determinants, so it may be the determinants calculation that is slow
>>>>> (and should be cached). However, there are 100^2 different
>>>>> determinants (right?), but I guess caching 10000 expressions should
>>>>> still be doable. But if this is the case, we should just speed up the
>>>>> determinant calculation, imho. Looking at the code, we have 2
>>>>> algorithms implemented, bareis and berkowitz.
>>>>>           
>>>> I did some timings of the three matrix inversion (GE, ADJ, LU) using
>>>> the timeit module.  I also timed the two determinant methods as well
>>>> to see they the two perform side by side.  It seems that bareis (the
>>>> default one) is drastically slower than berkowitz, even when you
>>>> call .expand() on the berkowitz determinant to make it end up with
>>>> identical symbolic expressions.  Maybe this should be the default
>>>> method for .det()?  I went up to 5x5 matrices, it started to get
>>>> really slow after that.  Gaussian elimination seems to be the slowest
>>>> one, at least for dense matrices like the ones I used.  Here is the
>>>> code I used to do the timings:
>>>>         
>>>> import timeit
>>>> from numpy import zeros, max
>>>> import matplotlib.pyplot as plt
>>>>         
>>>> # Dimension of matrix to invert
>>>> n = range(2, 6)
>>>> # Number of times to invert
>>>> number = 20
>>>> # Store the results
>>>> t = zeros((len(n), 5))
>>>>         
>>>> for i in n:
>>>>     setup_code = "from sympy import Matrix, Symbol\nM = Matrix(%d,\
>>>>         %d"%(i,i)+",lambda i,j: Symbol('m%d%d'%(i,j)))"
>>>>     t[i-2, 0] = timeit.Timer('M.inverse_GE()', setup_code).timeit
>>>> (number)
>>>>     t[i-2, 1] = timeit.Timer('M.inverse_ADJ()', setup_code).timeit
>>>> (number)
>>>>     t[i-2, 2] = timeit.Timer('M.inverse_LU()', setup_code).timeit
>>>> (number)
>>>>     t[i-2, 3] = timeit.Timer('M.det(method="bareis")',
>>>>             setup_code).timeit(number)
>>>>     t[i-2, 4] = timeit.Timer('M.det(method="berkowitz").expand()',
>>>>             setup_code).timeit(number)
>>>>         
>>>> plt.plot(n, t[:,0]/number, label='GE')
>>>> plt.plot(n, t[:,1]/number, label='ADJ')
>>>> plt.plot(n, t[:,2]/number, label='LU')
>>>> plt.plot(n, t[:,3]/number, label='bareis_det')
>>>> plt.plot(n, t[:,4]/number, label='berkowitz_det.expand()')
>>>> plt.legend(loc=0)
>>>> plt.title('Average time to complete 1 matrix inversion/determinant')
>>>> plt.xlabel('matrix dimension')
>>>> plt.ylabel('Time [seconds]')
>>>> plt.xticks(n)
>>>> plt.axis([2, n[-1], 0, max(t/number)])
>>>> plt.show()
>>>>         
>>>> I'd be curious to know if others get similar results as I do.  I
>>>> posted the results of the above script here:
>>>> http://i35.tinypic.com/so09hw.jpg
>>>>         
>>>> It looks like Gaussian elimination is suffering from the bottleneck in
>>>> the Bareis determinant since it has an assertion that calls .det() to
>>>> make sure the determinant is non-zero.
>>>>         
>>>>> Also how about the creation of so many expressions, it could be slow too.
>>>>>           
>>>> Yeah, this is true.  It seems to me though that if you had all the
>>>> inverses computed for fully populated matrices, then if some of the
>>>> entries were zero these things would simplify some (or a lot), and
>>>> then those expressions would be used rather than the full ones.
>>>>         
>>>> Maybe it could be an optional module that gets imported in when you
>>>> need to work with large matrices and want to have inverses precomputed
>>>> so that you don't have to sit and wait for them for hours?  That way
>>>> it wouldn't affect the normal behavior of Sympy, but could be imported
>>>> if desired.
>>>>         
>>>>> So what I want to say is that we should profile it and determine
>>>>> exactly what things are slowing things down, then we should speed them
>>>>> up (or cache them).
>>>>>           
>>>> Should I use cProfile for this?  Or do you recommend another profiler?
>>>>         
>>>> ~Luke
>>>>         
>>>>> Ondrej
>>>>>           
>>> Are there differential equation solvers where you don't have to invert
>>> the matrix?
>>>       
> >
>
>   
Would you give an example set of equations you wish to solve?

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sympy@googlegroups.com
To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sympy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to