Skip to content

Commit

Permalink
update (#2)
Browse files Browse the repository at this point in the history
* Fix rounding tolerance bug for entropy_vn

* Update entropy_vn and REQUIRE

* Implement some predefined states (qojulia#215)

* Implement thermal state

* Implement different states

* Fix semiclassical stochastics

commit bc1d96d
Author: david-pl <[email protected]>
Date:   Mon May 28 09:54:48 2018 +0200

    Make default noise in-place

commit cc6c7f0
Author: david-pl <[email protected]>
Date:   Thu May 24 16:57:45 2018 +0200

    Minor changes

commit 986f10a
Author: david-pl <[email protected]>
Date:   Wed May 23 16:58:32 2018 +0200

    Add tests

commit c3c1452
Author: david-pl <[email protected]>
Date:   Wed May 23 11:16:13 2018 +0200

    Update REQUIRE

commit 3f2ff9f
Author: David Plankensteiner <[email protected]>
Date:   Wed May 23 08:52:20 2018 +0200

    Update docstrings

commit ee4d967
Author: david-pl <[email protected]>
Date:   Tue May 22 14:49:39 2018 +0200

    Fix bug for Euler algs with scalar noise

commit 046955d
Author: david-pl <[email protected]>
Date:   Tue May 22 10:35:30 2018 +0200

    Fix alg default value

commit ce310dd
Author: david-pl <[email protected]>
Date:   Tue May 22 10:17:33 2018 +0200

    Change noise_rate_prototype syntax

commit 92f59a6
Author: David Plankensteiner <[email protected]>
Date:   Sat May 19 20:08:30 2018 +0200

    Update stochastic schroedinger

commit a4fdf7d
Author: David Plankensteiner <[email protected]>
Date:   Sat May 19 19:16:45 2018 +0200

    Stochastic semiclassical tests pass

commit 56d2276
Author: david-pl <[email protected]>
Date:   Fri May 18 17:02:28 2018 +0200

    Fix combination of quantum and classical noise in schroedinger

* Fix bug for classical nondiagonal noise

* Change sparse diagonalization and implement conj

commit cadef00
Author: david-pl <[email protected]>
Date:   Tue May 29 16:21:14 2018 +0200

    Make non-hermitian warning inline

commit 732574b
Author: david-pl <[email protected]>
Date:   Tue May 29 15:42:37 2018 +0200

    Add n back to sparse diagonalization

commit af810ff
Author: david-pl <[email protected]>
Date:   Tue May 29 15:30:04 2018 +0200

    Add test

commit 5d3c7ae
Author: david-pl <[email protected]>
Date:   Tue May 29 15:27:34 2018 +0200

    Fix diagonalization and conjugate issues

* Add option to normalize stochastic schroedinger

commit e0a2b50
Author: david-pl <[email protected]>
Date:   Thu Jun 21 13:02:16 2018 +0200

    Make semiclassical normalization more efficient

commit d19673d
Author: david-pl <[email protected]>
Date:   Thu Jun 21 12:05:59 2018 +0200

    Fix schroedinger tests

commit 241243a
Author: david-pl <[email protected]>
Date:   Thu Jun 21 11:48:20 2018 +0200

    Fix semiclassical schroedinger normalization

commit 40ace6b
Author: david-pl <[email protected]>
Date:   Thu Jun 21 09:26:53 2018 +0200

    Update REQUIRE to new StochasticDiffEq

commit d9503a3
Author: david-pl <[email protected]>
Date:   Wed Jun 20 17:23:35 2018 +0200

    Add option to renormalize state in schroedinger

commit e6a7331
Author: david-pl <[email protected]>
Date:   Wed Jun 20 17:23:16 2018 +0200

    Change default algorithm

* Update to DiffEq with better callbacks for MCWF

* Fix typo in docstring

* Better recasting for master

* Implement sparse superoperator - sparse multiplication

* Implemented faster expect function for Kets with DenseOperators and SparseOperators. Should be much faster, at least for SparseOperators.

* Remove unnecessary term from stochastic master

* Implement coherent spin states (qojulia#222)

* Change stochastic master and implement homodyne CM scheme

* Add info message to slow sparse diagonalization

commit ba5ebec
Author: David Plankensteiner <[email protected]>
Date:   Mon Jul 9 17:15:00 2018 +0200

    Suppress info in tests

commit e36f652
Author: David Plankensteiner <[email protected]>
Date:   Mon Jul 9 17:13:44 2018 +0200

    Print info when sparse diagonalization is used

* Fix typo in Carmichael docstring
  • Loading branch information
karolpezet authored Jul 15, 2018
1 parent b571452 commit 614f390
Show file tree
Hide file tree
Showing 30 changed files with 596 additions and 932 deletions.
8 changes: 4 additions & 4 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
julia 0.6
Compat 0.52.0
OrdinaryDiffEq 3.8.0
DiffEqCallbacks 1.0
StochasticDiffEq 4.2.4
Compat 0.64.0
OrdinaryDiffEq 3.19.1
DiffEqCallbacks 1.1
StochasticDiffEq 4.4.5
RecursiveArrayTools
10 changes: 6 additions & 4 deletions src/QuantumOptics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ export bases, Basis, GenericBasis, CompositeBasis, basis,
operators_lazysum, LazySum,
operators_lazyproduct, LazyProduct,
operators_lazytensor, LazyTensor,
randstate, randoperator,
superoperators, SuperOperator, DenseSuperOperator, SparseSuperOperator,
spre, spost, liouvillian,
fock, FockBasis, number, destroy, create,
fockstate, coherentstate, displace,
randstate, randoperator, thermalstate, coherentthermalstate, phase_average, passive_state,
spin, SpinBasis, sigmax, sigmay, sigmaz, sigmap, sigmam, spinup, spindown,
subspace, SubspaceBasis, projector,
particle, PositionBasis, MomentumBasis, samplepoints, gaussianstate,
position, momentum, potentialoperator, transform,
nlevel, NLevelBasis, transition, nlevelstate,
manybody, ManyBodyBasis, fermionstates, bosonstates,
manybodyoperator, onebodyexpect, occupation,
phasespace, qfunc, wigner,
phasespace, qfunc, wigner, coherentspinstate,
metrics, tracenorm, tracenorm_h, tracenorm_nh,
tracedistance, tracedistance_h, tracedistance_nh,
entropy_vn, fidelity, ptranspose, PPT,
Expand All @@ -48,10 +48,10 @@ include("operators_sparse.jl")
include("operators_lazysum.jl")
include("operators_lazyproduct.jl")
include("operators_lazytensor.jl")
include("random.jl")
include("superoperators.jl")
include("spin.jl")
include("fock.jl")
include("state_definitions.jl")
include("subspace.jl")
include("particle.jl")
include("nlevel.jl")
Expand All @@ -74,10 +74,12 @@ include("timecorrelations.jl")
include("spectralanalysis.jl")
include("semiclassical.jl")
module stochastic
include("stochastic_definitions.jl")
include("stochastic_schroedinger.jl")
include("stochastic_master.jl")
include("stochastic_semiclassical.jl")
using .stochastic_schroedinger, .stochastic_master, .stochastic_semiclassical
using .stochastic_definitions
end
include("printing.jl")

Expand All @@ -89,10 +91,10 @@ using .operators_sparse
using .operators_lazysum
using .operators_lazyproduct
using .operators_lazytensor
using .random
using .superoperators
using .spin
using .fock
using .state_definitions
using .subspace
using .particle
using .nlevel
Expand Down
8 changes: 4 additions & 4 deletions src/master.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,15 @@ master_nh_dynamic(tspan, psi0::Ket, f::Function; kwargs...) = master_nh_dynamic(


# Recasting needed for the ODE solver is just providing the underlying data
function recast!(x::Vector{Complex128}, rho::DenseOperator)
rho.data = reshape(x, size(rho.data))
function recast!(x::Array{Complex128, 2}, rho::DenseOperator)
rho.data = x
end
recast!(rho::DenseOperator, x::Vector{Complex128}) = nothing
recast!(rho::DenseOperator, x::Array{Complex128, 2}) = nothing

function integrate_master(tspan, df::Function, rho0::DenseOperator,
fout::Union{Void, Function}; kwargs...)
tspan_ = convert(Vector{Float64}, tspan)
x0 = reshape(rho0.data, length(rho0))
x0 = rho0.data
state = DenseOperator(rho0.basis_l, rho0.basis_r, rho0.data)
dstate = DenseOperator(rho0.basis_l, rho0.basis_r, rho0.data)
integrate(tspan_, df, x0, state, dstate, fout; kwargs...)
Expand Down
13 changes: 11 additions & 2 deletions src/metrics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export tracenorm, tracenorm_h, tracenorm_nh,
entropy_vn, fidelity, ptranspose, PPT, negativity,
logarithmic_negativity

using ..bases, ..operators, ..operators_dense
using ..bases, ..operators, ..operators_dense, ..states

"""
tracenorm(rho)
Expand Down Expand Up @@ -147,8 +147,17 @@ S(ρ) = -Tr(ρ \\log(ρ)) = -\\sum_n λ_n\\log(λ_n)
where ``λ_n`` are the eigenvalues of the density matrix ``ρ``, ``\\log`` is the
natural logarithm and ``\\log(0) ≡ 0``.
# Arguments
* `rho`: Density operator of which to calculate Von Neumann entropy.
* `tol=1e-15`: Tolerance for rounding errors in the computed eigenvalues.
"""
entropy_vn(rho::DenseOperator) = sum([d == 0 ? 0 : -d*log(d) for d=eigvals(rho.data)])
function entropy_vn(rho::DenseOperator; tol::Float64=1e-15)
evals = eigvals(rho.data)
evals[abs.(evals) .< tol] = 0.0
sum([d == 0 ? 0 : -d*log(d) for d=evals])
end
entropy_vn(psi::StateVector; kwargs...) = entropy_vn(dm(psi); kwargs...)

"""
fidelity(rho, sigma)
Expand Down
8 changes: 6 additions & 2 deletions src/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export Operator, length, basis, dagger, ishermitian, tensor, embed,
trace, ptrace, normalize, normalize!, expect, variance,
expm, permutesystems, identityoperator

import Base: ==, +, -, *, /, length, trace, one, ishermitian, expm
import Base: ==, +, -, *, /, length, trace, one, ishermitian, expm, conj, conj!
import ..bases: basis, tensor, ptrace, permutesystems,
samebases, check_samebases, multiplicable
import ..states: dagger, normalize, normalize!
Expand Down Expand Up @@ -50,6 +50,9 @@ basis(a::Operator) = (check_samebases(a); a.basis_l)

dagger(a::Operator) = arithmetic_unary_error("Hermitian conjugate", a)

conj(a::Operator) = arithmetic_unary_error("Complex conjugate", a)
conj!(a::Operator) = conj(a::Operator)

"""
ishermitian(op::Operator)
Expand Down Expand Up @@ -155,7 +158,8 @@ Expectation value of the given operator `op` for the specified `state`.
`state` can either be a (density) operator or a ket.
"""
expect(op::Operator, state::Ket) = dagger(state)*(op*state)

expect(op::Operator, state::Ket) = dagger(state) * op * state
expect(op::Operator, state::Operator) = trace(op*state)

"""
Expand Down
10 changes: 10 additions & 0 deletions src/operators_dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ operators.dagger(x::DenseOperator) = DenseOperator(x.basis_r, x.basis_l, x.data'
operators.ishermitian(A::DenseOperator) = ishermitian(A.data)

operators.tensor(a::DenseOperator, b::DenseOperator) = DenseOperator(tensor(a.basis_l, b.basis_l), tensor(a.basis_r, b.basis_r), kron(b.data, a.data))

operators.conj(a::DenseOperator) = DenseOperator(a.basis_l, a.basis_r, conj(a.data))
operators.conj!(a::DenseOperator) = conj!(a.data)

"""
tensor(x::Ket, y::Bra)
Expand Down Expand Up @@ -121,6 +125,12 @@ end

operators.normalize!(op::DenseOperator) = scale!(op.data, 1./trace(op))

function operators.expect(op::DenseOperator, state::Ket)# where T <: Union{Ket, Bra}
check_samebases(op.basis_r, state.basis)
check_samebases(op.basis_l, state.basis)
state.data' * op.data * state.data
end

function operators.expect(op::DenseOperator, state::Operator)
check_samebases(op.basis_r, state.basis_l)
check_samebases(op.basis_l, state.basis_r)
Expand Down
10 changes: 10 additions & 0 deletions src/operators_sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ operators.tensor(a::SparseOperator, b::DenseOperator) = SparseOperator(tensor(a.

operators.trace(op::SparseOperator) = (check_samebases(op); trace(op.data))

operators.conj(op::SparseOperator) = SparseOperator(op.basis_l, op.basis_r, conj(op.data))
operators.conj!(op::SparseOperator) = conj!(op.data)

function operators.ptrace(op::SparseOperator, indices::Vector{Int})
operators.check_ptrace_arguments(op, indices)
shape = [op.basis_l.shape; op.basis_r.shape]
Expand All @@ -84,6 +87,13 @@ function operators.ptrace(op::SparseOperator, indices::Vector{Int})
SparseOperator(b_l, b_r, data)
end

function operators.expect(op::SparseOperator, state::Ket)# where T <: Union{Ket, Bra}
check_samebases(op.basis_r, state.basis)
check_samebases(op.basis_l, state.basis)
state.data' * op.data * state.data
end


function operators.expect(op::SparseOperator, state::DenseOperator)
check_samebases(op.basis_r, state.basis_l)
check_samebases(op.basis_l, state.basis_r)
Expand Down
21 changes: 19 additions & 2 deletions src/phasespace.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module phasespace

export qfunc, wigner
export qfunc, wigner, coherentspinstate

using ..bases, ..states, ..operators, ..operators_dense, ..fock
using ..bases, ..states, ..operators, ..operators_dense, ..fock, ..spin


"""
Expand Down Expand Up @@ -204,4 +204,21 @@ function _clenshaw(L::Int, abs2_2α::Float64, ρ::Matrix{Complex128})
end
end

############################ coherent spin state ##############################
function coherentspinstate(b::SpinBasis, theta::Number, phi::Number,
result = Ket(b, Vector{Complex128}(length(b))))
#theta = real(theta)
#phi = real(phi)
data = result.data
N = length(b)-1
@inbounds for n=0:N
data[n+1] =
sqrt(factorial(BigInt(N))/(factorial(BigInt(n)) *
factorial(BigInt(N-n)))) *
(sin(theta/2.)*exp(1im*phi/2.))^n *
(cos(theta/2.)*exp(-1im*phi/2.))^(N-n)
end
return result
end

end #module
27 changes: 0 additions & 27 deletions src/random.jl

This file was deleted.

22 changes: 13 additions & 9 deletions src/spectralanalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ about the way the calculation is done is needed, use the functions directly.
More details can be found at
[http://docs.julialang.org/en/stable/stdlib/linalg/].
NOTE: Especially for small systems full diagonalization with Julia's `eig`
function is often more desirable. You can convert a sparse operator `A` to a
dense one using `full(A)`.
If the given operator is non-hermitian a warning is given. This behavior
can be turned off using the keyword `warning=false`.
"""
Expand All @@ -41,15 +45,15 @@ end
"""
For sparse operators by default it only returns the 6 lowest eigenvalues.
"""
function eigenstates(op::SparseOperator, n::Int=length(basis(op)); warning=true)
function eigenstates(op::SparseOperator, n::Int=6; warning::Bool=true,
info::Bool=true, kwargs...)
b = basis(op)
if ishermitian(op)
data = Hermitian(op.data)
else
warning && warn(nonhermitian_warning)
data = op.data
end
D, V = eigs(data; nev=n, which=:SR)
# TODO: Change to sparese-Hermitian specific algorithm if more efficient
ishermitian(op) || (warning && warn(nonhermitian_warning))
info && println("INFO: Defaulting to sparse diagonalization.
If storing the full operator is possible, it might be faster to do
eigenstates(full(op)). Set info=false to turn off this message.")
D, V = eigs(op.data; which=:SR, nev=n, kwargs...)
states = [Ket(b, V[:, k]) for k=1:length(D)]
D, states
end
Expand Down Expand Up @@ -84,7 +88,7 @@ end
"""
For sparse operators by default it only returns the 6 lowest eigenvalues.
"""
eigenenergies(op::SparseOperator, n::Int=6; warning=true) = eigenstates(op, n; warning=warning)[1]
eigenenergies(op::SparseOperator, n::Int=6; kwargs...) = eigenstates(op, n; kwargs...)[1]


arithmetic_unary_error = operators.arithmetic_unary_error
Expand Down
64 changes: 64 additions & 0 deletions src/state_definitions.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module state_definitions

export randstate, randoperator, thermalstate, coherentthermalstate, phase_average, passive_state

using ..bases, ..states, ..operators, ..operators_dense, ..fock


"""
randstate(basis)
Calculate a random normalized ket state.
"""
function randstate(b::Basis)
psi = Ket(b, rand(Complex128, length(b)))
normalize!(psi)
psi
end

"""
randoperator(b1[, b2])
Calculate a random unnormalized dense operator.
"""
randoperator(b1::Basis, b2::Basis) = DenseOperator(b1, b2, rand(Complex128, length(b1), length(b2)))
randoperator(b::Basis) = randoperator(b, b)

"""
thermalstate(H,T)
Thermal state ``exp(-H/T)/Tr[exp(-H/T)]``.
"""
function thermalstate(H::Operator,T::Real)
return normalize(expm(-full(H)/T))
end

"""
coherentthermalstate(basis::FockBasis,H,T,alpha)
Coherent thermal state ``D(α)exp(-H/T)/Tr[exp(-H/T)]D^†(α)``.
"""
function coherentthermalstate(basis::FockBasis,H::Operator,T::Real,alpha::Number)
return displace(basis,alpha)*thermalstate(H,T)*dagger(displace(basis,alpha))
end

"""
phase_average(rho)
Returns the phase-average of ``ρ`` containing only the diagonal elements.
"""
function phase_average(rho::DenseOperator)
return DenseOperator(basis(rho),diagm(diag(rho.data)))
end

"""
passive_state(rho,IncreasingEigenenergies::Bool=true)
Passive state ``π`` of ``ρ``. IncreasingEigenenergies=true means that higher indices correspond to higher energies.
"""
function passive_state(rho::DenseOperator,IncreasingEigenenergies::Bool=true)
return DenseOperator(basis(rho),diagm(sort(abs.(eigvals(rho.data)),rev=IncreasingEigenenergies)))
end

end #module

Loading

0 comments on commit 614f390

Please sign in to comment.