I can't seem to get a benefit out of scipy's CG and sparse matrix algorithms.
When I try to solve this banded matrix equation
import time
import scipy.sparse.linalg as ssla
import scipy.sparse as ss
import numpy as np
size = 3000
x = np.ones(size)
A = ss.diags([1, -2, 1], [-1, 0, 1], shape=[size, size]).toarray()
print 'cond. nr.:{}'.format(np.linalg.cond(A))
b = np.dot(A, x)
start_time = time.clock()
sol = np.linalg.solve(A, b)
elapsed_time = time.clock() - start_time
error = np.sum(np.abs(sol - x))
print 'LU time, error:', elapsed_time, error
start_time = time.clock()
sol, info = ssla.bicg(A, b, tol=1e-12)
elapsed_time = time.clock() - start_time
error = np.sum(np.abs(sol - x))
print 'CG time, ret code, error:', elapsed_time, info, error
it takes about 20 times as long as the LU solver. From what I understood, CG isn't that much more costly than LU, even if it has to use all N iterations to reach the result. So I expected it to be at least as fast, but actually a lot faster, due to the prior knowledge about the bandedness. Does it have to do with the condition number to be so bad?
In case of a dense matrix
import time
import scipy.sparse.linalg as ssla
import numpy as np
import matplotlib.pyplot as plt
size = 1000
x = np.ones(size)
np.random.seed(1)
A = np.random.random_integers(-size, size,
size=(size, size))
print 'cond. nr.:{}'.format(np.linalg.cond(A))
b = np.dot(A, x)
start_time = time.clock()
sol = np.linalg.solve(A, b)
elapsed_time = time.clock() - start_time
error = np.sum(np.abs(sol - x))
print 'LU time, error:', elapsed_time, error
start_time = time.clock()
sol, info = ssla.bicg(A, b, tol=1e-12)
elapsed_time = time.clock() - start_time
error = np.sum(np.abs(sol - x))
print 'CG time, ret code, error:', elapsed_time, info, error
I don't get convergence at all. In this case, the condition number of A doesn't seem that large, but then I don't have a lot of experience with this kind of thing.
(1000, 1000)
matrix is trivially small. Try something bigger and sparser. – ali_m