def grmagnus2(alpha, beta, betad, kp):
    # grmagnus with sparse matrices
    # From J. Phys. F Vol 14, 1984, 1205, M P Lopez Sancho, J. Rubio
    # 20-50 % faster than gravik
    # From Huckel IV Simulator
    global I
    tmp = linalg.inv(alpha.todense())           # Inverse part of Eq. 8
    t = (-1*tmp)*(betad).todense()              # Eq. 8 (t0)
    tt = (-1*tmp)*(beta).todense()              # Eq. 8 (t0 tilde)
    T = t.copy()                                # First term in Eq. 16
    Toldt = I.copy()                            # Product of tilde t in subsequent terms in Eq. 16
    change = 1                                  # Convergence measure
    counter = 0                                 # Just to make sure no infinite loop

    etag = 0.000001
    etan = 0.0000000000001
    while linalg.norm(change) > etag and counter < 100:
        counter += 1
        Toldt = Toldt*tt # Product of tilde t in subsequent terms in Eq. 16
        tmp = I - t*tt - tt*t
        if (1/(linalg.cond(tmp))) < etan:
            g = 0
            print "1: tmp NaN or Inf occured, return forced. Kp: " + str(kp)
            return g

        tmp = faster_inverse(tmp)                      # Inverse part of Eq. 12
        t = (tmp*t*t)                                  # Eq. 12 (t_i)
        tt = (tmp*tt*tt)                               # Eq. 12 (t_i tilde)
        change = Toldt*t                               # Next term of Eq. 16
        T = T + change                                 # Add it to T, Eq. 16

        if isnan(change).sum() or isinf(change).sum():
            g = 0
            print "2: tmp NaN or Inf occured, return forced. Kp: " + str(kp)
            return g

    g = (alpha + beta*T)

    if (1/(linalg.cond(g))) < etan:
        g = 0
        print "3: tmp NaN or Inf occured, return forced. Kp: " + str(kp)
        return g

    g = faster_inverse(g)
    gn = (abs(g - linalg.inv(alpha - beta*g*betad)))

    if gn.max() > 0.001 or counter > 99:
        g = 0
        print "4: Attention! not correct sgf. Kp: " + str(kp)
        return g

    # Help save memory
    del tmp, t, tt, T, Toldt, change, counter, etag, etan, gn

    return g
def grmagnus(alpha, beta, betad, kp):
    # From J. Phys. F Vol 14, 1984, 1205, M P Lopez Sancho, J. Rubio
    # 20-50 % faster than gravik
    # From Huckel IV Simulator
    tmp = linalg.inv(alpha)                     # Inverse part of Eq. 8
    t = (-1*tmp)*(betad)                        # Eq. 8 (t0)
    tt = (-1*tmp)*(beta)                        # Eq. 8 (t0 tilde)
    T = t.copy()                                # First term in Eq. 16
    Id = eye(alpha.shape[0])                    # Save the identity matrix
    Toldt = Id.copy()                           # Product of tilde t in subsequent terms in Eq. 16
    change = 1                                  # Convergence measure
    counter = 0                                 # Just to make sure no infinite loop

    etag = 0.000001
    etan = 0.0000000000001
    while linalg.norm(change) > etag and counter < 100:
        counter += 1
        Toldt = Toldt.dot(tt) # Product of tilde t in subsequent terms in Eq. 16
        if (1/(linalg.cond(Id - dot(t,tt) - dot(tt,t)))) < etan:
            g = 0
            print "1: tmp NaN or Inf occured, return forced. Kp: " + str(kp)
            return g

        tmp = linalg.inv(Id - t.dot(tt) - tt.dot(t)) # Inverse part of Eq. 12

        t = tmp.dot(t).dot(t)       # Eq. 12 (t_i)
        tt = tmp.dot(tt).dot(tt)    # Eq. 12 (t_i tilde)
        change = Toldt.dot(t)       # Next term of Eq. 16
        T = T + change              # Add it to T, Eq. 16

        if isnan(change).sum() or isinf(change).sum():
            g = 0
            print "2: tmp NaN or Inf occured, return forced. Kp: " + str(kp)
            return g

    if (1/(linalg.cond(alpha + beta.dot(T)))) < etan:
        g = 0
        print "3: tmp NaN or Inf occured, return forced. Kp: " + str(kp)
        return g

    g = linalg.inv(alpha + beta.dot(T))

    gn = abs(g - linalg.inv(alpha - beta.dot(g).dot(betad)))

    if gn.max() > 0.001 or counter > 99:
        g = 0
        print "4: Attention! not correct sgf. Kp: " + str(kp)
        return g

    nan_inf_flag = 0

    # Help save memory
    del tmp, t, tt, T, Id, Toldt, change, counter, etag, etan, gn

    return g