A better way to make a tridiagonal?

4 views (last 30 days)
I'm currently generating a ton of square tridiagonal matrices using
matrix = full(gallery('tridiag',nn,D,1-2*D,D))
I definitely need it in my program but its using about 60% of my computation time. Any advice on a more efficient way for this?

Accepted Answer

Guillaume
Guillaume on 16 Apr 2018
You can look at the code of gallery and if you do you'll find out that it calls tridiag in its private folder. What tridiag ends up doing in your case is:
matrix = full(spdiag([ [ones(nn-1, 1)*D; 0], ones(nn, 1)*(1-2*D), [0; ones(nn-1)*D] ], -1:1, nn, nn))
You could do the above directly to avoid the argument checking that gallery does but I doubt you'll see a meaningfull speed increase.
Other options:
  • call diag:
matrix = diag(repmat(D, nn-1, 1), -1) + diag(repmat(1-2*D, nn, 1)) + diag(repmat(D, nn-1, 1);
This avoids going through a sparse matrix. No idea if it's any faster
  • If nn is fixed you could precompute the diagonal indices and use these to fill the matrix:
%precompute:
subdiagidx = 2:nn+1:nn^2;
diagidx = 1:nn+1:nn^2;
superdiagidx = nn+1:nn+1:nn^2;
subsuperidx = [subdiagidx, superdiagidx];
%gemeration
matrix = zeros(nn);
matrix(subsuperidx) = D;
matrix(diagidx) = 1-2*D;
  1 Comment
Andrew Thomas
Andrew Thomas on 16 Apr 2018
Thank you! nn was fixed so I went with the last option. Works a whole lot quicker now.

Sign in to comment.

More Answers (0)

Categories

Find more on Time-Frequency Analysis in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!