Reputation: 61
To solve a linear equation system
Ax=b
in which A is a striped matrix like
who has 5 non-zero diagonals.
But unlike a banded matrix, A has three non-zero diagonals whose offsets are 0, -1, and 1, and two non-zeros diagonals with offsets of -m and m.
I tried directly solving it with
diagonals = [Ap, As, An, Aw, Ae]
A = diags(diagonals, [0, -1, 1, -m, m]).toarray()
x = linalg.solve(A, b)
This method created the whole A. But A is spares so this method wasted too many memories to save zero elements.
So I tried using solve_banded
A = np.zeros((2 * m + 1, len(initial)))
A[0] = Ae
A[m - 1] = An
A[m] = Ap
A[m + 1] = As
A[2 * m] = Aw
x = linalg.solve_banded((m, m), A, b)
This method costs less memories than the previous ones, but it still wasted some on (2m-4) zero vectors. Is there any smarter methods which uses only the five non-zero vectors?
Upvotes: 6
Views: 3691
Reputation: 577
Hey I can partially answer this question. To reduce the memory storage, you can maintain the sparse matrix form, without turning it to large matrix by dropping to.array()
command:
A = diags(diagonals, [0, -1, 1, -m, m])
Now sparse matrix has its own spsolve
method and hence scipy.sparse.linalg.spsolve(A,b)
will work.
To boost performance further, you can sparse.linalg.splu(A).solve(b)
which converts A by LU-decomposition and then the SuperLU object again have a solve
method. (As I tested, this method is slightly faster than directly spsolve
, which also uses a LU-like decomposition. See here for instance.)
The only problem here is in midst of LU-decomposition the memory usage will also be huge due to decomposition.
I was also wondering if there is any way to synthesise the solve_banded
method with sparse matrix, as there is no inherent method.
Upvotes: 4