5
$\begingroup$

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.

$\endgroup$
11
$\begingroup$

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.

$\endgroup$
  • 1
    $\begingroup$ Very efficient. Elegant. $\endgroup$ – David G. Stork Feb 18 '16 at 21:10
  • $\begingroup$ 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}]. $\endgroup$ – J. M. will be back soon Feb 19 '16 at 3:19
  • $\begingroup$ @J.M. Thanks, I'll include that - $\endgroup$ – Jens Feb 19 '16 at 4:02
6
$\begingroup$

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}$$

$\endgroup$
5
$\begingroup$

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

$\endgroup$
3
$\begingroup$

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

$\endgroup$
  • 1
    $\begingroup$ You could have done {i_, j_} /; j == i + 1 :> a (-1)^j instead. ;) $\endgroup$ – J. M. will be back soon Feb 20 '16 at 10:58
  • $\begingroup$ @J.M. yes that is neater...should have thought a bit more. Will edit with appropriate attribution :) $\endgroup$ – ubpdqn Feb 20 '16 at 11:03
  • $\begingroup$ Oh my, that was only for the superdiagonal; your expression for the subdiagonal was fine as it was. $\endgroup$ – J. M. will be back soon Feb 20 '16 at 11:08
  • $\begingroup$ @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.... $\endgroup$ – ubpdqn Feb 20 '16 at 11:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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