# easiest way to construct the following determinant

What is the easiest way to construct the following determinant?]

p is variable, I want to vary value of p each time and get the appropriate determinant.

One way to do it would be

mat[p_] := SparseArray[{
{i_, i_} :> B[i - 1],
{i_, j_} /; i == j + 1 :> A[j - 1],
{i_, j_} /; i == j - 1 :> CC[j - 1]
},
p + 1
]
Det@mat[p]


For example

With[{p = 2},
SparseArray[{
{i_, i_} :> B[i - 1],
{i_, j_} /; i == j + 1 :> A[j - 1],
{i_, j_} /; i == j - 1 :> CC[j - 1]
},
p + 1
]
]
Det@%


$$\left( \begin{array}{ccc} B(0) & \text{CC}(1) & 0 \\ A(0) & B(1) & \text{CC}(2) \\ 0 & A(1) & B(2) \\ \end{array} \right)$$

B[0] B[1] B[2] - A[0] B[2] CC[1] - A[1] B[0] CC[2]

But the computation time quickly increases with p since the elements are symbolic. For example, with p = 17,

With[{p = 17},
SparseArray[{
{i_, i_} :> B[i - 1],
{i_, j_} /; i == j + 1 :> A[j - 1],
{i_, j_} /; i == j - 1 :> CC[j - 1]
},
p + 1
]
] // Det // RepeatedTiming // First


2.7

But, if the elements are numeric quantities,

SeedRandom[1234]
With[{p = 17},
SparseArray[{
{i_, i_} :> RandomReal[],
{i_, j_} /; i == j + 1 :> RandomReal[],
{i_, j_} /; i == j - 1 :> RandomReal[]
},
p + 1
]
] // Det // RepeatedTiming // First


0.0020

the calculation is no problem.

• thanks a lot. In fact A,B and C are some functions which become determined by initial values. – Wisdom Oct 15 '19 at 6:14

Since you indicate you're interested only in the determinant, a recursive procedure is faster:

ClearAll[det];
det[0] = 1;
det[1] = b[0];
mem : det[p_] := mem = b[p - 1] det[p - 1] - a[p - 2] c[p - 1] det[p - 2];

d1 = det[15]; // AbsoluteTiming
d3 = With[{n = 15},  (* J.M.'s RecurrenceTable[] idea *)
First[RecurrenceTable[{d[p] ==
b[p - 1] d[p - 1] - a[p - 2] c[p - 1] d[p - 2], d[0] == 1,
d[1] == b[0]}, d, {p, n, n}]]]; // AbsoluteTiming
d2 = Det@sa[15]; // AbsoluteTiming (*sa[p] = SparseArray solution (I used @kglr's)*)

d1 - d2 // Simplify
d1 - d3 // Simplify
(*
{0.000188, Null}
{0.000936, Null}
{0.391194, Null}

0
0
*)


The results are memoized, so that if you need to compute the determinant for another value of p, the new result is built on top of any previous computations. As long as storing the results is not a problem (in terms of RAM), it should make things faster.

• You'd think this method would be built into M somewhere, but I can't find it. – Michael E2 Oct 15 '19 at 21:30
• Of course, you can use RecurrenceTable[] for this as well: With[{n = 15}, First[RecurrenceTable[{d[p] == b[p - 1] d[p - 1] - a[p - 2] c[p - 1] d[p - 2], d[0] == 1, d[1] == b[0]}, d, {p, n, n}]]] – J. M.'s ennui Nov 13 '19 at 22:49

An alternative, and faster, way to construct the SparseArray using Band:

sa[n_] := SparseArray[{
Band[{1, 1}] -> Array[b, n, 0],
Band[{2, 1}] -> Array[a, n - 1, 0],
Band[{1, 2}] -> Array[c, n - 1]},
{n, n}]

sa[10] // MatrixForm // TeXForm


$$\left( \begin{array}{cccccccccc} b(0) & c(1) & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ a(0) & b(1) & c(2) & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & a(1) & b(2) & c(3) & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & a(2) & b(3) & c(4) & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & a(3) & b(4) & c(5) & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & a(4) & b(5) & c(6) & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & a(5) & b(6) & c(7) & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & a(6) & b(7) & c(8) & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & a(7) & b(8) & c(9) \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & a(8) & b(9) \\ \end{array} \right)$$

• Originally I thought to use your Band method (from the other very similar question recently), but didn't think to create the element vectors. – NonDairyNeutrino Oct 15 '19 at 21:21