Julia空间中张量积空间的快速Fourier变换
现在我使用FFTW包来获得一些我感兴趣的傅里叶变换。然而,我想知道是否已经有一个FFT包可以在向量空间中进行变换,该向量空间的形式为Julia空间中张量积空间的快速Fourier变换,julia,fft,physics,Julia,Fft,Physics,现在我使用FFTW包来获得一些我感兴趣的傅里叶变换。然而,我想知道是否已经有一个FFT包可以在向量空间中进行变换,该向量空间的形式为kron(C2,Rn),其中C2表示2x2系统,Rn表示有兴趣获得傅里叶变换的“空间”子空间。换句话说,是否存在实现以下功能的例程: kron(Id2x2, FFT)[kron(C2, Rn)] = kron(C2, FFT(Rn)) 当然,我感兴趣的真正问题是“两粒子情况”,其中向量空间(希尔伯特空间)是kron(kron(C2,Rn),kron(C2,Rn))
kron(C2,Rn)
,其中C2
表示2x2系统,Rn
表示有兴趣获得傅里叶变换的“空间”子空间。换句话说,是否存在实现以下功能的例程:
kron(Id2x2, FFT)[kron(C2, Rn)] = kron(C2, FFT(Rn))
当然,我感兴趣的真正问题是“两粒子情况”,其中向量空间(希尔伯特空间)是kron(kron(C2,Rn),kron(C2,Rn))
,因此在这种情况下,例程需要kron(kron(Id2x2,FFT),kron(Id2x2,FFT))
注1:我没有试图解决部分跟踪的问题,但在我的情况下,这个选项可能根本不起作用,因为状态是稀疏的,也就是说,它可能是无效的
注2:注意(除非我错了)对于
kron(C2,Rn)
一个人可以做“两次”fft(在C2
的每个扇区中一次)。然而,对于大型向量空间,这也可能是无效的。这里有一个例子,我想你是在问这个问题res
是通过FFT从mat=kron(C2,Rn)
计算出来的,这是(正如您所说)一种浪费的方法,因为它沿着k
维度的FFT是针对其他2×2维度中的每个维度重新进行的。但问题大概是,对乘积空间中的“纠缠”态——一般的likemat=rand(8,2)
不能分解为因子kron(likeC2,likeRn)
(相反,如果你真的只对“无纠缠”的产品状态感兴趣,那么你可能只需要处理它们的组件。与kron
组合将永远是浪费。Kronecker.jl包在某些方面可能会有所帮助,但我认为它不知道fft
)
这使用我的包来处理kron
类操作;你也可以写下必要的重塑自己
julia> C2 = [1 2; 3 4]; Rn = [1,10,0,0];
julia> mat = kron(C2,Rn)
8×2 Matrix{Int64}:
1 2
10 20
0 0
0 0
3 4
30 40
0 0
0 0
julia> using TensorCast, FFTW
# notation: kron is a reshape of a tensor product, to combine i & k
julia> kron(C2,Rn) == @cast out[(k,i),j] := C2[i,j] * Rn[k]
true
# reshape mat to put the index from Rn in its own dimension:
julia> @cast tri[k,i,j] := mat[(k,i),j] (i in 1:2);
julia> summary(tri)
"4×2×2 Array{Int64, 3}"
# then fft(tri, 1) is the FFT along only that, reshape back:
julia> @cast res[(ktil,i),j] := fft(tri, 1)[ktil,i,j]
8×2 Matrix{ComplexF64}:
11.0+0.0im 22.0+0.0im
1.0-10.0im 2.0-20.0im
-9.0+0.0im -18.0+0.0im
1.0+10.0im 2.0+20.0im
33.0+0.0im 44.0+0.0im
3.0-30.0im 4.0-40.0im
-27.0+0.0im -36.0+0.0im
3.0+30.0im 4.0+40.0im
julia> res ≈ kron(C2, fft(Rn))
true
julia> res ≈ fft(mat, 1)
false
julia> fft(Rn)
4-element Vector{ComplexF64}:
11.0 + 0.0im
1.0 - 10.0im
-9.0 + 0.0im
1.0 + 10.0im
# if fft() understood the dims keyword, it could be tidier:
julia> _fft(x; dims) = fft(x, dims);
julia> @cast _res[(k,i),j] := _fft(k) mat[(k,i),j] (i in 1:2);
julia> _res ≈ res
true
这就是我所认为的,人们总是需要重塑阵列以得到一个“矩阵”,进行fft,然后重塑回阵列的原始形式,对吗?