'Fast algorithm for solving a lower-triangular system,
exploiting the sparsity of the given matrix.'

def _lower_triangular_solve(self, rhs):

    rows = [[] for i in range(self.rows)]
    for (i, j, v) in self.row_list():
        if (i > j):
            rows[i].append((j, v))
    X = rhs.copy()
    for i in range(self.rows):
        for (j, v) in rows[i]:
            X[(i, 0)] -= (v * X[(j, 0)])
        X[(i, 0)] /= self[(i, i)]
    return self._new(X)
