8
$\begingroup$

I want to define the Kronecker product of quaternionic matrices. I want to follow the idea of this answer of passing the NonCommutativeMultiply to the matrix product

times[q1_, q2_] := Inner[NonCommutativeMultiply, q1, q2, Plus]

As the standard KroneckerProduct does not allow to change the definition of its matrix multiplication I am attempting something like

Outer[NonCommutativeMultiply, q1, q2] // ArrayFlatten[#, 2] &

But this does not work as hoped.

$\endgroup$
1
  • $\begingroup$ For future reference, please show the actual vs. desired output of your code, rather than saying "didn't work as hoped", so we know exactly what you want to achieve. $\endgroup$
    – MarcoB
    Commented Sep 11, 2022 at 18:24

2 Answers 2

7
$\begingroup$

You could temporarily and locally change the "meaning" of Times to NonCommutativeMultiply just while you run KroneckerProduct:

Block[
 {Times = NonCommutativeMultiply},
 KroneckerProduct[Array[b, {2, 2}], Array[a, {2, 2}]]
]

(* Out:
{{b[1, 1] ** a[1, 1], b[1, 1] ** a[1, 2], b[1, 2] ** a[1, 1], b[1, 2] ** a[1, 2]},
 {b[1, 1] ** a[2, 1], b[1, 1] ** a[2, 2], b[1, 2] ** a[2, 1], b[1, 2] ** a[2, 2]},
 {b[2, 1] ** a[1, 1], b[2, 1] ** a[1, 2], b[2, 2] ** a[1, 1], b[2, 2] ** a[1, 2]},
 {b[2, 1] ** a[2, 1], b[2, 1] ** a[2, 2], b[2, 2] ** a[2, 1], b[2, 2] ** a[2, 2]}}
*)
$\endgroup$
4
  • 1
    $\begingroup$ Nice answer, indeed! $\endgroup$ Commented Sep 11, 2022 at 18:38
  • 1
    $\begingroup$ Why are you inheriting the default definition of Times? After all, you are overriding most things anyway. Also, you are inheriting the Orderless attribute - that shouldn't matter here, since Times is immediately replaced my NonVommutativeMultiply, but I would be a bit worried about the evaluator canonicalizing the expression before replacing the head. $\endgroup$
    – Lukas Lang
    Commented Sep 11, 2022 at 18:53
  • $\begingroup$ Nevermind, it does matter: If you swap a and b, you still get a[...]**b[...] type products with the current answer $\endgroup$
    – Lukas Lang
    Commented Sep 11, 2022 at 18:55
  • 1
    $\begingroup$ @Lukas You have a good point. I went with InheritedBlock out of habit, but Block should actually do fine here, and it's simpler. That also returns b ** a products when swapping a and b. See update $\endgroup$
    – MarcoB
    Commented Sep 11, 2022 at 19:31
5
$\begingroup$

Again, a possible solution is to define a new function.

qkronecker[q1_, q2_] := Outer[NonCommutativeMultiply, q1, q2] // ArrayFlatten

To see if this works, we first try not with quaternions, but with symbols:

am = Array[Subscript[a, #1, #2] &, {2, 2}];
bm = Array[Subscript[b, #1, #2] &, {2, 2}];

qkronecker[am, bm] // MatrixForm

enter image description here

Now with quaternions:

q = {{Quaternion[7, 0, 0, 0], 
    Quaternion[0, 1, 1, 0]}, {Quaternion[0, 0, 1, 7], 
    Quaternion[0, 5, 0, 1]}};

qkronecker[q, q] // MatrixForm

enter image description here

$\endgroup$
1
  • $\begingroup$ I was about posting the same idea... ^^ $\endgroup$ Commented Sep 11, 2022 at 19:46

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.