Skip to content

Commit 606823a

Browse files
committed
Draft new indexed cnumbers implementation
1 parent 944cc40 commit 606823a

File tree

4 files changed

+170
-120
lines changed

4 files changed

+170
-120
lines changed

src/QuantumCumulants.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export HilbertSpace, ProductSpace, ⊗, tensor,
3535
ClusterSpace,
3636
scale,
3737
transition_superscript,
38-
Index, reorder, IndexedOperator, IndexedVariable, DoubleIndexedVariable,
38+
Index, reorder, IndexedOperator, IndexedVariable, DoubleIndexedVariable, IndexedParameter,
3939
Sum, Σ, change_index, has_index,
4040
# DoubleSum, indexed_complete, IndexedCorrelationFunction, scale_term,
4141
# scaleME, evalME, indexed_complete!, indexed_meanfield, subst_reds, AvgSums, plotME,

src/indexing.jl

+163-113
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ struct IndexedVariable <: CNumber #just a symbol, that can be manipulated via th
7070
end
7171
end
7272

73+
# TODO: deprecate IndexedVariable and DoubelIndexedVariable
74+
7375
"""
7476
DoubleIndexedVariable <: CNumber
7577
DoubleIndexedVariable(name::Symbol,ind1::Index,ind2::Index;identical::Bool)
@@ -92,7 +94,7 @@ struct DoubleIndexedVariable <: CNumber #just a symbol, that can be manipulated
9294
ind2::Index
9395
identical::Bool
9496
function DoubleIndexedVariable(name,ind1,ind2;identical::Bool=true)
95-
if !(identical) && (ind1 == ind2)
97+
if !(identical) && isequal(ind1, ind2)
9698
return 0
9799
end
98100
metadata = new(name,ind1,ind2,identical)
@@ -102,6 +104,43 @@ struct DoubleIndexedVariable <: CNumber #just a symbol, that can be manipulated
102104
end
103105
end
104106

107+
struct IndexedParameterSym <: CNumber end
108+
const SymbolicIndexedParameter = SymbolicUtils.BasicSymbolic{<:IndexedParameterSym}
109+
const sym_idx_parameter = begin
110+
T = SymbolicUtils.FnType{Tuple{Complex{Real}, Vector{<:Index}}, IndexedParameterSym}
111+
SymbolicUtils.Sym{T}(:getindex_parameter)
112+
end
113+
SymbolicUtils.symtype(::T) where T <: SymbolicIndexedParameter = IndexedParameterSym
114+
115+
function IndexedParameter(name::Symbol, indices::Vector{Index})
116+
return SymbolicUtils.Term{IndexedParameterSym}(sym_idx_parameter, [Parameter(name), indices])
117+
end
118+
IndexedParameter(name::Symbol, index::Index) = IndexedParameter(name, [index])
119+
IndexedParameter(name::Symbol, indices::Index...) = IndexedParameter(name, [indices...])
120+
IndexedParameter(name::Symbol) = (args...) -> IndexedParameter(name, args...)
121+
122+
# TermInterface
123+
# TermInterface.iscall(::IndexedParameter) = true
124+
# TermInterface.arguments(x::IndexedParameter) = x.indices
125+
# TermInterface.operation(x::IndexedParameter) = IndexedParameter(x.name)
126+
# TermInterface.maketerm(::Type{<:IndexedParameter}, ::typeof(IndexedParameter), args, metadata) = IndexedParameter(args..., metadata)
127+
128+
# function Base.isequal(pi::IndexedParameter, pj::IndexedParameter)
129+
# if !isequal(pi.name, pj.name)
130+
# return false
131+
# end
132+
133+
# if !isequal(length(pi.indices), length(pj.indices))
134+
# return false
135+
# end
136+
137+
# for (i, j) in zip(pi.indices, pj.indices)
138+
# isequal(i, j) || return false
139+
# end
140+
141+
# return true
142+
# end
143+
105144
"""
106145
IndexedOperator <: QSym
107146
IndexedOperator(op::Union{Transition,Create,Destroy},ind::Index)
@@ -188,7 +227,7 @@ function Base.:*(a::IndexedOperator{<:Transition}, b::IndexedOperator{<:Transiti
188227
else
189228
t2 = QMul(1, [a_copy, b_copy])
190229
end
191-
return t1 * (i == j) + (1 - i == j) * t2
230+
return t1 * (i == j) + (1 - (i == j)) * t2
192231
end
193232
elseif aon_a < aon_b
194233
return QMul(1, [a,b])
@@ -309,7 +348,15 @@ Examples
309348
310349
311350
"""
312-
change_index(x,from::Index,to::Index) = x
351+
change_index(x, from::Index, to::Index) = x
352+
353+
function change_index(t::SymbolicUtils.Symbolic, from::Index, to::Index)
354+
isequal(from, to) || !TermInterface.iscall(t) && return t
355+
356+
f = SymbolicUtils.operation(t)
357+
args = SymbolicUtils.arguments(t)
358+
return f(change_index(args, from, to)...)
359+
end
313360

314361
function change_index(a::IndexedOperator, from::Index, to::Index)
315362
if !isequal(a.ind, from)
@@ -337,130 +384,133 @@ function change_index(v::DoubleIndexedVariable, from::Index, to::Index)
337384
return v
338385
end
339386

340-
function change_index(t::SymbolicUtils.Symbolic, from::Index, to::Index)
341-
isequal(from, to) && return t
342-
343-
if !TermInterface.iscall(t)
344-
metadata = TermInterface.metadata(t)
345-
metadata_ = change_index(metadata.value, from, to)
346-
t_ = deepcopy(t)
347-
t_ = SymbolicUtils.setmetadata(t_, typeof(metadata_), metadata_)
348-
return t_
349-
end
387+
# function change_index(p::IndexedParameter, from::Index, to::Index)
388+
# p_ = deepcopy(p)
389+
# for i=1:length(p.indices)
390+
# if isequal(p_.indices[i], from)
391+
# p_.indices[i] = to
392+
# end
393+
# end
394+
# return p_
395+
# end
350396

351-
f = SymbolicUtils.operation(t)
352-
args = SymbolicUtils.arguments(t)
353-
return f(change_index(args, from, to))
354-
end
355397

356398
function change_index(args::Vector, from::Index, to::Index)
357399
isequal(from, to) && return args
358400

359401
return [change_index(arg, from, to) for arg in args]
360402
end
361403

362-
363-
getIndName(op::IndexedOperator) = op.ind.name
364-
getIndName(ind::Index) = ind.name
365-
getIndName(x) = Symbol()
366-
367-
# SymbolicUtils.iscall(a::SingleSum) = false
368-
# SymbolicUtils.arguments(a::SingleSum) = SymbolicUtils.arguments(a.term)
369-
# SymbolicUtils.arguments(a::IndexedOperator) = [a]
370-
371-
get_order(::IndexedOperator) = 1
372-
#It is assumed that the term for which this operation is done already commutes with indices inside the indices-Vector
373-
function order_by_index(vec::Vector,indices::Vector{Index})
374-
vec_ = copy(vec)
375-
frontfront = filter(x -> !(typeof(x) == IndexedOperator),vec_)
376-
front = filter(x -> typeof(x) == IndexedOperator && x.ind in indices,vec_)
377-
back = filter(x -> typeof(x) == IndexedOperator && x.ind indices,vec_)
378-
sort!(front,by=getIndName)
379-
return vcat(frontfront,front,back)
404+
function change_index(i::Index, from::Index, to::Index)
405+
if isequal(i, from)
406+
return to
407+
else
408+
return i
409+
end
380410
end
381-
order_by_index(qmul::QMul,inds::Vector{Index}) = qmul.arg_c*prod(order_by_index(qmul.args_nc,inds))
382-
order_by_index(avrg::Average,inds::Vector{Index}) = order_by_index(arguments(avrg)[1],inds)
383-
order_by_index(x,inds) = x
384411

385-
#Reorder function: given a tuple vector of indices meaning for each tuple: first ≠ second
386-
#-> go through the term given and exchange 2 ops when the second has "lower" (i.e. its name is first in the alphabet) index than the first one
387-
#-> results in a term, ordered by its commutating indices
388-
"""
389-
reorder(param,indexMapping)
390-
391-
Reorders a given term (param) regarding to a given indexMapping, which specifies, which [`Index`](@ref) entities can not be equal
392-
inside the given term. reorder() creates a [`SpecialIndexedTerm`](@ref) as a result.
393-
394-
Examples
395-
========
396412

397-
reorder(σⱼ²¹ * σᵢ²¹,[(i,j)]) = σᵢ²¹ * σⱼ²¹
413+
# getIndName(op::IndexedOperator) = op.ind.name
414+
# getIndName(ind::Index) = ind.name
415+
# getIndName(x) = Symbol()
398416

399-
reorder(σⱼ²¹ * σᵢ²¹ * σⱼ¹²,[(i,j)]) = σᵢ²¹ * σⱼ²²
417+
# # SymbolicUtils.iscall(a::SingleSum) = false
418+
# # SymbolicUtils.arguments(a::SingleSum) = SymbolicUtils.arguments(a.term)
419+
# # SymbolicUtils.arguments(a::IndexedOperator) = [a]
400420

401-
"""
402-
function reorder(param::QMul,indexMapping::Vector{Tuple{Index,Index}})
403-
term = copy(param.args_nc)
404-
carg = param.arg_c
405-
indOps = []
406-
others = []
407-
for i = 1:length(term) #Split into indexed ops and non indexed ops
408-
if term[i] isa IndexedOperator
409-
push!(indOps,term[i])
410-
else
411-
push!(others,term[i])
412-
end
413-
end
414-
if isequal(carg,0) || (0 in term)
415-
return 0
416-
end
417-
finish = false
418-
while !(finish) #go over all ops ind indexed ops -> order by
419-
finish = true
420-
for i = 1:(length(indOps)-1)
421-
if ((indOps[i].ind,indOps[i+1].ind) in indexMapping || (indOps[i+1].ind,indOps[i].ind) in indexMapping) && (indOps[i+1].ind < indOps[i].ind)
422-
temp = indOps[i+1]
423-
indOps[i+1] = indOps[i]
424-
indOps[i] = temp
425-
finish = false
426-
end
427-
end
428-
end
429-
args = vcat(others,indOps)
430-
qmul = carg*prod(args)
421+
# get_order(::IndexedOperator) = 1
422+
# #It is assumed that the term for which this operation is done already commutes with indices inside the indices-Vector
423+
# function order_by_index(vec::Vector,indices::Vector{Index})
424+
# vec_ = copy(vec)
425+
# frontfront = filter(x -> !(typeof(x) == IndexedOperator),vec_)
426+
# front = filter(x -> typeof(x) == IndexedOperator && x.ind in indices,vec_)
427+
# back = filter(x -> typeof(x) == IndexedOperator && x.ind ∉ indices,vec_)
428+
# sort!(front,by=getIndName)
429+
# return vcat(frontfront,front,back)
430+
# end
431+
# order_by_index(qmul::QMul,inds::Vector{Index}) = qmul.arg_c*prod(order_by_index(qmul.args_nc,inds))
432+
# order_by_index(avrg::Average,inds::Vector{Index}) = order_by_index(arguments(avrg)[1],inds)
433+
# order_by_index(x,inds) = x
434+
435+
# #Reorder function: given a tuple vector of indices meaning for each tuple: first ≠ second
436+
# #-> go through the term given and exchange 2 ops when the second has "lower" (i.e. its name is first in the alphabet) index than the first one
437+
# #-> results in a term, ordered by its commutating indices
438+
# """
439+
# reorder(param,indexMapping)
440+
441+
# Reorders a given term (param) regarding to a given indexMapping, which specifies, which [`Index`](@ref) entities can not be equal
442+
# inside the given term. reorder() creates a [`SpecialIndexedTerm`](@ref) as a result.
443+
444+
# Examples
445+
# ========
446+
447+
# reorder(σⱼ²¹ * σᵢ²¹,[(i,j)]) = σᵢ²¹ * σⱼ²¹
448+
449+
# reorder(σⱼ²¹ * σᵢ²¹ * σⱼ¹²,[(i,j)]) = σᵢ²¹ * σⱼ²²
450+
451+
# """
452+
# function reorder(param::QMul,indexMapping::Vector{Tuple{Index,Index}})
453+
# term = copy(param.args_nc)
454+
# carg = param.arg_c
455+
# indOps = []
456+
# others = []
457+
# for i = 1:length(term) #Split into indexed ops and non indexed ops
458+
# if term[i] isa IndexedOperator
459+
# push!(indOps,term[i])
460+
# else
461+
# push!(others,term[i])
462+
# end
463+
# end
464+
# if isequal(carg,0) || (0 in term)
465+
# return 0
466+
# end
467+
# finish = false
468+
# while !(finish) #go over all ops ind indexed ops -> order by
469+
# finish = true
470+
# for i = 1:(length(indOps)-1)
471+
# if ((indOps[i].ind,indOps[i+1].ind) in indexMapping || (indOps[i+1].ind,indOps[i].ind) in indexMapping) && (indOps[i+1].ind < indOps[i].ind)
472+
# temp = indOps[i+1]
473+
# indOps[i+1] = indOps[i]
474+
# indOps[i] = temp
475+
# finish = false
476+
# end
477+
# end
478+
# end
479+
# args = vcat(others,indOps)
480+
# qmul = carg*prod(args)
431481

432-
if qmul isa QMul
433-
mapping_ = orderMapping(indexMapping)
434-
return SpecialIndexedTerm(qmul,mapping_)
435-
else
436-
return reorder(qmul,indexMapping)
437-
end
438-
end
439-
# reorder(sum::SingleSum,indexMapping::Vector{Tuple{Index,Index}}) = SingleSum(reorder(sum.term,indexMapping),sum.sum_index,sum.non_equal_indices)
440-
function reorder(term::QAdd,indexMapping::Vector{Tuple{Index,Index}})
441-
args = []
442-
for arg in arguments(term)
443-
push!(args,reorder(arg,indexMapping))
444-
end
445-
if length(args) == 0
446-
return 0
447-
end
448-
if length(args) == 1
449-
return args[1]
450-
end
451-
return +(args...)
452-
end
453-
reorder(x::IndexedOperator,indexMapping::Vector{Tuple{Index,Index}}) = SpecialIndexedTerm(x,indexMapping)
454-
reorder(x,indMap) = x
455-
456-
function orderMapping(mapping::Vector{Tuple{Index,Index}})
457-
mapping_ = Vector{Union{Missing,Tuple{Index,Index}}}(missing,length(mapping))
458-
for i = 1:length(mapping)
459-
sort_ = sort([first(mapping[i]),last(mapping[i])],by=getIndName)
460-
mapping_[i] = (sort_[1],sort_[2])
461-
end
462-
return mapping_
463-
end
482+
# if qmul isa QMul
483+
# mapping_ = orderMapping(indexMapping)
484+
# return SpecialIndexedTerm(qmul,mapping_)
485+
# else
486+
# return reorder(qmul,indexMapping)
487+
# end
488+
# end
489+
# # reorder(sum::SingleSum,indexMapping::Vector{Tuple{Index,Index}}) = SingleSum(reorder(sum.term,indexMapping),sum.sum_index,sum.non_equal_indices)
490+
# function reorder(term::QAdd,indexMapping::Vector{Tuple{Index,Index}})
491+
# args = []
492+
# for arg in arguments(term)
493+
# push!(args,reorder(arg,indexMapping))
494+
# end
495+
# if length(args) == 0
496+
# return 0
497+
# end
498+
# if length(args) == 1
499+
# return args[1]
500+
# end
501+
# return +(args...)
502+
# end
503+
# reorder(x::IndexedOperator,indexMapping::Vector{Tuple{Index,Index}}) = SpecialIndexedTerm(x,indexMapping)
504+
# reorder(x,indMap) = x
505+
506+
# function orderMapping(mapping::Vector{Tuple{Index,Index}})
507+
# mapping_ = Vector{Union{Missing,Tuple{Index,Index}}}(missing,length(mapping))
508+
# for i = 1:length(mapping)
509+
# sort_ = sort([first(mapping[i]),last(mapping[i])],by=getIndName)
510+
# mapping_[i] = (sort_[1],sort_[2])
511+
# end
512+
# return mapping_
513+
# end
464514

465515
#Show functions
466516
Base.show(io::IO, index::Index) = write(io, index.name)

src/indexing_sums.jl

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ has_index(s::Sum, i::Index) = isequal(s.index, i) || has_index(s.term, i)
3333

3434
function has_index(t::SymbolicUtils.Symbolic, i::Index)
3535
if !TermInterface.iscall(t)
36-
metadata = TermInterface.metadata(t)
37-
return has_index(metadata.value, i)
36+
return false
3837
end
3938

4039
return has_index(SymbolicUtils.arguments(t), i)

test/test_index_basic.jl

+5-4
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const qc=QuantumCumulants
5252
id = uuid4()
5353
push!(s1.merge_events, id)
5454
push!(s2.merge_events, id)
55-
@test isequal(ex, σ(2,2,i_ind)*(i_ind == j_ind) + (1 - i_ind==j_ind) * s1*s2)
55+
@test isequal(ex, σ(2,2,i_ind)*(i_ind == j_ind) + (1 - (i_ind==j_ind)) * s1*s2)
5656

5757
a = Destroy(h,:a)
5858
a_indexed(i) = IndexedOperator(a, i)
@@ -95,12 +95,13 @@ sum3 = Sum(a'*σ(1,2,i_ind) + a*σ(2,1,i_ind),i_ind)
9595
@test isequal(0,Σ(σ(2,1,i_ind)*σ(2,1,i_ind),i_ind))
9696

9797
k_ind = indT(:k)
98-
Γij = DoubleIndexedVariable(,i_ind,j_ind)
98+
Γij = IndexedParameter(,i_ind,j_ind)
99+
g = IndexedParameter(:g)
99100

100-
@test(isequal(change_index(Γij,j_ind,k_ind), DoubleIndexedVariable(,i_ind,k_ind)))
101+
@test(isequal(change_index(Γij,j_ind,k_ind), IndexedParameter(,i_ind,k_ind)))
101102
@test(isequal(change_index(σ(1,2,j_ind)*σ(1,2,i_ind),j_ind,i_ind),0))
102103
@test(isequal(change_index(g(k_ind),k_ind,j_ind),g(j_ind)))
103-
@test isequal(change_index((2g(i_ind),i_ind), i_ind, j_ind), (2g(j_ind),j_ind))
104+
@test isequal(change_index(Σ(2g(i_ind),i_ind), i_ind, j_ind), Σ(2g(j_ind),j_ind))
104105

105106
@test(isequal(
106107
order_by_index(σ(1,2,k_ind)*σ(1,2,j_ind)*σ(1,2,i_ind),[i_ind]), σ(1,2,i_ind)*σ(1,2,k_ind)*σ(1,2,j_ind)

0 commit comments

Comments
 (0)