diff --git a/REQUIRE b/REQUIRE index d76558f..3df93e9 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,3 +1,3 @@ -julia 0.3 0.4- +julia 0.6 Compat -Iterators \ No newline at end of file +Iterators diff --git a/src/QuDirac.jl b/src/QuDirac.jl index c018411..25919b7 100644 --- a/src/QuDirac.jl +++ b/src/QuDirac.jl @@ -1,12 +1,12 @@ module QuDirac - + using Compat using Iterators.product - if !(v"0.3-" <= VERSION < v"0.4-") - warn("QuDirac v0.1 only officially supports the v0.3 release of Julia. Your version of Julia is $VERSION.") + if !(VERSION < v"0.6") + warn("QuDirac v0.1 only officially supports the v0.6 release of Julia. Your version of Julia is $VERSION.") end - + #################### # String Constants # #################### @@ -18,21 +18,21 @@ module QuDirac ################## # Abstract Types # ################## - abstract AbstractInner - - immutable UndefinedInner <: AbstractInner end + abstract type AbstractInner end + + immutable UndefinedInner <: AbstractInner end immutable KroneckerDelta <: AbstractInner end - - abstract AbstractDirac{P<:AbstractInner,N} - abstract DiracOp{P,N} <: AbstractDirac{P,N} - abstract DiracState{P,N} <: AbstractDirac{P,N} - abstract DiracScalar <: Number + abstract type AbstractDirac{P<:AbstractInner,N} end + abstract type DiracOp{P,N} <: AbstractDirac{P,N} end + abstract type DiracState{P,N} <: AbstractDirac{P,N} end + + abstract type DiracScalar <: Number end ############# # Functions # ############# - # These functions will be in + # These functions will be in # QuBase when it releases tensor() = error("Cannot call tensor function without arguments") tensor(s...) = reduce(tensor, s) @@ -49,19 +49,19 @@ module QuDirac include("dictfuncs.jl") include("mapfuncs.jl") include("str_macros.jl") - + ################# # default_inner # ################# - # Julia doesn't recompile functions within other - # previously compiled functions, so we can't have a + # Julia doesn't recompile functions within other + # previously compiled functions, so we can't have a # get_default_inner() or something like that. # # Also, global optimization is poor, so we don't want # to use that either. Thus, we go for a function that - # straight-up redefines the default constructors for - # the relevant objects. This is hacky, but works for now, - # seeing as how only a few functions actually "use" + # straight-up redefines the default constructors for + # the relevant objects. This is hacky, but works for now, + # seeing as how only a few functions actually "use" # the default ptype. function default_inner(ptype::AbstractInner) QuDirac.OpSum(dict::Dict) = OpSum(ptype, dict) @@ -80,8 +80,8 @@ module QuDirac AbstractDirac, DiracState, DiracOp, - # All functions that conflict - # with QuBase should be exported + # All functions that conflict + # with QuBase should be exported # below: tensor, commute, diff --git a/src/innerexpr.jl b/src/innerexpr.jl index 799633f..26d8946 100644 --- a/src/innerexpr.jl +++ b/src/innerexpr.jl @@ -12,12 +12,12 @@ klabel(i::InnerProduct) = i.k Base.repr(i::InnerProduct) = brstr(blabel(i))*ktstr(klabel(i))[2:end] Base.show(io::IO, i::InnerProduct) = print(io, repr(i)) -Base.(:(==))(a::InnerProduct, b::InnerProduct) = blabel(a) == blabel(b) && klabel(a) == klabel(b) -Base.(:(==))(::InnerProduct, ::Number) = false -Base.(:(==))(::Number, ::InnerProduct) = false +Base.:(==)(a::InnerProduct, b::InnerProduct) = blabel(a) == blabel(b) && klabel(a) == klabel(b) +Base.:(==)(::InnerProduct, ::Number) = false +Base.:(==)(::Number, ::InnerProduct) = false Base.hash(i::InnerProduct) = hash(blabel(i), hash(klabel(i))) -Base.hash(i::InnerProduct, h::Uint64) = hash(hash(i), h) +Base.hash(i::InnerProduct, h::UInt64) = hash(hash(i), h) Base.conj(i::InnerProduct) = InnerProduct(klabel(i), blabel(i)) @@ -26,7 +26,7 @@ Base.conj(i::InnerProduct) = InnerProduct(klabel(i), blabel(i)) ############## # we can cheat here to avoid tempory StateLabel construction -# to evaluate KroneckerDelta inner products +# to evaluate KroneckerDelta inner products eval_inner_rule(p::KroneckerDelta, b, k) = inner_rule(p, b, k) eval_inner_rule(p::KroneckerDelta, b::StateLabel, k::StateLabel) = inner_rule(p, b, k) @@ -48,10 +48,10 @@ inner_mul(v,c,prodtype,b,k) = v * c * eval_inner_rule(prodtype, b, k) # InnerExpr # ############## # A InnerExpr is a type that wraps arthimetic expressions -# performed with InnerExprs. The allows storage and -# delayed evaluation of expressions. For example, this +# performed with InnerExprs. The allows storage and +# delayed evaluation of expressions. For example, this # expression: -# +# # (< a | b >^2 + < c | d >^2 - 3.13+im) / 2 # # is representable as a InnerExpr. @@ -66,7 +66,7 @@ InnerExpr{N<:Number}(n::N) = convert(InnerExpr, n) Base.convert(::Type{InnerExpr}, iex::InnerExpr) = iex Base.convert{N<:Number}(::Type{InnerExpr}, n::N) = InnerExpr(Expr(:call, +, n)) -Base.(:(==))(a::InnerExpr, b::InnerExpr) = a.ex == b.ex +Base.:(==)(a::InnerExpr, b::InnerExpr) = a.ex == b.ex same_num(a::Number, b::Number) = a == b same_num(a::InnerExpr, b::InnerExpr) = a == b same_num(iex::InnerExpr, i::InnerProduct) = iex == InnerExpr(i) @@ -75,7 +75,7 @@ same_num(iex::InnerExpr, n::Number) = iex == InnerExpr(n) same_num(n::Number, iex::InnerExpr) = iex == n Base.hash(iex::InnerExpr) = hash(iex.ex) -Base.hash(iex::InnerExpr, h::Uint64) = hash(hash(iex), h) +Base.hash(iex::InnerExpr, h::UInt64) = hash(hash(iex), h) Base.one(::InnerExpr) = InnerExpr(1) Base.zero(::InnerExpr) = InnerExpr(0) @@ -83,7 +83,7 @@ Base.zero(::InnerExpr) = InnerExpr(0) Base.promote_rule{N<:Number}(::Type{InnerExpr}, ::Type{N}) = InnerExpr Base.length(iex::InnerExpr) = length(iex.ex.args) -Base.getindex(iex::InnerExpr, i) = iex.ex.args[i] +Base.getindex(iex::InnerExpr, i::Integer) = iex.ex.args[i] ############## # inner_eval # @@ -123,12 +123,12 @@ function iexpr_exp(a, b) end end -Base.(:^)(a::InnerExpr, b::Integer) = iexpr_exp(a, b) -Base.(:^)(a::InnerExpr, b::Rational) = iexpr_exp(a, b) -Base.(:^)(a::InnerExpr, b::InnerExpr) = iexpr_exp(a, b) -Base.(:^)(a::InnerExpr, b::Number) = iexpr_exp(a, b) -Base.(:^)(a::MathConst{:e}, b::InnerExpr) = iexpr_exp(a, b) -Base.(:^)(a::Number, b::InnerExpr) = iexpr_exp(a, b) +Base.:^(a::InnerExpr, b::Integer) = iexpr_exp(a, b) +Base.:^(a::InnerExpr, b::Rational) = iexpr_exp(a, b) +Base.:^(a::InnerExpr, b::InnerExpr) = iexpr_exp(a, b) +Base.:^(a::InnerExpr, b::Number) = iexpr_exp(a, b) +#Base.:^(a::MathConst{:e}, b::InnerExpr) = iexpr_exp(a, b) +Base.:^(a::Number, b::InnerExpr) = iexpr_exp(a, b) Base.exp(iex::InnerExpr) = InnerExpr(:(exp($(iex)))) Base.exp2(iex::InnerExpr) = InnerExpr(:(exp2($(iex)))) @@ -136,7 +136,7 @@ Base.exp2(iex::InnerExpr) = InnerExpr(:(exp2($(iex)))) Base.sqrt(iex::InnerExpr) = InnerExpr(:(sqrt($(iex)))) Base.log(iex::InnerExpr) = length(iex)==2 && iex[1]==:exp ? iex[2] : InnerExpr(:(log($(iex)))) -Base.log(a::MathConst{:e}, b::InnerExpr) = InnerExpr(:(log($(a),$(b)))) +#Base.log(a::MathConst{:e}, b::InnerExpr) = InnerExpr(:(log($(a),$(b)))) Base.log(a::InnerExpr, b::InnerExpr) = InnerExpr(:(log($(a),$(b)))) Base.log(a::InnerExpr, b::Number) = InnerExpr(:(log($(a),$(b)))) Base.log(a::Number, b::InnerExpr) = InnerExpr(:(log($(a),$(b)))) @@ -157,11 +157,11 @@ function iexpr_mul(a,b) end end -Base.(:*)(a::InnerExpr, b::InnerExpr) =iexpr_mul(a,b) -Base.(:*)(a::Bool, b::InnerExpr) = iexpr_mul(a,b) -Base.(:*)(a::InnerExpr, b::Bool) = iexpr_mul(a,b) -Base.(:*)(a::InnerExpr, b::Number) = iexpr_mul(a,b) -Base.(:*)(a::Number, b::InnerExpr) = iexpr_mul(a,b) +Base.:*(a::InnerExpr, b::InnerExpr) =iexpr_mul(a,b) +Base.:*(a::Bool, b::InnerExpr) = iexpr_mul(a,b) +Base.:*(a::InnerExpr, b::Bool) = iexpr_mul(a,b) +Base.:*(a::InnerExpr, b::Number) = iexpr_mul(a,b) +Base.:*(a::Number, b::InnerExpr) = iexpr_mul(a,b) ############ # Division # @@ -180,16 +180,16 @@ function iexpr_div(a, b) end end -Base.(:/)(a::InnerExpr, b::InnerExpr) = iexpr_div(a, b) -Base.(:/)(a::InnerExpr, b::Complex) = iexpr_div(a, b) -Base.(:/)(a::InnerExpr, b::Number) = iexpr_div(a, b) -Base.(:/)(a::Number, b::InnerExpr) = iexpr_div(a, b) +Base.:/(a::InnerExpr, b::InnerExpr) = iexpr_div(a, b) +Base.:/(a::InnerExpr, b::Complex) = iexpr_div(a, b) +Base.:/(a::InnerExpr, b::Number) = iexpr_div(a, b) +Base.:/(a::Number, b::InnerExpr) = iexpr_div(a, b) ############ # Addition # ############ function iexpr_add(a, b) - if same_num(a, 0) + if same_num(a, 0) return InnerExpr(b) elseif same_num(b, 0) return InnerExpr(a) @@ -198,14 +198,14 @@ function iexpr_add(a, b) end end -Base.(:+)(a::InnerExpr, b::InnerExpr) = iexpr_add(a, b) -Base.(:+)(a::InnerExpr, b::Number) = iexpr_add(a, b) -Base.(:+)(a::Number, b::InnerExpr) = iexpr_add(a, b) +Base.:+(a::InnerExpr, b::InnerExpr) = iexpr_add(a, b) +Base.:+(a::InnerExpr, b::Number) = iexpr_add(a, b) +Base.:+(a::Number, b::InnerExpr) = iexpr_add(a, b) ############### # Subtraction # ############### -Base.(:-)(iex::InnerExpr) = length(iex)==2 && iex[1]==:- ? InnerExpr(iex[2]) : InnerExpr(:(-$(iex))) +Base.:-(iex::InnerExpr) = length(iex)==2 && iex[1]==:- ? InnerExpr(iex[2]) : InnerExpr(:(-$(iex))) function iexpr_subtract(a, b) if same_num(a, b) @@ -219,9 +219,9 @@ function iexpr_subtract(a, b) end end -Base.(:-)(a::InnerExpr, b::InnerExpr) = iexpr_subtract(a, b) -Base.(:-)(a::InnerExpr, b::Number) = iexpr_subtract(a, b) -Base.(:-)(a::Number, b::InnerExpr) = iexpr_subtract(a, b) +Base.:-(a::InnerExpr, b::InnerExpr) = iexpr_subtract(a, b) +Base.:-(a::InnerExpr, b::Number) = iexpr_subtract(a, b) +Base.:-(a::Number, b::InnerExpr) = iexpr_subtract(a, b) ################## # Absolute Value # @@ -239,7 +239,7 @@ Base.ctranspose(iex::InnerExpr) = conj(iex) # Elementwise Operations # ########################## for op=(:*,:-,:+,:/,:^) - elop = symbol(string(:.) * string(op)) + elop = Symbol(string(:.) * string(op)) @eval begin ($elop)(a::InnerExpr, b::InnerExpr) = ($op)(a,b) ($elop)(a::InnerExpr, b::Number) = ($op)(a,b) diff --git a/src/labels.jl b/src/labels.jl index aae96e9..e93566e 100644 --- a/src/labels.jl +++ b/src/labels.jl @@ -3,9 +3,9 @@ ############## immutable StateLabel{N} label::NTuple{N} - hash::Uint64 - StateLabel(label::NTuple{N}) = new(label, hash(label)) - StateLabel(label::NTuple{N}, h::Uint64) = new(label, h) + hash::UInt64 + StateLabel{N}(label::NTuple{N}) where N = new(label, hash(label)) + StateLabel{N}(label::NTuple{N}, h::UInt64) where N = new(label, h) end StateLabel(s::StateLabel) = s @@ -18,9 +18,9 @@ Base.getindex(s::StateLabel, arr::AbstractArray) = s.label[arr] Base.copy{N}(s::StateLabel{N}) = StateLabel{N}(s.label, s.hash) Base.hash(s::StateLabel) = s.hash -Base.hash(s::StateLabel, h::Uint64) = hash(hash(s), h) +Base.hash(s::StateLabel, h::UInt64) = hash(hash(s), h) -Base.(:(==)){N}(a::StateLabel{N},b::StateLabel{N}) = hash(a) == hash(b) +Base.:(==){N}(a::StateLabel{N},b::StateLabel{N}) = hash(a) == hash(b) Base.start(s::StateLabel) = start(s.label) Base.next(s::StateLabel, i) = next(s.label, i) @@ -32,7 +32,7 @@ Base.endof(s::StateLabel) = endof(s.label) Base.length{N}(::StateLabel{N}) = N -Base.map(f::Union(Function,DataType), s::StateLabel) = StateLabel(map(f, s.label)) +#Base.map(f::Union(Function,DataType), s::StateLabel) = StateLabel(map(f, s.label)) tensor(a::StateLabel, b::StateLabel) = StateLabel(tuple(a.label..., b.label...)) @@ -46,9 +46,9 @@ Base.show(io::IO, s::StateLabel) = print(io, repr(s)) immutable OpLabel{N} k::StateLabel{N} b::StateLabel{N} - hash::Uint64 - OpLabel(k::StateLabel{N}, b::StateLabel{N}) = new(k, b, hash(k, hash(b))) - OpLabel(k::StateLabel{N}, b::StateLabel{N}, h::Uint64) = new(k, b, h) + hash::UInt64 + OpLabel{N}(k::StateLabel{N}, b::StateLabel{N}) where N = new(k, b, hash(k, hash(b))) + OpLabel{N}(k::StateLabel{N}, b::StateLabel{N}, h::UInt64) where N = new(k, b, h) end OpLabel(op::OpLabel) = op @@ -61,9 +61,9 @@ blabel(o::OpLabel) = o.b Base.copy{N}(o::OpLabel{N}) = OpLabel{N}(o.k, o.b, o.hash) Base.hash(o::OpLabel) = o.hash -Base.hash(o::OpLabel, h::Uint64) = hash(hash(o), h) +Base.hash(o::OpLabel, h::UInt64) = hash(hash(o), h) -Base.(:(==)){N}(a::OpLabel{N}, b::OpLabel{N}) = hash(a) == hash(b) +Base.:(==){N}(a::OpLabel{N}, b::OpLabel{N}) = hash(a) == hash(b) Base.length{N}(::OpLabel{N}) = N diff --git a/src/mapfuncs.jl b/src/mapfuncs.jl index 226670b..8bc0e78 100644 --- a/src/mapfuncs.jl +++ b/src/mapfuncs.jl @@ -29,36 +29,36 @@ Base.filter(f::Function, op::OuterProduct) = filter(f, convert(OpSum, op)) ######################## # mapcoeffs!/mapcoeffs # ######################## -mapcoeffs!(f::Union(Function,DataType), k::Ket) = (mapvals!(f, dict(k)); return k) -mapcoeffs!(f::Union(Function,DataType), b::Bra) = (mapvals!(v->f(v')', dict(b)); return b) -mapcoeffs!(f::Union(Function,DataType), op::OpSum) = (mapvals!(f, dict(op)); return op) -mapcoeffs!(f::Union(Function,DataType), opc::DualOpSum) = (mapvals!(v->f(v')', dict(opc)); return opc) +mapcoeffs!(f::Function, k::Ket) = (mapvals!(f, dict(k)); return k) +mapcoeffs!(f::Function, b::Bra) = (mapvals!(v->f(v')', dict(b)); return b) +mapcoeffs!(f::Function, op::OpSum) = (mapvals!(f, dict(op)); return op) +mapcoeffs!(f::Function, opc::DualOpSum) = (mapvals!(v->f(v')', dict(opc)); return opc) -mapcoeffs(f::Union(Function,DataType), kt::Ket) = similar(kt, mapvals(f, dict(kt))) -mapcoeffs(f::Union(Function,DataType), br::Bra) = similar(br, mapvals(v->f(v')', dict(br))) -mapcoeffs(f::Union(Function,DataType), op::OpSum) = similar(op, mapvals(f, dict(op))) -mapcoeffs(f::Union(Function,DataType), opc::DualOpSum) = similar(opc, mapvals(v->f(v')', dict(opc))) -mapcoeffs(f::Union(Function,DataType), op::OuterProduct) = mapcoeffs(f, convert(OpSum, op)) +mapcoeffs(f::Function, kt::Ket) = similar(kt, mapvals(f, dict(kt))) +mapcoeffs(f::Function, br::Bra) = similar(br, mapvals(v->f(v')', dict(br))) +mapcoeffs(f::Function, op::OpSum) = similar(op, mapvals(f, dict(op))) +mapcoeffs(f::Function, opc::DualOpSum) = similar(opc, mapvals(v->f(v')', dict(opc))) +mapcoeffs(f::Function, op::OuterProduct) = mapcoeffs(f, convert(OpSum, op)) ######################## # maplabels!/maplabels # ######################## -maplabels(f::Union(Function,DataType), s::DiracState) = similar(s, mapkeys(f, dict(s))) -maplabels(f::Union(Function,DataType), op::OpSum) = similar(op, mapkeys(f, dict(op))) -maplabels(f::Union(Function,DataType), opc::DualOpSum) = OpSum(ptype(opc), mapkeys(label->f(label'), dict(op))) -maplabels(f::Union(Function,DataType), op::OuterProduct) = maplabels(f, convert(OpSum, op)) +maplabels(f::Function, s::DiracState) = similar(s, mapkeys(f, dict(s))) +maplabels(f::Function, op::OpSum) = similar(op, mapkeys(f, dict(op))) +maplabels(f::Function, opc::DualOpSum) = OpSum(ptype(opc), mapkeys(label->f(label'), dict(op))) +maplabels(f::Function, op::OuterProduct) = maplabels(f, convert(OpSum, op)) ####### # map # ####### -Base.map(f::Union(Function,DataType), obj::AbstractDirac) = similar(obj, mapkv(kv->f(kv[1], kv[2]), dict(obj))) -Base.map(f::Union(Function,DataType), br::Bra) = similar(br, mapkv(kv->br_tup(f(kv[1], kv[2]')), dict(d))) -Base.map(f::Union(Function,DataType), opc::DualOpSum) = OpSum(ptype(opc), mapkv(kv->f(kv[1]', kv[2]'), dict(d))) -Base.map(f::Union(Function,DataType), op::OuterProduct) = map(f, convert(OpSum, op)) +Base.map(f::Function, obj::AbstractDirac) = similar(obj, mapkv(kv->f(kv[1], kv[2]), dict(obj))) +Base.map(f::Function, br::Bra) = similar(br, mapkv(kv->br_tup(f(kv[1], kv[2]')), dict(d))) +Base.map(f::Function, opc::DualOpSum) = OpSum(ptype(opc), mapkv(kv->f(kv[1]', kv[2]'), dict(d))) +Base.map(f::Function, op::OuterProduct) = map(f, convert(OpSum, op)) br_tup(tup) = (tup[1], tup[2]') export maplabels!, mapcoeffs!, maplabels, - mapcoeffs \ No newline at end of file + mapcoeffs diff --git a/src/opsum.jl b/src/opsum.jl index 6464cd7..1b0613f 100644 --- a/src/opsum.jl +++ b/src/opsum.jl @@ -1,15 +1,15 @@ ################### # OpSum/DualOpSum # ################### -abstract AbsOpSum{P,N,T} <: DiracOp{P,N} +abstract type AbsOpSum{P,N,T} <: DiracOp{P,N} end -typealias OpDict{N,T} Dict{OpLabel{N},T} +OpDict{N,T} = Dict{OpLabel{N},T} type OpSum{P,N,T} <: AbsOpSum{P,N,T} ptype::P dict::OpDict{N,T} - OpSum(ptype, dict) = new(ptype, dict) - OpSum(ptype, dict::OpDict{0}) = error("Cannot construct a 0-factor operator; did you mean to construct a scalar?") + OpSum{P,N,T}(ptype, dict) where {P,N,T} = new(ptype, dict) + OpSum{P,N,T}(ptype, dict::OpDict{0}) where {P,N,T} = error("Cannot construct a 0-factor operator; did you mean to construct a scalar?") end OpSum{P,N,T}(ptype::P, dict::OpDict{N,T}) = OpSum{P,N,T}(ptype, dict) @@ -57,12 +57,12 @@ Base.copy(opc::DualOpSum) = DualOpSum(copy(opc.op)) Base.similar(op::OpSum, d=similar(dict(op)); P=ptype(op)) = OpSum(P, d) Base.similar(opc::DualOpSum, d=similar(dict(opc)); P=ptype(opc)) = DualOpSum(P, d) -Base.(:(==)){P,N}(a::OpSum{P,N}, b::OpSum{P,N}) = ptype(a) == ptype(b) && dict(filternz(a)) == dict(filternz(b)) -Base.(:(==)){P,N}(a::DualOpSum{P,N}, b::DualOpSum{P,N}) = a.op == b.op -Base.(:(==))(a::DiracOp, b::DiracOp) = ==(promote(a,b)...) +Base.:(==){P,N}(a::OpSum{P,N}, b::OpSum{P,N}) = ptype(a) == ptype(b) && dict(filternz(a)) == dict(filternz(b)) +Base.:(==){P,N}(a::DualOpSum{P,N}, b::DualOpSum{P,N}) = a.op == b.op +Base.:(==)(a::DiracOp, b::DiracOp) = ==(promote(a,b)...) Base.hash(op::AbsOpSum) = hash(dict(filternz(op)), hash(ptype(op))) -Base.hash(op::AbsOpSum, h::Uint64) = hash(hash(op), h) +Base.hash(op::AbsOpSum, h::UInt64) = hash(hash(op), h) Base.length(op::AbsOpSum) = length(dict(op)) @@ -160,7 +160,7 @@ inner(a::DualOpSum, b::DualOpSum) = inner(b.op, a.op)' function inner_load!(result, a::OpSum, b::OpSum, prodtype) for (o1,v) in dict(a), (o2,c) in dict(b) - add_to_dict!(result, + add_to_dict!(result, OpLabel(klabel(o1), blabel(o2)), inner_mul(v, c, prodtype, blabel(o1), klabel(o2))) end @@ -169,7 +169,7 @@ end function inner_load!(result, a::OpSum, b::DualOpSum, prodtype) for (o1,v) in dict(a), (o2,c) in dict(b) - add_to_dict!(result, + add_to_dict!(result, OpLabel(klabel(o1), klabel(o2)), inner_mul(v, c', prodtype, blabel(o1), blabel(o2))) end @@ -202,7 +202,7 @@ end function brcoeff{T}(brdict, prodtype, klabel, v, ::Type{T}) coeff = predict_zero(T) for (blabel,c) in brdict - coeff += inner_mul(c', v, prodtype, klabel, blabel) + coeff += inner_mul(c', v, prodtype, klabel, blabel) end return coeff' end @@ -215,9 +215,9 @@ function ktcoeff{T}(ktdict, prodtype, blabel, v, ::Type{T}) return coeff end -Base.(:*)(br::Bra, op::DiracOp) = inner(br,op) -Base.(:*)(op::DiracOp, kt::Ket) = inner(op,kt) -Base.(:*)(a::DiracOp, b::DiracOp) = inner(a,b) +Base.:*(br::Bra, op::DiracOp) = inner(br,op) +Base.:*(op::DiracOp, kt::Ket) = inner(op,kt) +Base.:*(a::DiracOp, b::DiracOp) = inner(a,b) ################################### # Functional Operator Application # @@ -226,10 +226,10 @@ immutable DualFunc f::Function end -Base.(:*)(op::Function, kt::Ket) = op(kt) -Base.(:*)(br::Bra, op::Function) = op(br) -Base.(:*)(op::DualFunc, kt::Ket) = (kt' * op.f)' -Base.(:*)(br::Bra, op::DualFunc) = (op.f * br')' +Base.:*(op::Function, kt::Ket) = op(kt) +Base.:*(br::Bra, op::Function) = op(br) +Base.:*(op::DualFunc, kt::Ket) = (kt' * op.f)' +Base.:*(br::Bra, op::DualFunc) = (op.f * br')' Base.ctranspose(f::Function) = DualFunc(f) Base.ctranspose(fc::DualFunc) = fc.f @@ -257,7 +257,7 @@ end function act_on_dict!(result, op::OpSum, kt::Ket, i, prodtype) for (o,c) in dict(op), (k,v) in dict(kt) - add_to_dict!(result, + add_to_dict!(result, setindex(k, klabel(o)[1], i), inner_mul(c, v, prodtype, blabel(o)[1], k[i])) end @@ -280,39 +280,42 @@ tensor{P}(a::OpSum{P}, b::OpSum{P}) = OpSum(ptype(a), tensordict(dict(a), dict(b tensor(a::DualOpSum, b::DualOpSum) = tensor(a.opc, b.opc)' tensor(a::DiracOp, b::DiracOp) = tensor(promote(a,b)...) -Base.(:*)(kt::Ket, br::Bra) = tensor(kt,br) +Base.:*(kt::Ket, br::Bra) = tensor(kt,br) ########### # Scaling # ########### -Base.scale!(op::OpSum, c::Number) = (dscale!(dict(op), c); return op) -Base.scale!(c::Number, op::OpSum) = scale!(op, c) -Base.scale!(opc::DualOpSum, c::Number) = DualOpSum(scale!(opc.op, c')) -Base.scale!(c::Number, opc::DualOpSum) = scale!(opc, c) +scale!(op::OpSum, c::Number) = (dscale!(dict(op), c); return op) +scale!(c::Number, op::OpSum) = scale!(op, c) +scale!(opc::DualOpSum, c::Number) = DualOpSum(scale!(opc.op, c')) +scale!(c::Number, opc::DualOpSum) = scale!(opc, c) + +# See #15258 in JuliaLang/julia + +scale(op::OpSum, c::Number) = similar(op, dscale(dict(op), c)) +scale(c::Number , op::OpSum) = op * c +scale(opc::DualOpSum, c::Number) = DualOpSum(opc.op * (c')) +scale(c::Number, opc::DualOpSum) = opc * c -Base.scale(op::OpSum, c::Number) = similar(op, dscale(dict(op), c)) -Base.scale(c::Number, op::OpSum) = scale(op, c) -Base.scale(opc::DualOpSum, c::Number) = DualOpSum(scale(opc.op, c')) -Base.scale(c::Number, opc::DualOpSum) = scale(opc, c) -Base.(:*)(c::Number, op::DiracOp) = scale(c, op) -Base.(:*)(op::DiracOp, c::Number) = scale(op, c) -Base.(:/)(op::DiracOp, c::Number) = scale(op, 1/c) +Base.:*(c::Number, op::DiracOp) = scale(c, op) +Base.:*(op::DiracOp, c::Number) = scale(op, c) +Base.:/(op::DiracOp, c::Number) = scale(op, 1/c) ########### # + and - # ########### -Base.(:-)(op::OpSum) = scale(-1, op) -Base.(:-)(opc::DualOpSum) = DualOpSum(-opc.op) +Base.:-(op::OpSum) = scale(-1, op) +Base.:-(opc::DualOpSum) = DualOpSum(-opc.op) -Base.(:+){P,N}(a::OpSum{P,N}, b::OpSum{P,N}) = similar(b, add_merge(dict(a), dict(b))) -Base.(:-){P,N}(a::OpSum{P,N}, b::OpSum{P,N}) = similar(b, sub_merge(dict(a), dict(b))) +Base.:+{P,N}(a::OpSum{P,N}, b::OpSum{P,N}) = similar(b, add_merge(dict(a), dict(b))) +Base.:-{P,N}(a::OpSum{P,N}, b::OpSum{P,N}) = similar(b, sub_merge(dict(a), dict(b))) -Base.(:+){P,N}(a::DualOpSum{P,N}, b::DualOpSum{P,N}) = DualOpSum(a.op + b.op) -Base.(:-){P,N}(a::DualOpSum{P,N}, b::DualOpSum{P,N}) = DualOpSum(a.op - b.op) +Base.:+{P,N}(a::DualOpSum{P,N}, b::DualOpSum{P,N}) = DualOpSum(a.op + b.op) +Base.:-{P,N}(a::DualOpSum{P,N}, b::DualOpSum{P,N}) = DualOpSum(a.op - b.op) -Base.(:+)(a::DiracOp, b::DiracOp) = +(promote(a,b)...) -Base.(:-)(a::DiracOp, b::DiracOp) = a + (-b) +Base.:+(a::DiracOp, b::DiracOp) = +(promote(a,b)...) +Base.:-(a::DiracOp, b::DiracOp) = a + (-b) ################# # Normalization # @@ -320,8 +323,8 @@ Base.(:-)(a::DiracOp, b::DiracOp) = a + (-b) Base.norm(op::OpSum) = sqrt(sum(abs2, values(dict(op)))) Base.norm(opc::DualOpSum) = norm(opc.op) -normalize(op::DiracOp) = scale(1/norm(op), op) -normalize!(op::DiracOp) = scale!(1/norm(op), op) +QuDirac.normalize(op::DiracOp) = (1/norm(op))*op +QuDirac.normalize!(op::DiracOp) = scale!(1/norm(op), op) ######### # Trace # @@ -408,11 +411,11 @@ function matrep(op::DiracOp, labels...) return T[bra(i...) * op * ket(j...) for i in iter, j in iter] end -function matrep(op::Union(DualFunc, Function), labels) +function matrep(op::DualFunc, labels) return [bra(i) * op * ket(j) for i in labels, j in labels] end -function matrep(op::Union(DualFunc, Function), labels...) +function matrep(op::DualFunc, labels...) iter = Iterators.product(labels...) return [bra(i...) * op * ket(j...) for i in iter, j in iter] end diff --git a/src/outerproduct.jl b/src/outerproduct.jl index 74152f0..164a072 100644 --- a/src/outerproduct.jl +++ b/src/outerproduct.jl @@ -5,7 +5,7 @@ type OuterProduct{P,N,S,K<:Ket,B<:Bra} <: DiracOp{P,N} scalar::S kt::K br::B - OuterProduct(scalar::S, kt::Ket{P,N}, br::Bra{P,N}) = new(scalar, kt, br) + OuterProduct{P,N,S,K,B}(scalar::S, kt::Ket{P,N}, br::Bra{P,N}) where {P,N,S,K<:Ket,B<:Bra} = new(scalar, kt, br) end OuterProduct{P,N,S}(scalar::S, kt::Ket{P,N}, br::Bra{P,N}) = OuterProduct{P,N,S,typeof(kt),typeof(br)}(scalar, kt, br) @@ -27,9 +27,9 @@ Base.promote_rule{G<:OpSum, O<:OuterProduct}(::Type{G}, ::Type{O}) = OpSum Base.eltype(op::OuterProduct) = promote_type(typeof(op.scalar), eltype(op.kt), eltype(op.br)) # these equality/hash functions are pretty inefficient... -Base.(:(==)){P,N}(a::OuterProduct{P,N}, b::OuterProduct{P,N}) = convert(OpSum, a) == convert(OpSum, b) +Base.:(==){P,N}(a::OuterProduct{P,N}, b::OuterProduct{P,N}) = convert(OpSum, a) == convert(OpSum, b) Base.hash(op::OuterProduct) = hash(convert(OpSum, op)) -Base.hash(op::OuterProduct, h::Uint64) = hash(hash(op), h) +Base.hash(op::OuterProduct, h::UInt64) = hash(hash(op), h) Base.length(op::OuterProduct) = length(op.kt)*length(op.br) @@ -95,17 +95,17 @@ tensor(a::OuterProduct, b::OuterProduct) = OuterProduct(a.scalar * b.scalar, ten ########### # Scaling # ########### -Base.scale!(c::Number, op::OuterProduct) = (op.scalar = c*op.scalar; return op) -Base.scale!(op::OuterProduct, c::Number) = (op.scalar = op.scalar*c; return op) +scale!(c::Number, op::OuterProduct) = (op.scalar = c*op.scalar; return op) +scale!(op::OuterProduct, c::Number) = (op.scalar = op.scalar*c; return op) -Base.scale(c::Number, op::OuterProduct) = OuterProduct(c * op.scalar, copy(op.kt), copy(op.br)) -Base.scale(op::OuterProduct, c::Number) = OuterProduct(op.scalar * c, copy(op.kt), copy(op.br)) +scale(c::Number, op::OuterProduct) = OuterProduct(c * op.scalar, copy(op.kt), copy(op.br)) +scale(op::OuterProduct, c::Number) = OuterProduct(op.scalar * c, copy(op.kt), copy(op.br)) ########### # + and - # ########### -Base.(:-)(op::OuterProduct) = scale(-1, op) -Base.(:+)(a::OuterProduct, b::OuterProduct) = convert(OpSum, a) + convert(OpSum, b) +Base.:-(op::OuterProduct) = scale(-1, op) +Base.:+(a::OuterProduct, b::OuterProduct) = convert(OpSum, a) + convert(OpSum, b) ################# # Normalization # diff --git a/src/state.jl b/src/state.jl index 46fedc3..ad7179f 100644 --- a/src/state.jl +++ b/src/state.jl @@ -1,13 +1,13 @@ ########### # Ket/Bra # ########### -typealias StateDict{N,T} Dict{StateLabel{N},T} +StateDict{N,T} = Dict{StateLabel{N},T} type Ket{P,N,T} <: DiracState{P,N} ptype::P dict::StateDict{N,T} - Ket(ptype, dict) = new(ptype, dict) - Ket(ptype, dict::StateDict{0}) = error("Cannot construct a 0-factor state.") + Ket{P,N,T}(ptype, dict) where {P,N,T} = new(ptype, dict) + Ket{P,N,T}(ptype, dict::StateDict{0}) where {P,N,T} = error("Cannot construct a 0-factor state.") end Ket{P,N,T}(ptype::P, dict::StateDict{N,T}) = Ket{P,N,T}(ptype, dict) @@ -44,10 +44,10 @@ Base.copy(br::Bra) = Bra(copy(br.kt)) Base.similar(kt::Ket, d=similar(dict(kt)); P=ptype(kt)) = Ket(P, d) Base.similar(br::Bra, d=similar(dict(br)); P=ptype(br)) = Bra(P, d) -Base.(:(==)){P,N}(a::Ket{P,N}, b::Ket{P,N}) = ptype(a) == ptype(b) && dict(filternz(a)) == dict(filternz(b)) -Base.(:(==)){P,N}(a::Bra{P,N}, b::Bra{P,N}) = a.kt == b.kt +Base.:(==){P,N}(a::Ket{P,N}, b::Ket{P,N}) = ptype(a) == ptype(b) && dict(filternz(a)) == dict(filternz(b)) +Base.:(==){P,N}(a::Bra{P,N}, b::Bra{P,N}) = a.kt == b.kt Base.hash(s::DiracState) = hash(dict(filternz(s)), hash(ptype(s))) -Base.hash(s::DiracState, h::Uint64) = hash(hash(s), h) +Base.hash(s::DiracState, h::UInt64) = hash(hash(s), h) Base.length(s::DiracState) = length(dict(s)) @@ -115,7 +115,7 @@ function inner{P,N,T1,T2}(br::Bra{P,N,T1}, kt::Ket{P,N,T2}) for (b,c) in dict(br), (k,v) in dict(kt) result += inner_mul(c',v,prodtype,b,k) end - return result + return result end function ortho_inner(a::DiracState{KroneckerDelta}, b::DiracState{KroneckerDelta}) @@ -136,7 +136,7 @@ function inner{N}(br::Bra{KroneckerDelta,N}, kt::Ket{KroneckerDelta,N}) end end -Base.(:*)(br::Bra, kt::Ket) = inner(br,kt) +Base.:*(br::Bra, kt::Ket) = inner(br,kt) inner_eval(f, s::DiracState) = mapcoeffs(x->inner_eval(f,x),s) @@ -163,31 +163,33 @@ end ########### # Scaling # ########### -Base.scale!(k::Ket, c::Number) = (dscale!(dict(k), c); return k) -Base.scale!(c::Number, k::Ket) = scale!(k,c) -Base.scale!(b::Bra, c::Number) = Bra(scale!(b.kt, c')) -Base.scale!(c::Number, b::Bra) = scale!(b,c) +scale!(k::Ket, c::Number) = (dscale!(dict(k), c); return k) +scale!(c::Number, k::Ket) = scale!(k,c) +scale!(b::Bra, c::Number) = Bra(scale!(b.kt, c')) +scale!(c::Number, b::Bra) = scale!(b,c) + +# See #15258 in JuliaLang/julia -Base.scale(k::Ket, c::Number) = similar(k, dscale(dict(k), c)) -Base.scale(c::Number, k::Ket) = scale(k,c) -Base.scale(b::Bra, c::Number) = Bra(scale(b.kt, c')) -Base.scale(c::Number, b::Bra) = scale(b,c) +scale(k::Ket, c::Number) = similar(k, dscale(dict(k), c)) +scale(c::Number, k::Ket) = k * c +scale(b::Bra, c::Number) = Bra(b.kt* (c')) +scale(c::Number, b::Bra) = b * c -Base.(:*)(c::Number, s::DiracState) = scale(c, s) -Base.(:*)(s::DiracState, c::Number) = scale(s, c) -Base.(:/)(s::DiracState, c::Number) = scale(s, 1/c) +Base.:*(c::Number, s::DiracState) = scale(c, s) +Base.:*(s::DiracState, c::Number) = scale(s, c) +Base.:/(s::DiracState, c::Number) = scale(s, 1/c) ########### # + and - # ########### -Base.(:-){P,N}(kt::Ket{P,N}) = -1 * kt -Base.(:-)(br::Bra) = Bra(-br.kt) +Base.:-{P,N}(kt::Ket{P,N}) = -1 * kt +Base.:-(br::Bra) = Bra(-br.kt) -Base.(:+){P,N}(a::Ket{P,N}, b::Ket{P,N}) = similar(b, add_merge(dict(a), dict(b))) -Base.(:-){P,N}(a::Ket{P,N}, b::Ket{P,N}) = similar(b, sub_merge(dict(a), dict(b))) +Base.:+{P,N}(a::Ket{P,N}, b::Ket{P,N}) = similar(b, add_merge(dict(a), dict(b))) +Base.:-{P,N}(a::Ket{P,N}, b::Ket{P,N}) = similar(b, sub_merge(dict(a), dict(b))) -Base.(:+)(a::Bra, b::Bra) = Bra(a.kt + b.kt) -Base.(:-)(a::Bra, b::Bra) = Bra(a.kt - b.kt) +Base.:+(a::Bra, b::Bra) = Bra(a.kt + b.kt) +Base.:-(a::Bra, b::Bra) = Bra(a.kt - b.kt) ########## # tensor # @@ -195,15 +197,15 @@ Base.(:-)(a::Bra, b::Bra) = Bra(a.kt - b.kt) tensor{P}(a::Ket{P}, b::Ket{P}) = Ket(ptype(b), tensordict(dict(a), dict(b))) tensor(a::Bra, b::Bra) = tensor(a.kt, b.kt)' -Base.(:*)(a::Ket, b::Ket) = tensor(a,b) -Base.(:*)(a::Bra, b::Bra) = tensor(a,b) +Base.:*(a::Ket, b::Ket) = tensor(a,b) +Base.:*(a::Bra, b::Bra) = tensor(a,b) ################# # Normalization # ################# Base.norm(s::DiracState) = sqrt(sum(abs2, values(dict(s)))) -normalize(s::DiracState) = (1/norm(s))*s -normalize!(s::DiracState) = scale!(1/norm(s), s) +QuDirac.normalize(s::DiracState) = (1/norm(s))*s +QuDirac.normalize!(s::DiracState) = scale!(1/norm(s), s) ######################## # Misc. Math Functions # @@ -287,4 +289,4 @@ export Ket, lower, raise, act_on, - inner_eval \ No newline at end of file + inner_eval diff --git a/src/str_macros.jl b/src/str_macros.jl index f358217..5928644 100644 --- a/src/str_macros.jl +++ b/src/str_macros.jl @@ -63,12 +63,12 @@ end immutable OpDefExpr op_sym::Symbol - label_args::Union(Symbol, Expr) + label_args::Symbol lhs_type::Symbol - rhs::Union(Symbol, Expr) + rhs::Symbol end -OpDefExpr(ods::OpDefStr) = OpDefExpr(symbol(ods.op_name), parse(ods.label_args), symbol(ods.lhs_type), parse(ods.rhs)) +OpDefExpr(ods::OpDefStr) = OpDefExpr(Symbol(ods.op_name), Symbol(parse(ods.label_args)), Symbol(ods.lhs_type), Symbol(parse(ods.rhs))) rm_whspace(str) = join(split(str, r"\s")) @@ -97,18 +97,18 @@ end macro def_op(str) result_expr = def_op_expr(OpDefStr(str)) return esc(result_expr) -end +end function def_op_expr(ods::OpDefStr) odex = OpDefExpr(ods) if isa(odex.label_args, Expr) - func_on_label_def = quote + func_on_label_def = quote local func_on_args($(odex.label_args.args...)) = $(odex.rhs) local func_on_label(label::StateLabel) = func_on_args(label...) end else # isa(label_expr, Symbol) - func_on_label_def = quote + func_on_label_def = quote local func_on_args($(odex.label_args)) = $(odex.rhs) local func_on_label(label::StateLabel) = func_on_args(first(label)) end @@ -123,7 +123,7 @@ function def_op_expr(ods::OpDefStr) function func_on_pair(pair::Tuple) label, c = pair return $(coeff) * func_on_label(label) - end + end $(odex.op_sym)(state::$(odex.lhs_type)) = sum(func_on_pair, QuDirac.dict(state)) end @@ -140,7 +140,7 @@ coeff_sym(odex::OpDefExpr) = odex.lhs_type == :Ket ? :c : :(c') macro rep_op(str, bases...) result_expr = rep_op_expr(OpDefStr(str), build_prod_basis(bases...)) return esc(result_expr) -end +end build_prod_basis(basis) = basis build_prod_basis(first, bases...) = :(Iterators.product($first, $(bases...))) @@ -157,12 +157,12 @@ end function gen_ket_repr_expr(odex::OpDefExpr, basis) if isa(odex.label_args, Expr) - ex = quote + ex = quote local func_on_args($(odex.label_args.args...)) = $(odex.rhs) * bra($(odex.label_args.args...)) $(odex.op_sym) = sum(args->func_on_args(args...), $basis) end else - ex = quote + ex = quote $(odex.op_sym) = sum($(odex.label_args) -> $(odex.rhs) * bra($(odex.label_args)), $basis) end end @@ -171,12 +171,12 @@ end function gen_bra_repr_expr(odex::OpDefExpr, basis) if isa(odex.label_args, Expr) - ex = quote + ex = quote local func_on_args($(odex.label_args.args...)) = ket($(odex.label_args.args...)) * $(odex.rhs) $(odex.op_sym) = sum(args->func_on_args(args...), $basis) end else - ex = quote + ex = quote $(odex.op_sym) = sum($(odex.label_args) -> ket($(odex.label_args)) * $(odex.rhs), $basis) end end @@ -186,4 +186,4 @@ end export @d_str, @d_mstr, @def_op, - @rep_op \ No newline at end of file + @rep_op diff --git a/test/generaltests.jl b/test/generaltests.jl index 3d1b1e8..533e124 100644 --- a/test/generaltests.jl +++ b/test/generaltests.jl @@ -19,7 +19,7 @@ op_copy[3,0] = 32+im @assert op_copy[3,0] == 32+im @assert tensor(op_copy, op_copy')[(3,1),(1,2)] == 120 -@test_approx_eq norm(qubits) 1 +@test norm(qubits) ≈ 1 @assert ptrace(belldens, 1) == ptrace(belldens, 2) @assert d" act_on(< 1 |, | 'a','b','c' >, 2) == < 1 | 'b' >| 'a','c' > " diff --git a/test/orthotests.jl b/test/orthotests.jl index c4bf9a5..614daf3 100644 --- a/test/orthotests.jl +++ b/test/orthotests.jl @@ -7,16 +7,16 @@ @assert b*k == 56 - 28im @assert b*op*k == 2352 - 3136im -@test_approx_eq qubits'*qubits 1 -@test_approx_eq norm(ptrace(bitdens, 2)) 1 -@test_approx_eq trace(ptrace(bitdens, 2)) 1 -@test_approx_eq trace(ptrace(belldens, 1)^2) .5 -@test_approx_eq purity(bell) 1 +@test qubits'*qubits ≈ 1 +@test norm(ptrace(bitdens, 2)) ≈ 1 +@test trace(ptrace(bitdens, 2)) ≈ 1 +@test trace(ptrace(belldens, 1)^2) ≈ .5 +@test purity(bell) ≈ 1 @rep_op " H | n > = 1/√2 * ( | 0 > + (-1)^n * | 1 > )" 0:1 @assert matrep(H, 0:1) == 1/√2 * [1 1 ; 1 -1] m = 0.5 * [1 1;1 -1] -@test_approx_eq matrep(tensor(H, H), 0:1, 0:1) [m m ; m -m] +@test matrep(tensor(H, H), 0:1, 0:1) ≈ [m m ; m -m] @assert ptrace(ptrace(bitdens, 2), 1) == ptrace(ptrace(bitdens, 1), 2)