-
Notifications
You must be signed in to change notification settings - Fork 32
Description
This might be too breaking to be feasible, but I think it is worth considering defining tensor(a, b) = kron(b, a) (and in general tensor(args...) = kron(reverse(args)...)), essentially because the definition of kron is (I believe) only natural for row-oriented languages like C and python, and not column-oriented languages like Julia/fortran/MATLAB, and does not interact nicely with reshape, permute, etc in a column-oriented language (as e.g. mentioned here).
I will add that reversing the order like I'm advocating is the convention used in QuantumOptics.jl (see also qojulia/QuantumOptics.jl#177 (comment)).
Let me give some more examples about why it would help. I'll define kron_rev here for clarity, and use kron and kron_rev.
kron_rev(a, b) = kron(b, a)In section 1.1.3 of Watrous's TQI, he defines the vec operator:

then:
N = 5
e(i) = (z = zeros(N); z[i] = 1; z) # quick basis vector
E(i,j) = (z = zeros(N, N); z[i, j] = 1; z)
vec(E(1,2)) == kron(e(1), e(2)) # false
vec(E(1,2)) == kron_rev(e(1), e(2)) # trueThat is, if ⊗ were kron_rev, then this identity holds; if not, it does not. This has a bunch of consequences. For example, we have the identity:

and again we need kron_rev for this to hold:
julia> kron(A₀, A₁) * vec(B) ≈ vec(A₀*B*transpose(A₁))
false
julia> kron_rev(A₀, A₁) * vec(B) ≈ vec(A₀*B*transpose(A₁))
trueThis issue also has this example:
julia> A = rand(2,2); B = rand(2,2);
julia> AB = reshape(kron(A, B), (2,2,2,2));
julia> all(AB[a1,b1,a2,b2] ≈ A[a1,a2] * B[b1,b2] for a1=1:2, a2=1:2, b1=1:2, b2=1:2)
falsewhereas
julia> AB = reshape(kron_rev(A, B), (2,2,2,2));
julia> all(AB[a1,b1,a2,b2] ≈ A[a1,a2] * B[b1,b2] for a1=1:2, a2=1:2, b1=1:2, b2=1:2)
true