Skip to content

Commit

Permalink
add from_coeff_map and test
Browse files Browse the repository at this point in the history
  • Loading branch information
fsxbhyy committed Nov 18, 2023
1 parent feba9f4 commit 6b959a5
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 25 deletions.
10 changes: 7 additions & 3 deletions example/taylor_expansion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ using FeynmanDiagram.Utility:
taylorexpansion!, build_derivative_backAD!, count_operation

function benchmark_AD(glist::Vector{T}) where {T<:Graph}
taylormap = Dict{Int,TaylorSeries{T}}()
#taylormap = Dict{Int,TaylorSeries{T}}()
totaloperation = [0, 0]
taylorlist = Vector{TaylorSeries{T}}()
for g in glist
@time t, taylormap = taylorexpansion!(g; taylormap=taylormap)
var_dependence = Dict{Int,Vector{Bool}}()
for leaf in FeynmanDiagram.Leaves(g)
var_dependence[leaf.id] = [true for _ in 1:get_numvars()]
end
@time t, taylormap, from_coeff_map = taylorexpansion!(g, var_dependence)


operation = count_operation(t)
totaloperation = totaloperation + operation
push!(taylorlist, t)
print("operation number: $(operation)\n")
t_compare = build_derivative_backAD!(g)
t_compare, leaftaylor = build_derivative_backAD!(g)
for (order, coeff) in (t_compare.coeffs)
@assert (eval!(coeff)) == (eval!(Taylor.taylor_factorial(order) * t.coeffs[order]))
end
Expand Down
60 changes: 42 additions & 18 deletions src/utility.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,20 @@ using ..Taylor
- `var_dependence::Dict{Int,Vector{Bool}}` A dictionary that specifies the variable dependence of target graph leaves. Should map the id of each leaf to a Bool vector.
The length of the vector should be the same as number of variables.
- `to_coeff_map::Dict{Int,TaylorSeries}` A dicitonary that maps id of each node of target graph to its correponding taylor series.
`from_coeff_map::Dict{Int,Tuple{Int,Vector{Bool}}}` A dicitonary that maps a taylor coefficient to its owner FeynmanGraph. The key should be the id of coefficient graph, and value should be a tuple of (feynmangraph.id, order).
"""
function taylorexpansion!(graph::G, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); to_coeff_map::Dict{Int,TaylorSeries{G}}=Dict{Int,TaylorSeries{G}}()) where {G<:Graph}
function taylorexpansion!(graph::G, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); to_coeff_map::Dict{Int,TaylorSeries{G}}=Dict{Int,TaylorSeries{G}}(), from_coeff_map::Dict{Int,Tuple{Int,Vector{Int}}}=Dict{Int,Tuple{Int,Vector{Int}}}()) where {G<:Graph}
if haskey(to_coeff_map, graph.id) #If already exist, use taylor series in to_coeff_map.
return to_coeff_map[graph.id], to_coeff_map
if isleaf(graph)
for (order, coeff) in to_coeff_map[graph.id].coeffs
if haskey(from_coeff_map, coeff.id)
@assert from_coeff_map[coeff.id] == (graph.id, order) "The graph g$(graph.id) is mapped to two different leaf taylor series!"
else
from_coeff_map[coeff.id] = (graph.id, order)
end
end
end
return to_coeff_map[graph.id], to_coeff_map, from_coeff_map

elseif isleaf(graph)
if haskey(var_dependence, graph.id)
Expand All @@ -48,12 +58,13 @@ function taylorexpansion!(graph::G, var_dependence::Dict{Int,Vector{Bool}}=Dict{
coeff = Graph([]; operator=ComputationalGraphs.Sum(), factor=graph.factor)
result.coeffs[o] = coeff
end
from_coeff_map[result.coeffs[o].id] = (graph.id, o)
end
to_coeff_map[graph.id] = result
return result, to_coeff_map
return result, to_coeff_map, from_coeff_map
else
to_coeff_map[graph.id] = graph.factor * apply(graph.operator, [taylorexpansion!(sub, var_dependence; to_coeff_map=to_coeff_map)[1] for sub in graph.subgraphs], graph.subgraph_factors)
return to_coeff_map[graph.id], to_coeff_map
to_coeff_map[graph.id] = graph.factor * apply(graph.operator, [taylorexpansion!(sub, var_dependence; to_coeff_map=to_coeff_map, from_coeff_map=from_coeff_map)[1] for sub in graph.subgraphs], graph.subgraph_factors)
return to_coeff_map[graph.id], to_coeff_map, from_coeff_map
end
end

Expand Down Expand Up @@ -112,10 +123,20 @@ end
- `var_dependence::Dict{Int,Vector{Bool}}` A dictionary that specifies the variable dependence of target diagram leaves. Should map the id of each leaf to a Bool vector.
The length of the vector should be the same as number of variables.
- `to_coeff_map::Dict{Int,TaylorSeries}` A dicitonary that maps id of each node of target diagram to its correponding taylor series.
`from_coeff_map::Dict{Int,Tuple{Int,Vector{Bool}}}` A dicitonary that maps a taylor coefficient to its owner FeynmanGraph. The key should be the id of coefficient graph, and value should be a tuple of (feynmangraph.id, order).
"""
function taylorexpansion!(graph::Diagram{W}, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}()) where {W}
function taylorexpansion!(graph::Diagram{W}, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}(), from_coeff_map::Dict{Int,Tuple{Int,Vector{Int}}}=Dict{Int,Tuple{Int,Vector{Int}}}()) where {W}
if haskey(to_coeff_map, graph.hash) #If already exist, use taylor series in to_coeff_map.
return to_coeff_map[graph.hash], to_coeff_map
if isempty(graph.subdiagram)
for (order, coeff) in to_coeff_map[graph.hash].coeffs
if haskey(from_coeff_map, coeff.id)
@assert from_coeff_map[coeff.id] == (graph.hash, order) "The graph g$(graph.hash) is mapped to two different leaf taylor series!"
else
from_coeff_map[coeff.id] = (graph.hash, order)
end
end
end
return to_coeff_map[graph.hash], to_coeff_map, from_coeff_map

