Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# News

## v1.0.0

- First release, implementing necessary changes to be compatible with the breaking release of `QuantumInterface` 0.4.0.

4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "QuantumOpticsBase"
uuid = "4f57444f-1401-5e15-980d-4471b28d5678"
version = "0.5.5"
version = "1.0.0"

[deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
Expand All @@ -25,7 +25,7 @@ FastGaussQuadrature = "0.5, 1"
FillArrays = "0.13, 1"
LRUCache = "1"
LinearAlgebra = "1"
QuantumInterface = "0.3.3"
QuantumInterface = "0.4.0"
Random = "1"
RecursiveArrayTools = "3"
SparseArrays = "1"
Expand Down
8 changes: 2 additions & 6 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ QuantumOpticsBase.check_samebases
```

```@docs
@samebases
@compatiblebases
```

```@docs
Expand Down Expand Up @@ -598,10 +598,6 @@ passive_state

## [Pauli](@id API: Pauli)

```@docs
PauliBasis
```

```@docs
PauliTransferMatrix
```
Expand Down Expand Up @@ -640,4 +636,4 @@ lazytensor_cachesize

```@docs
lazytensor_clear_cache
```
```
27 changes: 15 additions & 12 deletions src/QuantumOpticsBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ using SparseArrays, LinearAlgebra, LRUCache, Strided, UnsafeArrays, FillArrays
import LinearAlgebra: mul!, rmul!
import RecursiveArrayTools

import QuantumInterface: dagger, directsum, ⊕, dm, embed, nsubsystems, expect, identityoperator, identitysuperoperator,
permutesystems, projector, ptrace, reduced, tensor, ⊗, variance, apply!, basis, AbstractSuperOperator
import QuantumInterface: Basis, GenericBasis, CompositeBasis, basis, basis_l, basis_r,
IncompatibleBases, @compatiblebases, samebases, check_samebases,
addible, check_addible, multiplicable, check_multiplicable, reduced, ptrace, permutesystems,
dagger, directsum, ⊕, dm, embed, nsubsystems, expect, identityoperator, identitysuperoperator,
permutesystems, projector, ptrace, reduced, tensor, ⊗, variance, apply!,
vec, unvec, super, choi, kraus, stinespring, pauli, chi, spre, spost, sprepost, liouvillian

# index helpers
import QuantumInterface: complement, remove, shiftremove, reducedindices!, check_indices, check_sortedindices, check_embed_indices

export Basis, GenericBasis, CompositeBasis, basis,
tensor, ⊗, permutesystems, @samebases,
export Basis, GenericBasis, CompositeBasis, basis, basis_l, basis_r,
tensor, ⊗, permutesystems, @compatiblebases,
#states
StateVector, Bra, Ket, basisstate, sparsebasisstate, norm,
dagger, normalize, normalize!,
Expand All @@ -35,9 +39,10 @@ export Basis, GenericBasis, CompositeBasis, basis,
AbstractTimeDependentOperator, TimeDependentSum, set_time!,
current_time, time_shift, time_stretch, time_restrict, static_operator,
#superoperators
SuperOperator, DenseSuperOperator, DenseSuperOpType,
SparseSuperOperator, SparseSuperOpType, spre, spost, sprepost, liouvillian,
identitysuperoperator,
KetBraBasis, ChoiBasis, PauliBasis,
vec, unvec, super, choi, kraus, stinespring, pauli, chi,
spre, spost, sprepost, liouvillian, identitysuperoperator,
SuperOperatorType, DenseSuperOpType, SparseSuperOpType,
#fock
FockBasis, number, destroy, create,
fockstate, coherentstate, coherentstate!,
Expand All @@ -55,7 +60,7 @@ export Basis, GenericBasis, CompositeBasis, basis,
PositionBasis, MomentumBasis, samplepoints, spacing, gaussianstate,
position, momentum, potentialoperator, transform,
#nlevel
NLevelBasis, transition, nlevelstate,
NLevelBasis, transition, nlevelstate, paulix, pauliz, pauliy,
#manybody
ManyBodyBasis, FermionBitstring, fermionstates, bosonstates,
manybodyoperator, onebodyexpect,
Expand All @@ -64,14 +69,12 @@ export Basis, GenericBasis, CompositeBasis, basis,
tracedistance, tracedistance_h, tracedistance_nh,
entropy_vn, entropy_renyi, fidelity, ptranspose, PPT,
negativity, logarithmic_negativity, entanglement_entropy,
PauliBasis, PauliTransferMatrix, DensePauliTransferMatrix,
ChiMatrix, DenseChiMatrix, avg_gate_fidelity,
avg_gate_fidelity,
SumBasis, directsum, ⊕, LazyDirectSum, getblock, setblock!,
qfunc, wigner, coherentspinstate, qfuncsu2, wignersu2
#apply
apply!

include("bases.jl")
include("states.jl")
include("operators.jl")
include("operators_dense.jl")
Expand All @@ -92,7 +95,7 @@ include("particle.jl")
include("nlevel.jl")
include("manybody.jl")
include("transformations.jl")
include("pauli.jl")
#include("pauli.jl")
include("metrics.jl")
include("spinors.jl")
include("phasespace.jl")
Expand Down
4 changes: 2 additions & 2 deletions src/apply.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ function apply!(state::Operator, indices, operation::Operator)
state
end

function apply!(state::Ket, indices, operation::T) where {T<:AbstractSuperOperator}
function apply!(state::Ket, indices, operation::T) where {T<:SuperOperatorType}
apply!(dm(state), indices, operation)
end

function apply!(state::Operator, indices, operation::T) where {T<:AbstractSuperOperator}
function apply!(state::Operator, indices, operation::T) where {T<:SuperOperatorType}
if is_apply_shortcircuit(state, indices, operation)
state.data = (operation*state).data
return state
Expand Down
3 changes: 0 additions & 3 deletions src/bases.jl

This file was deleted.

2 changes: 2 additions & 0 deletions src/charge.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct ChargeBasis{T} <: Basis
end

Base.:(==)(b1::ChargeBasis, b2::ChargeBasis) = (b1.ncut == b2.ncut)
Base.length(b::ChargeBasis) = b.dim

"""
ShiftedChargeBasis(nmin, nmax) <: Basis
Expand All @@ -50,6 +51,7 @@ end

Base.:(==)(b1::ShiftedChargeBasis, b2::ShiftedChargeBasis) =
(b1.nmin == b2.nmin && b1.nmax == b2.nmax)
Base.length(b::ShiftedChargeBasis) = b.dim

"""
chargestate([T=ComplexF64,] b::ChargeBasis, n)
Expand Down
6 changes: 4 additions & 2 deletions src/manybody.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ end
ManyBodyBasis(onebodybasis::B, occupations::O) where {B,O} = ManyBodyBasis{B,O}(onebodybasis, occupations)
ManyBodyBasis(onebodybasis::B, occupations::Vector{T}) where {B,T} = ManyBodyBasis(onebodybasis, SortedVector(occupations))

==(b1::ManyBodyBasis, b2::ManyBodyBasis) = b1.occupations_hash == b2.occupations_hash && b1.onebodybasis == b2.onebodybasis
Base.length(b::ManyBodyBasis) = length(b.occupations)


allocate_buffer(occ) = similar(occ)
allocate_buffer(mb::ManyBodyBasis) = allocate_buffer(first(mb.occupations))

Expand Down Expand Up @@ -89,8 +93,6 @@ bosonstates(T::Type, Nmodes::Int, Nparticles::Vector{Int}) = union((bosonstates(
bosonstates(T::Type, onebodybasis::Basis, Nparticles) = bosonstates(T, length(onebodybasis), Nparticles)
bosonstates(arg1, arg2) = bosonstates(OccupationNumbers{BosonStatistics,Int}, arg1, arg2)

==(b1::ManyBodyBasis, b2::ManyBodyBasis) = b1.occupations_hash == b2.occupations_hash && b1.onebodybasis == b2.onebodybasis

"""
basisstate([T=ComplexF64,] mb::ManyBodyBasis, occupation::Vector)

Expand Down
20 changes: 12 additions & 8 deletions src/metrics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,15 @@ The `indices` argument can be a single integer or a collection of integers.
function ptranspose(rho::DenseOpType{B,B}, indices=1) where B<:CompositeBasis
# adapted from qutip.partial_transpose (https://qutip.org/docs/4.0.2/modules/qutip/partial_transpose.html)
# works as long as QuantumOptics.jl doesn't change the implementation of `tensor`, i.e. tensor(a,b).data = kron(b.data,a.data)
nsys = length(rho.basis_l.shape)
nsys = nsubsystems(basis_l(rho))
mask = ones(Int, nsys)
mask[collect(indices)] .+= 1
pt_dims = reshape(1:2*nsys, (nsys,2)) # indices of the operator viewed as a tensor with 2nsys legs
pt_idx = [[pt_dims[i,mask[i]] for i = 1 : nsys]; [pt_dims[i,3-mask[i]] for i = 1 : nsys] ] # permute the legs on the subsystem of `indices`
# reshape the operator data into a 2nsys-legged tensor and shape it back with the legs permuted
data = reshape(permutedims(reshape(rho.data, Tuple([rho.basis_l.shape; rho.basis_r.shape])), pt_idx), size(rho.data))
data = reshape(permutedims(reshape(rho.data, Tuple([size(basis_l(rho)); size(basis_r(rho))])), pt_idx), size(rho.data))

return DenseOperator(rho.basis_l,data)
return DenseOperator(basis_l(rho),data)

end

Expand Down Expand Up @@ -253,11 +253,14 @@ logarithmic_negativity(rho::DenseOpType{B,B}, index) where B<:CompositeBasis = l
avg_gate_fidelity(x, y)

The average gate fidelity between two superoperators x and y.
"""

"""
function avg_gate_fidelity(x::T, y::T) where T <: Union{PauliTransferMatrix{B, B} where B, SuperOperator{B, B} where B, ChiMatrix{B, B} where B}
dim = 2 ^ length(x.basis_l)
return (tr(transpose(x.data) * y.data) + dim) / (dim^2 + dim)
end
"""

"""
entanglement_entropy(state, partition, [entropy_fun=entropy_vn])
Expand All @@ -276,7 +279,7 @@ function can be provided (for example to compute the entanglement-renyi entropy)
"""
function entanglement_entropy(psi::Ket{B}, partition, entropy_fun=entropy_vn) where B<:CompositeBasis
# check that sites are within the range
@assert all(partition .<= length(psi.basis.bases))
@assert all(partition .<= nsubsystems(psi.basis))

rho = ptrace(psi, partition)
return entropy_fun(rho)
Expand All @@ -285,17 +288,18 @@ end
function entanglement_entropy(rho::DenseOpType{B,B}, partition, args...) where {B<:CompositeBasis}
# check that sites is within the range
hilb = rho.basis_l
all(partition .<= length(hilb.bases)) || throw(ArgumentError("Indices in partition must be within the bounds of the composite basis."))
length(partition) <= length(hilb.bases) || throw(ArgumentError("Partition cannot include the whole system."))
N = nsubsystems(hilb)
all(partition .<= N) || throw(ArgumentError("Indices in partition must be within the bounds of the composite basis."))
length(partition) <= N || throw(ArgumentError("Partition cannot include the whole system."))

# build the doubled hilbert space for the vectorised dm, normalized like a Ket.
b_doubled = hilb^2
rho_vec = normalize!(Ket(b_doubled, vec(rho.data)))

if partition isa Tuple
partition_ = tuple(partition..., (partition.+length(hilb.bases))...)
partition_ = tuple(partition..., (partition.+N)...)
else
partition_ = vcat(partition, partition.+length(hilb.bases))
partition_ = vcat(partition, partition.+N)
end

return entanglement_entropy(rho_vec,partition_,args...)
Expand Down
37 changes: 37 additions & 0 deletions src/nlevel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,40 @@ function nlevelstate(::Type{T}, b::NLevelBasis, n::Integer) where T
basisstate(T, b, n)
end
nlevelstate(b::NLevelBasis, n::Integer) = nlevelstate(ComplexF64, b, n)

"""
paulix([T=ComplexF64,] b::NLevelBasis, pow=1)

Generalized Pauli X operator for the given N level system.
Returns `X^pow`.
"""
function paulix(::Type{T}, b::NLevelBasis, pow=1) where T
N = length(b)
SparseOperator(b, spdiagm(pow => fill(one(T), N-pow),
pow-N => fill(one(T), pow)))
end
paulix(b::NLevelBasis, pow=1) = paulix(ComplexF64, b, pow)

"""
pauliz([T=ComplexF64,] b::NLevelBasis, pow=1)

Generalized Pauli Z operator for the given N level system.
Returns `Z^pow`.
"""
function pauliz(::Type{T}, b::NLevelBasis, pow=1) where T
N = length(b)
ω = exp(2π*1im*pow/N)
SparseOperator(b, spdiagm(0 => T[ω^n for n=1:N]))
end
pauliz(b::NLevelBasis, pow=1) = pauliz(ComplexF64, b, pow)

"""
pauliy([T=ComplexF64,] b::NLevelBasis)

Pauli Y operator. Only defined for a two level system.
"""
function pauliy(::Type{T}, b::NLevelBasis) where T
length(b) == 2 || throw(ArgumentError("pauliy only defined for two level system"))
SparseOperator(b, spdiagm(-1 => T[-1im], 1 => T[1im]))
end
pauliy(b::NLevelBasis) = pauliy(ComplexF64,b)
Loading
Loading