4

Following my previous question I have this issue using TensorExpand:

KroneckerProduct[x, y].(KroneckerProduct[2 z, w]) // TensorExpand

results in:

2KroneckerProduct[x.z, y.w]

as expected. But why doesn't the following:

KroneckerProduct[x, y].(2 KroneckerProduct[z, w]) // TensorExpand

produce the same answer, and how should I get it to work?

Again this is a just a small step in my program, so I'm looking for a neat solution (minimum amount of modifying internal functions...)

It works for x. (2 y) // TensorExpand

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
Milad
  • 147
  • 6
  • I suspect it has to do with the fact that Mathematica doesn't reduce Dot expressions like a.2. I've never been able to resolve an issue of this type without, in this situation, defining an upvalue for Times or a downvalue for KroneckerProduct. – IPoiler Oct 22 '15 at 03:52
  • I see. Could you please elaborate on this? I'm not familiar with upvalue/downvalue. (I just realized that it works for

    x. (2 y) // TensorExpand )

    – Milad Oct 22 '15 at 04:01
  • Sure. Downvalues are the type of definitions you probably already use pretty regularly, = and :=. These definitions are associated with the outermost Head defined to the left of the operator and are checked when that Head is encountered. Upvalues are definitions associated with a Head in a subexpression left of it's operators, ^=, ^:= and /:. For your purposes I'd use define something like KroneckerProduct/:Dot[KroneckerProduct[x__],Times[a_?NumberQ,b_KroneckerProduct]:=a Dot[KroneckerProduct[x],b] to always pull out constant coefficients in the Dot. – IPoiler Oct 22 '15 at 04:13
  • Thanks. I get error using this (even after fixing the missing bracket.) I'll play with it. – Milad Oct 22 '15 at 04:27
  • For whatever reason I am unable to edit my previous comment, but try KroneckerProduct/:Dot[x_KroneckerProduct, Times[a_?NumberQ, b_KroneckerProduct]] := a Dot[x, b]. Don't forget to Unprotect[KroneckerProduct] first. – IPoiler Oct 22 '15 at 04:35
  • Now I see, thanks. Though I hope I can find a way out of this without modifying Kronecker.

    I have several functions defined using Kronecker, and also have expressions like :

    KroneckerProduct[x, y].(2 KroneckerProduct[z, w]).KroneckerProduct[x, y] // TensorExpand or with more products in my calculation.

    – Milad Oct 22 '15 at 17:23
  • KroneckerProduct /: Dot[x___KroneckerProduct, Times[a_?NumberQ, b_KroneckerProduct], y___KroneckerProduct] := a Dot[x, b, y] will work with both your most recent case and the previous one. – IPoiler Oct 22 '15 at 18:36
  • I appreciate it. My worries is that I'm not sure how careful I can use this approach in a large calculation. I have up to 10 Dot, on Kronecker product of 5 symbols. If there is not clean approach maybe I should really go through this approach, BTW, on you comment it doesn't correctly simplify this one : (2 KroneckerProduct[x, y]).(2 KroneckerProduct[3 z, w]).KroneckerProduct[z, w] // TensorExpand – Milad Oct 22 '15 at 19:07
  • Dot[x___, c_?NumberQ*y_, z___] := c Dot[x, y, z]. This time, Unprotect[Dot] since it will be associated with Dot now rather than KroneckerProduct. – IPoiler Oct 22 '15 at 19:23

1 Answers1

1

It looks like TensorExpand acquired support for this kind of expansion in M11.2 or M11.3:

KroneckerProduct[x, y].(2 KroneckerProduct[z, w]) // TensorExpand

2 KroneckerProduct[x.z, y.w]

Carl Woll
  • 130,679
  • 6
  • 243
  • 355