Comment #23 on issue 2015 by smi...@gmail.com: Hangs attempting to solve a system of linear equations
http://code.google.com/p/sympy/issues/detail?id=2015

It seems that the method of finding determinants of minors is actually very good for a sparse system like this since minors of elements in a given row that are 0 need not be computed. Here is a very rudimentary implementation that just uses the first row in the matrix to compute the determinant. The total time to turn the equations into a matrix system and compute the inverse is about 0.2 seconds:

def inv(self, factored=True, det=None):
    """Return the inverse of self using the determinant method `det`.
    """
    n = self.rows
    d = det(self)
    if d is S.Zero:
        raise ValueError("Matrix det == 0; not invertible.")
    ret = zeros(n)
    for i in range(n):
        s = (-1)**i
        for j in range(n):
            di = det(self.minorMatrix(i, j))
            ret[j, i] = s*di
            s = -s
    return (ret, d) if factored else ret/d

def det_minor(self):
    """Return the determinant of self computed from minors without
    introducing new nesting in products.
    """
    n = self.rows
    if n == 2:
        return self[0,0]*self[1,1] - self[1,0]*self[0,1]
    else:
        args = []
        sgn = 1
        for i in range(n):
            mi = self[0, i]
            if mi:
                args.append(sgn*Add(*[mi*d for d in Add.make_args(det_minor(
                    self.minorMatrix(0, i)))]))
            sgn = -sgn
        return Add(*args)

from sympy.abc import *
from sympy import *
eqs=Matrix([[b - c/d + r/d], [c*(1/g + 1/e + 1/d) - f/g - r/d], [-c/g +
f*(1/j + 1/i + 1/g) - h/i], [-f/i + h*(1/m + 1/l + 1/i) - k/m], [-h/m
+ k*(1/p + 1/o + 1/m) - n/p], [-k/p + n*(1/q + 1/p)]])
v=Matrix([f,h,k,n,b,c])

from time import time
t=time(); J = eqs.jacobian(v); r = J*v-eqs; i = inv(J, factored=False, det=det_minor); sol=i*r; time()-t

0.1979999542236328
# check the inverse
ii,d=inv(J, det=det_minor)
(ii*J/d).expand()
Matrix([
[1, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 1]])


The solution sizes are much smaller, too, than those from comment 19:

[s.count_ops() for s in sol]
[164, 148, 138, 135, 203, 196]


--
You received this message because this project is configured to send all issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

--
You received this message because you are subscribed to the Google Groups 
"sympy-issues" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sympy-issues+unsubscr...@googlegroups.com.
To post to this group, send email to sympy-issues@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy-issues.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to