elseif isempty(graph.subdiagram)
if haskey(var_dependence, graph.hash)
Expand All @@ -129,12 +150,13 @@ function taylorexpansion!(graph::Diagram{W}, var_dependence::Dict{Int,Vector{Boo
o = collect(order)
coeff = Graph([]; operator=ComputationalGraphs.Sum(), factor=graph.factor)
result.coeffs[o] = coeff
from_coeff_map[coeff.id] = (graph.hash, o)
end
to_coeff_map[graph.hash] = result
return result, to_coeff_map
return result, to_coeff_map, from_coeff_map
else
to_coeff_map[graph.hash] = graph.factor * apply(typeof(graph.operator), [taylorexpansion!(sub, var_dependence; to_coeff_map=to_coeff_map)[1] for sub in graph.subdiagram], ones(W, length(graph.subdiagram)))
return to_coeff_map[graph.hash], to_coeff_map
to_coeff_map[graph.hash] = graph.factor * apply(typeof(graph.operator), [taylorexpansion!(sub, var_dependence; to_coeff_map=to_coeff_map, from_coeff_map=from_coeff_map)[1] for sub in graph.subdiagram], ones(W, length(graph.subdiagram)))
return to_coeff_map[graph.hash], to_coeff_map, from_coeff_map
end
end

Expand All @@ -149,6 +171,7 @@ end
The dependence is given by a vector of the length same as the number of variables.
- `label::Tuple{LabelProduct,LabelProduct}` A Tuple fermi (first element) and bose LabelProduct (second element).
- `to_coeff_map::Dict{Int,TaylorSeries}` A dicitonary that maps id of each node of target diagram to its correponding taylor series.
`from_coeff_map::Dict{Int,Tuple{Int,Vector{Bool}}}` A dicitonary that maps a taylor coefficient to its owner FeynmanGraph. The key should be the id of coefficient graph, and value should be a tuple of (feynmangraph.id, order).
"""
function taylorexpansion!(graph::FeynmanGraph{F,W}, propagator_var::Tuple{Vector{Bool},Vector{Bool}}; to_coeff_map::Dict{Int,TaylorSeries{Graph{F,W}}}=Dict{Int,TaylorSeries{Graph{F,W}}}(), from_coeff_map::Dict{Int,Tuple{Int,Vector{Int}}}=Dict{Int,Tuple{Int,Vector{Int}}}()) where {F,W}
var_dependence = Dict{Int,Vector{Bool}}()
Expand Down Expand Up @@ -177,33 +200,34 @@ end
- `propagator_var::Dict{DataType,Vector{Bool}}` A dictionary that specifies the variable dependence of different types of diagrams. Should be a map between DataTypes in DiagramID and Bool vectors.
The dependence is given by a vector of the length same as the number of variables.
- `to_coeff_map::Dict{Int,TaylorSeries}` A dicitonary that maps id of each node of target diagram to its correponding taylor series.
- `from_coeff_map::Dict{Int,Tuple{Int,Vector{Bool}}}` A dicitonary that maps a taylor coefficient to its owner FeynmanGraph. The key should be the id of coefficient graph, and value should be a tuple of (feynmangraph.id, order).
"""
function taylorexpansion!(graph::Diagram{W}, propagator_var::Dict{DataType,Vector{Bool}}; to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}()) where {W}
function taylorexpansion!(graph::Diagram{W}, propagator_var::Dict{DataType,Vector{Bool}}; to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}(), from_coeff_map::Dict{Int,Tuple{Int,Vector{Int}}}=Dict{Int,Tuple{Int,Vector{Int}}}()) where {W}
var_dependence = Dict{Int,Vector{Bool}}()
for leaf in Leaves(graph)
if haskey(propagator_var, typeof(leaf.id))
var_dependence[leaf.hash] = [propagator_var[typeof(leaf.id)][idx] ? true : false for idx in 1:get_numvars()]
end
end
return taylorexpansion!(graph, var_dependence; to_coeff_map=to_coeff_map)
return taylorexpansion!(graph, var_dependence; to_coeff_map=to_coeff_map, from_coeff_map=from_coeff_map)
end

function taylorexpansion!(graphs::Vector{G}, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); to_coeff_map::Dict{Int,TaylorSeries{G}}=Dict{Int,TaylorSeries{G}}()) where {G<:Graph}
function taylorexpansion!(graphs::Vector{G}, var_dependence::Dict{Int,Vector{Bool}}=Dict{Int,Vector{Bool}}(); to_coeff_map::Dict{Int,TaylorSeries{G}}=Dict{Int,TaylorSeries{G}}(), from_coeff_map::Dict{Int,Tuple{Int,Vector{Int}}}=Dict{Int,Tuple{Int,Vector{Int}}}()) where {G<:Graph}
result = Vector{TaylorSeries{G}}()
for graph in graphs
taylor, _ = taylorexpansion!(graph, var_dependence; to_coeff_map=to_coeff_map)
taylor, _ = taylorexpansion!(graph, var_dependence; to_coeff_map=to_coeff_map, from_coeff_map=from_coeff_map)
push!(result, taylor)
end
return result, to_coeff_map
return result, to_coeff_map, from_coeff_map
end

