Code covered by the BSD License

### Highlights from (Block) tri-diagonal matrices

5.0
5.0 | 16 ratings Rate this file 35 Downloads (last 30 days) File Size: 42.2 KB File ID: #10603 Version: 1.0

# (Block) tri-diagonal matrices

### John D'Errico (view profile)

01 Apr 2006 (Updated )

Generate (block) tridiagonal matrices

File Information
Description

Every once in a while I need to generate a tridiagonal matrix with replicated elements down the diagonals. Sometimes its nice to generate block tridiagonal matrices of the same form.

full(blktridiag(2,-1,-1,5))
ans =
2 -1 0 0 0
-1 2 -1 0 0
0 -1 2 -1 0
0 0 -1 2 -1
0 0 0 -1 2

full(blktridiag(ones(2),2*ones(2),3*ones(2),3))
ans =
1 1 3 3 0 0
1 1 3 3 0 0
2 2 1 1 3 3
2 2 1 1 3 3
0 0 2 2 1 1
0 0 2 2 1 1

This can of course be easily extended to handle general blocks, so since I saw an interest from a user, this release does that too.

Amd = reshape(1:16,[2,2,4]);
Asub = reshape(101:112,[2,2,3]);
Asup = reshape(201:212,[2,2,3]);
A = blktridiag(Amd,Asub,Asup);

full(A)
ans =
1 3 201 203 0 0 0 0
2 4 202 204 0 0 0 0
101 103 5 7 205 207 0 0
102 104 6 8 206 208 0 0
0 0 105 107 9 11 209 211
0 0 106 108 10 12 210 212
0 0 0 0 109 111 13 15
0 0 0 0 110 112 14 16

I've also seen a request to allow non-square blocks. This too is now accommodated in the latest release.

A = blktridiag([1;2],[3;4],[5;6],4);
full(A)
ans =
1 5 0 0
2 6 0 0
3 1 5 0
4 2 6 0
0 3 1 5
0 4 2 6
0 0 3 1
0 0 4 2

MATLAB release MATLAB 7.0.1 (R14SP1)
Other requirements I've intentionally kept this code accessible to earlier releases of matlab.
04 Jun 2016 Shumao Zhang

### Shumao Zhang (view profile)

Absolutely useful, especially when solving elliptical PDEs.

19 Feb 2015 Josef

### Josef (view profile)

Good one! Only thing to add would be the possibility to just pass [] for super/sub diagonal instead of zeros, if one only wants the sub/super diagonal, resp.

25 Apr 2014 YIXIN LI

### YIXIN LI (view profile)

awesome

07 Jun 2012 Jean-Philippe

### Jean-Philippe (view profile)

Thank you, it worked nicely.

07 Jun 2012 John D'Errico

### John D'Errico (view profile)

Sorry. It was not written to accept a cell array of sparse matrices. It does work if you pass in a single element that is intended to be replicated down the diagonals. So this works of course:

