11
$\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$
5
  • 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
    Commented Apr 25, 2018 at 17:44
  • $\begingroup$ @MarcoB you're absolutely right, I mean the Kronecker sum $\endgroup$ Commented Apr 25, 2018 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
    Commented Apr 25, 2018 at 17:54
  • $\begingroup$ @MarcoB That's great because I actually needed both. $\endgroup$ Commented Apr 25, 2018 at 17:57
  • 1
    $\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
    Commented Jul 27, 2018 at 21:32

3 Answers 3

13
$\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$
4
  • $\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$ Commented Apr 25, 2018 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
    Commented Apr 25, 2018 at 20:06
  • $\begingroup$ Of course I don't mind. That was the purpose of my comment. $\endgroup$ Commented Apr 25, 2018 at 20:22
  • $\begingroup$ @HenrikSchumacher Done. Thank you. $\endgroup$
    – MarcoB
    Commented Apr 25, 2018 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 and acknowledge you have read our privacy policy.

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