Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Operators : Squeeze, displaceop. Addition : expm, full #25

Merged
merged 1 commit into from
Apr 21, 2015
Merged
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
8 changes: 7 additions & 1 deletion src/arrays/arraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function *{B<:OrthonormalBasis}(qm1::QuMatrix{B}, qm2::QuMatrix{B})
bases(qm2,2))
end

*(dm1::DualMatrix, dm2::DualMatrix) = (dm1.qarr*dm2.qarr)'
*(dm1::DualMatrix, dm2::DualMatrix) = (dm2.qarr*dm1.qarr)'

function +{B<:OrthonormalBasis,N}(qarr1::AbstractQuArray{B,N}, qarr2::AbstractQuArray{B,N})
if bases(qarr1) == bases(qarr2)
Expand Down Expand Up @@ -90,6 +90,12 @@ Base.scale(qarr::Union(QuArray,CTranspose), num::Number) = scale(num, qarr)
*(qarr::Union(QuArray,CTranspose), num::Number) = scale(qarr, num)
/(qarr::Union(QuArray,CTranspose), num::Number) = scale(1/num, qarr)

# sparse to dense
Base.full(qarr::AbstractQuMatrix) = QuArray(full(coeffs(qarr)),bases(qarr))

# exponential of dense matrix
Base.expm(qarr::AbstractQuMatrix) = QuArray(expm(full(coeffs(qarr))),bases(qarr))

# normalization
Base.norm(qarr::Union(QuArray,CTranspose)) = vecnorm(rawcoeffs(qarr))

Expand Down
19 changes: 18 additions & 1 deletion src/arrays/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,21 @@
one_at_ind!(arr, i) = setindex!(arr, one(eltype(arr)), i)
single_coeff(i, lens...) = one_at_ind!(zeros(lens), i)

export statevec
# Reference :
# Section - 1.1, http://cds.cern.ch/record/331607/files/9708012.pdf
function coherentstatevec_inf(n::Int,alpha::Number)
s = zeros(typeof(float(alpha)),n)
s[1] = one(alpha)
for i in [2:n]
s[i] = alpha/sqrt(i-1)*s[i-1]
end
z = QuArray(s)
return scale!(exp(-abs2(alpha)/2),z)
end

# Reference :
# 2nd Defintion : http://en.wikipedia.org/wiki/Coherent_states#Mathematical_features_of_the_canonical_coherent_states
coherentstatevec(n::Int, alpha::Number) = displaceop(n,alpha)*statevec(1,FiniteBasis(n))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need both versions and for now I would prefer the second one. There might actually be a problem having both, because they only differ in the keywords and I am not sure how Julia handles this. You can check by calling

@which coherentstatevec(20,1,method = "direct")
@which coherentstatevec(20,1)

To see which versions are actually called.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried this out

println(@which coherentstatevec(10,1,method="direct"))
println(coherentstatevec(10,1,method="direct"))
println(@which coherentstatevec(10,1))
println(coherentstatevec(10,1))

# gives out 

coherentstatevec(n::Int64,alpha::Number) at QuBase.jl/src/arrays/constructors.jl:28
10-element QuVector in FiniteBasis{Orthonormal,1}:
...coefficients: Array{Float64,1}
[0.6065306597126334,0.6065306597126334,0.4288819424803534,0.24761510494160166,0.12380755247080083,0.05536842069051653,0.02260406309258736,0.008543532794657104,0.0030205949871958465,0.001006864995731949]
coherentstatevec(n::Int64,alpha::Number) at QuBase.jl/src/arrays/constructors.jl:28
10-element QuVector in FiniteBasis{Orthonormal,1}:
...coefficients: Array{Float64,1}
[0.6065306597114603,0.6065306597355303,0.4288819421804789,0.24761510797604577,0.12380752738214919,0.05536859516814174,0.02260302507996636,0.008548870306885925,0.0029967233467164565,0.0011000726308558629]

The output is different though they point to the same method which is reflected by the @which

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be sure you can put a println statement in one of the functions ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave in a println for the rand(n) and this is the output ... seems like the method is being called but is not reflected by @which

coherentstatevec(n::Int64,alpha::Number) at QuBase.jl/src/arrays/constructors.jl:28

# printing rand(n)

[0.019244684430714143,0.3719091096873184,0.9047165798455694,0.6866397480495858,0.5561245580875909,0.14391135614954487,0.6180840544733457,0.002417775152962154,0.9427717780056364,0.20641868199486169]

# returning the output 

10-element QuVector in FiniteBasis{Orthonormal,1}:
...coefficients: Array{Float64,1}
[0.6065306597126334,0.6065306597126334,0.4288819424803534,0.24761510494160166,0.12380755247080083,0.05536842069051653,0.02260406309258736,0.008543532794657104,0.0030205949871958465,0.001006864995731949]


coherentstatevec(n::Int64,alpha::Number) at QuBase.jl/src/arrays/constructors.jl:28
10-element QuVector in FiniteBasis{Orthonormal,1}:
...coefficients: Array{Float64,1}
[0.6065306597114603,0.6065306597355303,0.4288819421804789,0.24761510797604577,0.12380752738214919,0.05536859516814174,0.02260302507996636,0.008548870306885925,0.0029967233467164565,0.0011000726308558629]


export statevec,
coherentstatevec
10 changes: 9 additions & 1 deletion src/arrays/ladderops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,15 @@ function momentumop(n::Int)
return scale(im/sqrt(2.), cop-cop')
end

squeeze_construct(a::AbstractQuMatrix,b::AbstractQuMatrix, z::Number) = scale!(0.5,(scale!(z',a*b)-scale!(z,a'*b')))
squeezingop(a::AbstractQuMatrix, b::AbstractQuMatrix, z::Number) = expm(squeeze_construct(a,b,z))
squeezingop(n::Int,z::Number) = squeezingop(lowerop(n),lowerop(n),z)

displaceop(n::Int,alpha::Number) = expm(scale(alpha,lowerop(n)')-scale(alpha',lowerop(n)))

export raiseop,
lowerop,
positionop,
momentumop
momentumop,
squeezingop,
displaceop
2 changes: 1 addition & 1 deletion test/multest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ qv = QuArray(v)
@test_approx_eq rawcoeffs(normalize(qv)) rawcoeffs(qv)/norm(v)

# a simple test of the `==` operator
@assert qm*3im == scale!(3im, copy(qm))
@assert qm*3im == scale!(3im, copy(qm))
17 changes: 14 additions & 3 deletions test/operatortest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,22 @@

@assert coeffs(commutator(sigma_x, sigma_x)) == spzeros(2,2)

######################################
# Position & Momentum Operators Test #
######################################
####################################################
# Position, Displacement & Momentum Operators Test #
####################################################

p = positionop(2)
m = momentumop(2)
@assert coeffs(commutator(sigma_x, p)) == spzeros(2,2)
@assert coeffs(commutator(sigma_y, m)) == spzeros(2,2)

coherentstate_inf = QuBase.coherentstatevec_inf(20,1)
coherentstate = displaceop(20,1)*statevec(1,FiniteBasis(20))
@test_approx_eq_eps coeffs(coherentstate_inf)[1] coeffs(coherentstate)[1] 1e-8

############################
# Squeezing Operators Test #
############################

@assert squeezingop(2,1.0)== QuArray(eye(2))
@test_approx_eq coeffs(squeezingop(lowerop(2), QuArray(eye(2)), 2.0)') coeffs(displaceop(2,1.0))