6
$\begingroup$

I need to represent $M-\lambda\cdot\textrm{Identity}$ where $M$ is an operator on $V_1\oplus\cdots\oplus V_n$ made from $$ V_1\xrightarrow{M_1}V_2\xrightarrow{M_2}\cdots\xrightarrow{M_{n-1}}V_n\xrightarrow{M_n}V_1. $$ With, say, $n=3$, $\dim V_k=k+1$, I am trying

sa = With[{dim = {2, 3, 4}}, With[{n = Length[dim]}, SparseArray[ { Band[{1, 1}] -> Table[λ IdentityMatrix[dim[[k]]], {k, n}], Band[{2, 1}] -> Table[ Table[Indexed[M[k], {i, j}], {i, dim[[k + 1]]}, {j, dim[[k]]}], {k, n - 1} ], Band[{1, n}] -> Table[Indexed[M[n], {i, j}], {i, dim[[1]]}, {j, dim[[n]]}] } ] ] ] 

The result is very strange: both sa//TableForm and ArrayFlatten[sa]//TableForm give

enter image description here

The same happens with Band[{1, n}] -> {Table[...]}.

What am I doing wrong here?

$\endgroup$
10
  • $\begingroup$ Shouldn't the last matrix be placed on Band[{1, Quotient[n (n + 1), 2]}]? $\endgroup$ Commented Jun 5, 2018 at 6:14
  • $\begingroup$ @HenrikSchumacher Tried. Wrong again (in a different way) - among other things, it is not square anymore. Besides, I don't see why should it be placed there... $\endgroup$ Commented Jun 5, 2018 at 6:21
  • $\begingroup$ Then try Band[{1, n (n - 1)/2 + 1}]. The second index of the band of the last matrix should the sum of the dimensions of the others +1 $\endgroup$ Commented Jun 5, 2018 at 6:24
  • $\begingroup$ @HenrikSchumacher Now it gives correct answer. However with, say, dim = {2, 3, 4} it is all wrong again. As for your explanation: it should be an $n\times n$ array of matrices, should not it? $\endgroup$ Commented Jun 5, 2018 at 6:27
  • 1
    $\begingroup$ Ah, this last command actually gave me a hint on what you were thinking how it should work. $\endgroup$ Commented Jun 5, 2018 at 7:18

2 Answers 2

9
$\begingroup$

SparseArray reacts different when lists of matrices appear on the right hand side of Rule for Band. In this case, it assembles the ArrayFlattened block matrix instead of the matrix of blocks and Band[{i,j}] refers to the positions in the final, assembled matrix, not to the position within the matrix of blocks. I have to admit that this is really counterintuitive.

sa[dim_] := With[{n = Length[dim]}, SparseArray[{ Band[{1, 1}] -> λ, Band[{dim[[1]] + 1, 1}] -> Table[Table[ Indexed[M[k], {i, j}], {i, dim[[k + 1]]}, {j, dim[[k]]}], {k, n - 1}], Band[{1, Total[Most[dim]] + 1}] -> Table[Indexed[M[n], {i, j}], {i, dim[[1]]}, {j, dim[[n]]}]}, {Total[dim], Total[dim]} ] ] sa[{2, 3, 4}] 

There is also the undocumented function SparseArray`SparseBlockMatrix in which you can use {i,j}-> ... for the block in the i-row and j-th column. But SparseArray`SparseBlockMatrix does not go well with Band. And it is undocumented, so one has to go mostly by trial and error.

$\endgroup$
3
  • $\begingroup$ Wow. I still don't understand why it should work this way but it works! $\endgroup$ Commented Jun 5, 2018 at 6:52
  • $\begingroup$ Accepted. That seems to be the way it is, so... $\endgroup$ Commented Jun 5, 2018 at 7:08
  • $\begingroup$ I wonder what will happen with a sparse array of sparse arrays! Fortunately I don't need this :) $\endgroup$ Commented Jun 5, 2018 at 7:09
3
$\begingroup$

An alternative way without using Band:

sA = Module[{dim = #, n = Length @ #, l = Array[\[FormalX], Length @ #], lim = λ IdentityMatrix[Total @ #], mats}, mats = Table[Indexed[M[k], {i, j}], {k, n}, {i, dim[[Mod[k + 1, n, 1]]]}, {j, dim[[k]]}]; SparseArray[ArrayFlatten[RotateRight[DiagonalMatrix[l]] /. Thread[l -> mats]] + lim]] &; 

Examples:

MatrixForm @ sA @ {2, 3, 4} 

enter image description here

MatrixForm @ sA @ {2, 3, 4, 3} 

enter image description here

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.