Julia空间中张量积空间的快速Fourier变换

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))

现在我使用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(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,然后重塑回阵列的原始形式,对吗?