function taylorexpansion!(graphs::Vector{Diagram{W}}, propagator_var::Dict{DataType,Vector{Bool}}; to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}()) where {W}
function taylorexpansion!(graphs::Vector{Diagram{W}}, propagator_var::Dict{DataType,Vector{Bool}}; to_coeff_map::Dict{Int,TaylorSeries{Graph{W,W}}}=Dict{Int,TaylorSeries{Graph{W,W}}}(), from_coeff_map::Dict{Int,Tuple{Int,Vector{Int}}}=Dict{Int,Tuple{Int,Vector{Int}}}()) where {W}
result = Vector{TaylorSeries{Graph{W,W}}}()
for graph in graphs
taylor, _ = taylorexpansion!(graph, propagator_var; to_coeff_map=to_coeff_map)
taylor, _ = taylorexpansion!(graph, propagator_var; to_coeff_map=to_coeff_map, from_coeff_map=from_coeff_map)
push!(result, taylor)
end
return result, to_coeff_map
return result, to_coeff_map, from_coeff_map
end
"""
taylorexpansion_withmap(g::G; coeffmode=true, var::Vector{Int}=collect(1:get_numvars())) where {G<:Graph}
Expand Down
27 changes: 23 additions & 4 deletions test/taylor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,13 @@ end
var_dependence[leaf.id] = [true for _ in 1:get_numvars()]
end
end
T, taylormap = taylorexpansion!(G, var_dependence)
T, taylormap, from_coeff_map = taylorexpansion!(G, var_dependence)
for leaf in Leaves(G)
t = taylormap[leaf.id]
for (order, coeff) in t.coeffs
@test from_coeff_map[coeff.id] == (leaf.id, order)
end
end
T_compare, taylormap_compare = build_derivative_backAD!(G)
leafmap1, leafvec1, leafmap2, leafvec2 = assign_random_numbers(G, taylormap, taylormap_compare)
for (order, coeff) in T_compare.coeffs
Expand All @@ -82,8 +88,13 @@ end

set_variables("x y", orders=[2, 2])
propagator_var = ([true, false], [false, true]) # Specify variable dependence of fermi (first element) and bose (second element) particles.
t, taylormap = taylorexpansion!(g[1][1], propagator_var)

t, taylormap, from_coeff_map = taylorexpansion!(g[1][1], propagator_var)
for leaf in Leaves(g[1][1])
taylor = taylormap[leaf.id]
for (order, coeff) in taylor.coeffs
@test from_coeff_map[coeff.id] == (leaf.id, order)
end
end
for (order, graph) in dict_g
if graph[2][1] == g[2][1]
idx = 1
Expand Down Expand Up @@ -206,7 +217,15 @@ end
set_variables("x y"; orders=[2, 2])

propagator_var = Dict(DiagTree.BareGreenId => [true, false], DiagTree.BareInteractionId => [false, true]) # Specify variable dependence of fermi (first element) and bose (second element) particles.
t, taylormap = taylorexpansion!(root, propagator_var)
t, taylormap, from_coeff_map = taylorexpansion!(root, propagator_var)
for leaf in PostOrderDFS(root)
if isempty(leaf.subdiagram)
taylor = taylormap[leaf.hash]
for (order, coeff) in taylor.coeffs
@test from_coeff_map[coeff.id] == (leaf.hash, order)
end
end
end
taylorleafmap, taylorleafvec = assign_leaves(root, taylormap)
@test eval!(t.coeffs[[0, 0]], taylorleafmap, taylorleafvec) root.weight
@test eval!(t.coeffs[[0, 1]], taylorleafmap, taylorleafvec) droot_dv.weight / taylor_factorial([0, 1])
Expand Down

0 comments on commit 6b959a5

Please sign in to comment.