GTorlai / PastaQ.jl

Package for Simulation, Tomography and Analysis of Quantum Computers
Apache License 2.0
142 stars 23 forks source link

Inner between MPO/MPO and MPO/MPS with more than 2 site indices #180

Closed GTorlai closed 3 years ago

GTorlai commented 3 years ago

Extend the inner function to accommodate MPO and MPS with local tensors having two site indices.

circuit = randomcircuit(3,3);

# get MPS of the vectorized unitary MPO
U = runcircuit(circuit; process = true)
Ψ = PastaQ._UnitaryMPOtoChoiMPS(U)
# get the Choi matrix
Λ = PastaQ.choimatrix(PastaQ.hilbertspace(U), circuit; noise = ("DEP",(p=0.001,)))

# check normalizations
@show abs2(norm(Ψ))
# 8.00000000000002
@show tr(Λ)
# 7.999999999999989 + 4.738936278377485e-16im

@show inner(Ψ,Ψ)
# 8.000000000000018 - 1.421697017934987e-16im

@show inner(Ψ,Λ,Ψ)
# ERROR: ArgumentError: Collection has multiple elements, must contain exactly 1 element
Stacktrace:
#  [1] only(::IndexSet{2,Index{Int64},Tuple{Index{Int64},Index{Int64}}}) at ./iterators.jl:1299
#  [2] siteind(::typeof(only), ::MPS, ::Int64; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /Users/gttorlai/.julia/packages/ITensors/oTskW/src/mps/mps.jl:346
#  [3] siteind at /Users/gttorlai/.julia/packages/ITensors/oTskW/src/mps/mps.jl:342 [inlined]
#  [4] replace_siteinds!(::MPS, ::Array{Index{Int64},1}) at /Users/gttorlai/.julia/packages/ITensors/oTskW/src/mps/mps.jl:367
#  [5] dot(::MPS, ::MPO, ::MPS; make_inds_match::Bool) at /Users/gttorlai/.julia/packages/ITensors/oTskW/src/mps/mpo.jl:186
#  [6] dot at /Users/gttorlai/.julia/packages/ITensors/oTskW/src/mps/mpo.jl:180 [inlined]
#  [7] #inner#587 at /Users/gttorlai/.julia/packages/ITensors/oTskW/src/mps/mpo.jl:197 [inlined]
#  [8] inner(::MPS, ::MPO, ::MPS) at /Users/gttorlai/.julia/packages/ITensors/oTskW/src/mps/mpo.jl:197
#  [9] top-level scope at REPL[177]:1
GTorlai commented 3 years ago

Design for quantum state fidelity:

"""
Quantum state fidelity between two wavefunctions.

F = |⟨ψ|ϕ⟩|²
"""
function fidelity(ψ::MPS, ϕ::MPS)
  log_F̃ = 2.0 * real(loginner(ψ, ϕ))
  log_K = 2.0 * (lognorm(ψ) + lognorm(ϕ))
  fidelity = exp(log_F̃ - log_K)
  return fidelity
end

"""
Quantum state fidelity between an MPS wavefunction and a 
density operator.

F = ⟨ψ|ρ|ψ⟩
"""
function fidelity(ψ::MPS, ρ::MPO)
  log_F̃ = log(abs(inner(ψ, ρ, ψ)))
  log_K = 2 * lognorm(ψ) + log(real(tr(ρ)))
  fidelity = exp(log_F̃ - log_K)
  return fidelity
end

"""
Quantum state fidelity between an MPS wavefunction and a 
LPDO density operator.

F = ⟨ψ|ϱ|ψ⟩=|X†|ψ⟩|²
"""
function fidelity(Ψ::MPS, ϱ::LPDO{MPO})
  proj = bra(ϱ) * Ψ
  return inner(proj,proj)
end

"""
Quantum state fidelity between two MPO density matrices.

F = (tr[√(√A B √A)])² 
"""
fidelity(ρ::MPO, σ::MPO) = fidelity(prod(ρ), prod(σ))

"""
Quantum state fidelity between two LPDO density matrices.

F = (tr[√(√A B √A)])² 
"""
fidelity(ρ::LPDO{MPO}, σ::LPDO{MPO}) = fidelity(MPO(ρ), MPO(σ))

# add this for consistency with `processtomography`
const statefidelity = fidelity
GTorlai commented 3 years ago

Design for quantum process fidelity. The function _choifidelity should be replaced with the inner between a MPS and MPO with two site indices.

"""
1. Quantum process fidelity between two MPO unitary operators.
   F = |⟨⟨A|B⟩⟩|²
2. Quantum process fidelity bewteen a MPO unitary and MPO Choi matrix
   F = ⟨⟨A|B|A⟩⟩
3. Quantum process fidelity bewteen two MPO Choi matrices
   F = (Tr[√(√A B √A)])² 

"""
function processfidelity(A::MPO, B::MPO)
  # check whether a MPO is Choi or not (from number of site indices)
  # 1: unitary   -   unitary
  (!ischoi(A) && !ischoi(B)) && return fidelity(_UnitaryMPOtoChoiMPS(A), _UnitaryMPOtoChoiMPS(B))
  # 2: unitary   -   Choi MPO
  (!ischoi(A) && ischoi(B)) && return _choifidelity(_UnitaryMPOtoChoiMPS(A),B)
  # 2reverse: Choi MPO  -   unitary
  (ischoi(A) && !ischoi(B)) && return _choifidelity(B,_UnitaryMPOtoChoiMPS(A))
  # : Choi MPO - Choi MPO
  return fidelity(A,B)
end

"""
1. Quantum process fidelity between a unitary MPO and a Choi LPDO.
   F = ⟨ψ|ϱ|ψ⟩=|X†|ψ⟩|²
2. Quantum process fidelity bewteen a Choi MPO and a Choi LPDO
"""
function processfidelity(A::MPO, Λ::LPDO{MPO})
  #1: Choi MPO   -  Choi LPDO
  (!ischoi(A)) && fidelity(_UnitaryMPOtoChoiMPS(A),Λ)#processfidelity(A, MPO(L))
  return fidelity(A, MPO(Λ))
end
processfidelity(Λ::LPDO, A::MPO) = processfidelity(Λ, L)

"""
Quantum process fidelity between two LPDO Choi matrices
"""
processfidelity(A::LPDO{MPO}, B::LPDO{MPO}) = fidelity(MPO(A), MPO(B))