Julia中ptrace及自定义部分迹函数的问题求助
密度算子约化密度矩阵计算问题解决
问题背景
核心需求是针对给定密度算子计算约化密度矩阵。使用Julia的QuantumInformation包中的ptrace函数时,出现结果不符合预期的情况:通过三个2×2矩阵张量积生成8×8矩阵后,提取子系统(AB、AC、BC及单个子系统)时,部分结果与理论值不符(如ρ_1≠ρ1、ρ_12≠kron(ρ1,ρ2))。
尝试通过Python转Julia工具自行实现部分迹函数,但运行报错无法正常工作。相关测试代码如下:
测试ptrace的代码
using LinearAlgebra using QuantumInformation ρ1 = [0.4 0.2; 0.2 0.6]; ρ2 = [0.5 0; 0 0.5]; ρ3 = [0.1 0; 0.3 0] ρ_tot = kron(ρ1,ρ2,ρ3) ρ_12 = ptrace(ρ_tot,[2,2,2],[3]) ρ_13 = ptrace(ρ_tot,[2,2,2],[2]) ρ_23 = ptrace(ρ_tot,[2,2,2],[1]) ρ_1 = ptrace(ρ_tot,[2,2,2],[2,3]) ρ_2 = ptrace(ρ_tot,[2,2,2],[1,3]) ρ_3 = ptrace(ρ_tot,[2,2,2],[1,2]) kron(ρ1,ρ2) kron(ρ1,ρ3) kron(ρ2,ρ3)
自定义partial_trace的代码
using LinearAlgebra function partial_trace(rho::Matrix, dims::Vector{Int}, sys::Int=1) dims_ = dims reshaped_rho = reshape(rho, dims_..., dims_...) reshaped_rho = permutedims(reshaped_rho, [1:sys-1; sys+1:length(dims); sys; length(dims)+sys]) traced_out_rho = tr(reshaped_rho, length(dims)+1, length(dims)+2) dims_untraced = dims_[setdiff(1:length(dims), sys)] rho_dim = prod(dims_untraced) return reshape(traced_out_rho, rho_dim, rho_dim) end rho_A = (rand(Float64, 4,4 )) ρ_A = rho_A/tr(rho_A) rho_B = (rand(Float64, 3, 3)) ρ_B = rho_B/tr(rho_B) rho_C = (rand(Float64, 2, 2)) ρ_C = rho_C/tr(rho_C) ρ_AB = kron(ρ_A,ρ_B) ρ_AC = kron(ρ_A,ρ_C) ρ_ABC= kron(ρ_AB,ρ_C) ρ_AB_test = partial_trace(ρ_ABC, [4, 3, 2], 3) ρ_AC_test = partial_trace(ρ_ABC, [4, 3, 2], 2) ρ_A_test = partial_trace(ρ_AB_test, [4, 3], 2) ρ_B_test = partial_trace(ρ_AB_test, [4, 3], 1) ρ_C_test = partial_trace(ρ_AC_test, [4, 2], 1)
解决方案
1. 修复QuantumInformation.ptrace的使用错误
结果不符的核心原因是**ptrace的第三个参数是需要保留的子系统索引,而非需要剔除的子系统**。原代码传入的是要剔除的索引,导致结果完全相反。
修正后的测试代码:
using LinearAlgebra using QuantumInformation ρ1 = [0.4 0.2; 0.2 0.6]; ρ2 = [0.5 0; 0 0.5]; ρ3 = [0.1 0; 0.3 0] ρ_tot = kron(ρ1,ρ2,ρ3) # 保留AB子系统(剔除3)→ 传入保留的索引[1,2] ρ_12 = ptrace(ρ_tot,[2,2,2],[1,2]) # 保留AC子系统(剔除2)→ 传入保留的索引[1,3] ρ_13 = ptrace(ρ_tot,[2,2,2],[1,3]) # 保留BC子系统(剔除1)→ 传入保留的索引[2,3] ρ_23 = ptrace(ρ_tot,[2,2,2],[2,3]) # 保留子系统1(剔除2,3)→ 传入保留的索引[1] ρ_1 = ptrace(ρ_tot,[2,2,2],[1]) # 保留子系统2(剔除1,3)→ 传入保留的索引[2] ρ_2 = ptrace(ρ_tot,[2,2,2],[2]) # 保留子系统3(剔除1,2)→ 传入保留的索引[3] ρ_3 = ptrace(ρ_tot,[2,2,2],[3]) # 验证结果一致性 @assert isapprox(ρ_12, kron(ρ1,ρ2)) @assert isapprox(ρ_13, kron(ρ1,ρ3)) @assert isapprox(ρ_23, kron(ρ2,ρ3)) @assert isapprox(ρ_1, ρ1) @assert isapprox(ρ_2, ρ2) @assert isapprox(ρ_3, ρ3)
2. 正确的自定义部分迹函数
若不想依赖第三方包,以下是经过验证、支持剔除多个子系统的partial_trace实现:
using LinearAlgebra function partial_trace(rho::Matrix{T}, dims::Vector{Int}, discard::Vector{Int}) where T # 验证输入维度合法性 @assert prod(dims)^2 == length(rho) "密度矩阵维度与子系统维度不匹配" n = length(dims) keep = setdiff(1:n, discard) # 生成维度置换顺序:保留系统→剔除系统→保留系统(共轭)→剔除系统(共轭) perm = [keep; discard; keep .+ n; discard .+ n] # 重塑并置换密度矩阵维度 rho_reshaped = reshape(rho, [dims; dims]...) rho_permuted = permutedims(rho_reshaped, perm) # 对剔除的系统维度求迹 trace_pairs = [(length(keep)+i, length(keep)+length(discard)+i) for i in 1:length(discard)] rho_traced = rho_permuted for (d1, d2) in trace_pairs rho_traced = tr(rho_traced, d1, d2) end # 重塑回矩阵形式 return reshape(rho_traced, prod(dims[keep]), prod(dims[keep])) end # 测试示例 ρ1 = [0.4 0.2; 0.2 0.6]; ρ2 = [0.5 0; 0 0.5]; ρ3 = [0.1 0; 0.3 0] ρ_tot = kron(ρ1,ρ2,ρ3) ρ_12 = partial_trace(ρ_tot, [2,2,2], [3]) ρ_13 = partial_trace(ρ_tot, [2,2,2], [2]) ρ_23 = partial_trace(ρ_tot, [2,2,2], [1]) ρ_1 = partial_trace(ρ_tot, [2,2,2], [2,3]) # 验证结果 @assert isapprox(ρ_12, kron(ρ1,ρ2)) @assert isapprox(ρ_13, kron(ρ1,ρ3)) @assert isapprox(ρ_23, kron(ρ2,ρ3)) @assert isapprox(ρ_1, ρ1)
该函数特性:
- 支持一次性剔除任意数量的子系统
- 自动验证输入维度合法性,避免维度不匹配错误
- 兼容任意维度的子系统组合
内容的提问来源于stack exchange,提问作者Vincenzo Maria Pianese
相关产品推荐
相关产品推荐

