Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

What is the best way to construct a large tridiagonal matrix, in the following form (notably with alternating signs)?

$\mathbf M = \begin{pmatrix} 0 & a & 0 & 0 & 0 & \cdots \\ a & 0 & -a & 0 & 0&\cdots \\ 0 & -a & 0 & a & 0 &\cdots \\ 0 & 0 & a & 0 & -a &\cdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \ddots \end{pmatrix}$

I was using code like that shown below to produce constant sign diagonals of $a$ above and below the main diagonal for an $n\times n$ matrix.

DiagonalMatrix[Array[a &, n - 1], -1]


DiagonalMatrix[Array[a &, n - 1], 1] 

Any help is appreciated.

share|improve this question
up vote 11 down vote accepted

Here is a way using Band:

SparseArray[{Band[{1, 2}, {4, 5}] -> {a, -a}, 
          Band[{2, 1}, {5, 4}] -> {a, -a}}, {5, 5}] // MatrixForm

$$\left( \begin{array}{ccccc} 0 & a & 0 & 0 & 0 \\ a & 0 & -a & 0 & 0 \\ 0 & -a & 0 & a & 0 \\ 0 & 0 & a & 0 & -a \\ 0 & 0 & 0 & -a & 0 \\ \end{array} \right)$$

To make it easier to modify the size and the pattern of elements on the off-diagonals, I'd suggest something like this (incorporating J.M.'s suggestion):

With[{n = 7, pattern = {a, -a}},
 SparseArray[{Band[{1, 2}, {-2, -1}] -> pattern, 
   Band[{2, 1}, {-1, -2}] -> pattern}, {n, n}]]

The negative indices are counted from the end, so that we don't need to use the dimension n in the Band specification. The reason I specify the beginning and end of each band is that only in this case will a cyclic repetition of pattern occur, as desired. If the end specification is omitted, pattern will only be used to fill the first few entries of the Band.

share|improve this answer
1  
Very efficient. Elegant. – David G. Stork Feb 18 at 21:10
    
Alternatively, you can use negative indices on the second argument of Band[]: SparseArray[{Band[{1, 2}, {-2, -1}] -> {a, -a}, Band[{2, 1}, {-1, -2}] -> {a, -a}}, {7, 7}]. – J. M. Feb 19 at 3:19
    
@J.M. Thanks, I'll include that - – Jens Feb 19 at 4:02

Here are two alternatives to Jens's procedure.

With Band[]:

With[{n = 7, a = 1}, 
     SparseArray[{Band[{1, 2}] -> #, Band[{2, 1}] -> #}] & @
     PadRight[{}, n - 1, {a, -a}]]

Without Band[]:

With[{n = 7, a = 1}, 
     SparseArray[{{j_, k_} /; Abs[j - k] == 1 && EvenQ[Max[j, k]] -> a,
                  {j_, k_} /; Abs[j - k] == 1 && OddQ[Max[j, k]] -> -a}, {n, n}]]

Both should yield

$$\begin{pmatrix} 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 1 & 0 & -1 & 0 & 0 & 0 & 0 \\ 0 & -1 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & -1 & 0 & 0 \\ 0 & 0 & 0 & -1 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 1 & 0 & -1 \\ 0 & 0 & 0 & 0 & 0 & -1 & 0 \\ \end{pmatrix}$$

share|improve this answer

You can do it with DiagonalMatrix easily as well:

n = 7; 
DiagonalMatrix[-a*(-1)^Range[n - 1], -1] + DiagonalMatrix[-a*(-1)^Range[n - 1], 1]

enter image description here

share|improve this answer

EDIT

fun[n_, a_] := SparseArray[{{i_, j_} /; j == i + 1 :> a (-1)^(i - 1),
   {i_, j_} /; j == i - 1 :> a (-1)^(i)}, {n, n}]

e.g.

Grid[Partition[(fun[#, a] // MatrixForm) & /@ Range[2, 10], 3]]

enter image description here

See comments from J.M. nicer first condition: {i_, j_} /; j == i + 1 :> a (-1)^j

share|improve this answer
1  
You could have done {i_, j_} /; j == i + 1 :> a (-1)^j instead. ;) – J. M. Feb 20 at 10:58
    
@J.M. yes that is neater...should have thought a bit more. Will edit with appropriate attribution :) – ubpdqn Feb 20 at 11:03
    
Oh my, that was only for the superdiagonal; your expression for the subdiagonal was fine as it was. – J. M. Feb 20 at 11:08
    
@J.M. I am not well atm...will correct my blunder...you saved characters based on parity change (j=i+1, has same parity as i-1)...as I said not well.... – ubpdqn Feb 20 at 11:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.