I have the following code to construct a tridiagonal matrix:
ClearAll[th];
th[nwells_ /; EvenQ@nwells] := Module[
{size = nwells, bdiag},
bdiag = RandomReal[{0, 99}, size - 1];
SparseArray[
{
Band[{1, 1}] -> bdiag,
Band[{1, 2}] -> -0.5,
Band[{2, 1}] -> -0.5},
{size - 1, size - 1}
]
]
This will be executed millions of times (bdiag
is actually something that will change each time, so this is unavoidable). I'd like to speed it up as much as possible. Any ideas? I am interested in values of nwells
of the order of 100 to 1000.
EDIT: Let us compare the time taken by the Band
version, by MrW's version and Rojo's version for varying sizes:
{
Table[{i, Do[th[i], {100}] // AbsoluteTiming // First}, {i, 100,
5000, 200}],
Table[{i, Do[banded[i], {100}] // AbsoluteTiming // First}, {i, 100,
5000, 200}],
Table[{i, Do[banded2[i], {100}] // AbsoluteTiming // First}, {i, 100,
5000, 200}]
} // ListLogPlot[#, AxesLabel -> {"size", "t"}] &
(the slowest one is mine). Note the logarithmic axis. Evidently, the Band
method falls behind more and more with larger system sizes.
Also, using Band
unpacks:
On["Packing"]
th[3000]; // AbsoluteTiming
banded[3000]; // AbsoluteTiming
This occurs when Band
is used to insert the (packed) bdiag
list into the diagonal.
th[nwells_ /; EvenQ@nwells, theta_] := Module[{size = nwells, bdiag, boffdiag}, boffdiag = SparseArray[{}, size - 2, -0.5]; bdiag = RandomReal[99, size - 1]; SparseArray[{{i_, i_} :> bdiag[[i]]}, size - {1, 1}] + Sum[DiagonalMatrix[boffdiag, i], {i, {-1, 1}}] ]
... hurr hurr :D $\endgroup$