A = sparse([1 0;0 4]);
bigA = blktridiag(A,A,A',10);

And blktridiag would work if MATLAB supported 3-d sparse arrays.

blkdiag works for you because you can pass in a comma separated list of elements. So an easy fix is for you to use blkdiag to build the main diagonal. Then use blkdiag to build the sub and super diagonal arrays. Shift them over as necessary by padding with zeros, and then just add the three arrays together. No problem.

Comment only
07 Jun 2012 Jean-Philippe

### Jean-Philippe (view profile)

Hi, would it be possible to use blktridiag with cell arrays of sparse matrices? I have a 3d volume (nxmxp) and I must create a tridiagonal matrice of size (nxmxp)x(nxmxp) where the matrices (nxm)x(nxm) for all the slices p of the volume are on the main diagonal. The sub and sup diagonals are matrices also of size (nxm)x(nxm) representing the relationship between neighboring slices.

W11 W12 [ ] [ ]
W21 W22 W23 [ ]
[ ] W32 W33 W34
[ ] [ ] W43 W44

Where W21 is the same as W12' (transpose).

Since Matlab doesn't support 3d sparse matrices, I thought I could use a cell array. The function blkdiag from Matlab works with my cell array, but I am missing the sub and sup diagonals.

Thanks you!

07 Feb 2012 D.Chehov

### D.Chehov (view profile)

03 Feb 2012 Silvia Sasheva

### Silvia Sasheva (view profile)

Hello, John,
I did it in other way. I defined Amdb (A main diag. boundary blocks) in your code and then applied this:
s=repmat(Amdb(:),1,1);
v=[s;repmat(Amd(:),n-2,1);s];
It works and now I will try to go further with the solution of the examined problem. Thank you and regards!

Comment only
01 Feb 2012 Silvia Sasheva

### Silvia Sasheva (view profile)

Thank you for the quick and complete answer. Unfortunately, I'm not familiar with a "repmat" and how to replicate only the middle blocks and replace the first and the last one.
I tried this:
v = repmat(AmdF(1),n,1);
v = repmat(Amd(:),n,1);
v = repmat(AmdL(n),n,1);
but of course it doesn't work....
Have you got a clue how to call it?
Thank you in advance and appreciation again for the code!!!

01 Feb 2012 John D'Errico

### John D'Errico (view profile)

Of course it is possible, since you can supply the individual blocks along the main diagonal. Since the diagonal blocks can be supplied as a pxqxn array in Amd, use repmat to replicate the middle blocks, then replace the first and last blocks in Amd as you wish. Then its just a call to blktridiag.

Comment only
01 Feb 2012 Silvia Sasheva

### Silvia Sasheva (view profile)

Hello,
can please help me to find out if it's possible, using "blktridiag", to generate a block tridiagonal matrix A, whose main diagonal (Amd) to starts and ends with different copies of Amd. I.e. AmdFirst and AmdLast~= Amd...
example:
[AmdF Asup 0 0 0;
Asub Amd Asup 0 0;
0 Asub Amd Asup 0;
0 0 Asub Amd Asup;
0 0 0 Asub AmdL]

I hope that the explanation was clear enought! Thank you in advance!
Regards

Comment only
19 Jan 2012 John D'Errico

### John D'Errico (view profile)

It means you have not placed the function in a directory on your search path. Do NOT put it in the matlab toolbox directories, but in some other directory that you should reserve for your own functions. Then make sure that directory is on the search path. Use the functions addpath, savepath and pathtool to set up your search path.

Comment only
19 Jan 2012 Silvia Sasheva

### Silvia Sasheva (view profile)

Hello, can you help with this error:??? Undefined function or method 'blktridiag' for input arguments of type
'double'.
Probably, it is a stupid question, but I really need help! Thank you in advance!
Best Regards!

Comment only
19 Jul 2011 Bert Xer

### Bert Xer (view profile)

Nice work! Thanks so much!

14 Jan 2008 Jun Seo

Good example for making a sparse matrix.

14 Dec 2007 Antoine Tambue
13 Dec 2007 Antoine Tambue

Many thank for the function, it work very well for square blocks.
Can you have any idea for tridiagonal matrix with not square blocks?
One again many thanks
Antoine

13 May 2007 Tim Davis

Great example of the best way to create a sparse matrix. Nice demo (including a demo is very important in a usable submission).

One minor comment: your submission as of May 11 includes ".DS_Store" files in each folder, which only tell a Mac how to size the window when viewing the folders. Those files are visible to the Windows and Unix/Linux users. They can be deleted.

Very useful code....
Could you please show us the code for the extension too? Thanks in advance.

13 Jun 2006 Miguel de Vega

Wonderful code, and very useful. Thanks John

11 Apr 2006 hicham laanaya

Thank you John.

03 Apr 2006 Kong Zuor

Nice work John. Very usefull indeed. This is a very useful code, especially CFD.

03 Oct 2006

Added the ability to handle general, distinct blocks, also added demos and a screenshot.

03 Oct 2006

Added test subdirectory for Select nom

11 Oct 2006

Cleaned up the code a bit, removed replicated code blocks and a spare call to ndgrid. Also special cased scalar tridiagonals using spdiags. (Thanks to Jos for pointing these items out.)

14 May 2007

Update to remove the .DS_Store files in the zip file. (My thanks to Tim, and of course, to the gipper.)