2
$\begingroup$

What is the easiest way to construct the following determinant?enter image description here]

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

$\endgroup$
4
$\begingroup$

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.

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

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
d2 = Det@sa[15]; // AbsoluteTiming (* sa[p] = SparseArray solution (I used @kglr's) *) 
d1 - d2 // Simplify
(*
  {0.000188, Null}
  {0.391194, Null}
  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.

$\endgroup$
  • $\begingroup$ You'd think this method would be built into M somewhere, but I can't find it. $\endgroup$ – Michael E2 Oct 15 at 21:30
3
$\begingroup$

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

$\endgroup$
  • 1
    $\begingroup$ Originally I thought to use your Band method (from the other very similar question recently), but didn't think to create the element vectors. $\endgroup$ – That Gravity Guy Oct 15 at 21:21

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.