10
$\begingroup$

There is Kronecker product but there is no Kronecker sum? It seems like a very important features to include.

So in the absence of a Kronecker sum function, how can I construct my own Kronecker sum $A\oplus B$ of two arbitrary $n\times n$ matrices $A$ and $B$?

Thanks very much!

$\endgroup$
  • 1
    $\begingroup$ Your question seems ambiguous. The matrix direct sum and the Kronecker sum are two different things. Which one do you want? $\endgroup$ – MarcoB Apr 25 '18 at 17:44
  • $\begingroup$ @MarcoB you're absolutely right, I mean the Kronecker sum $\endgroup$ – Turbotanten Apr 25 '18 at 17:52
  • $\begingroup$ Thank you for clarifying. You got both answers at this point anyway :-) , but it may still be best to clear that up in the text of the question. $\endgroup$ – MarcoB Apr 25 '18 at 17:54
  • $\begingroup$ @MarcoB That's great because I actually needed both. $\endgroup$ – Turbotanten Apr 25 '18 at 17:57
  • $\begingroup$ See also Henrik's answer here. I didn't realize I was trying to get the Kronecker sum, but he wrote an amazing compiled implementation for sparse matrices. $\endgroup$ – b3m2a1 Jul 27 '18 at 21:32
10
$\begingroup$

Using the Wikipedia definition of Kronecker sum, it seems that we can define it in terms of the Kronecker products, which is built in:

Clear[kroneckersum]
kroneckersum[a_, b_ /; Dimensions[a] == Dimensions[b]] :=
 KroneckerProduct[a, IdentityMatrix[Length[a]]] + 
  KroneckerProduct[IdentityMatrix[Length[b]], b]

a = RandomInteger[{0, 10}, {5, 5}]
b = RandomInteger[{0, 10}, {5, 5}]

kroneckersum[a, b]

An alternative implementation that has the significant advantage of retaining the use of SparseArrays for large matrices was proposed by Henrik in comments:

kroneckersum[a_?SquareMatrixQ, b_?SquareMatrixQ] :=
 KroneckerProduct[a, IdentityMatrix[Length[b], SparseArray]] +
  KroneckerProduct[IdentityMatrix[Length[a], SparseArray], b]

This also reminded me of SquareMatrixQ, a convenient bit of syntactic sugar which I'd seen used before, but keep forgetting.

$\endgroup$
  • $\begingroup$ I think there is no reason for checking dimensions if you use kroneckersum[a_?SquareMatrixQ, b_?SquareMatrixQ] := KroneckerProduct[a, IdentityMatrix[Length[b], SparseArray]] + KroneckerProduct[IdentityMatrix[Length[a], SparseArray], b] . Due to using SparseArrays, this works also for larger matrices (e.g., I tested a = RandomInteger[{0, 10}, {250, 250}]; b = RandomInteger[{0, 10}, {350, 350}];. $\endgroup$ – Henrik Schumacher Apr 25 '18 at 18:21
  • $\begingroup$ @HenrikSchumacher That's very nice! I particularly like the SparseArray part. Would you mind if I added / edited your method in the answer? $\endgroup$ – MarcoB Apr 25 '18 at 20:06
  • $\begingroup$ Of course I don't mind. That was the purpose of my comment. $\endgroup$ – Henrik Schumacher Apr 25 '18 at 20:22
  • $\begingroup$ @HenrikSchumacher Done. Thank you. $\endgroup$ – MarcoB Apr 25 '18 at 20:27
11
$\begingroup$

You could use DiagonalMatrix and ArrayFlatten to define a direct sum:

DirectSum[a_List] := ArrayFlatten @ Block[{Identity}, DiagonalMatrix[Identity/@a]]

For instance:

DirectSum[{
    {{a,b,c},{d,e,f}},
    {{g,h},{i,j},{k,l}}
}] //TeXForm

$\left( \begin{array}{ccccc} a & b & c & 0 & 0 \\ d & e & f & 0 & 0 \\ 0 & 0 & 0 & g & h \\ 0 & 0 & 0 & i & j \\ 0 & 0 & 0 & k & l \\ \end{array} \right)$

See @MarcoB's answer if you wanted the Kronecker sum.

$\endgroup$
8
$\begingroup$

From the docs for KroneckerProduct:

KroneckerSum[a_, b_] /; MatrixQ[a] && MatrixQ[b] :=
  Catch@Module[{n, p, m, q},
    {n, p} = Dimensions[a]; {m, q} = Dimensions[b];
    If[n != p || m != q, Throw[$Failed]];
    KroneckerProduct[a, IdentityMatrix[m]] +
     KroneckerProduct[IdentityMatrix[n], b]
    ];
$\endgroup$

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.