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

Update generated self-energy in the GV module #147

Merged
merged 8 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from 7 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
22 changes: 11 additions & 11 deletions src/backend/static.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ function _to_static(::Type{ComputationalGraphs.Power{N}}, subgraphs::Vector{Feyn
end

"""
function to_julia_str(graphs::AbstractVector{G}; root::AbstractVector{Int}=[g.id for g in graphs], name::String="eval_graph!") where {G<:AbstractGraph}
function to_julia_str(graphs::AbstractVector{<:AbstractGraph}; root::AbstractVector{Int}=[g.id for g in graphs], name::String="eval_graph!")

Compile a list of graphs into a string for a julia static function. The function takes two arguments: `root` and `leaf`.
`root` is a vector of the root node ids of the graphs, and `leaf` is a vector of the leaf nodes' weights of the graphs.
"""
function to_julia_str(graphs::AbstractVector{G}; root::AbstractVector{Int}=[g.id for g in graphs], name::String="eval_graph!") where {G<:AbstractGraph}
function to_julia_str(graphs::AbstractVector{<:AbstractGraph}; root::AbstractVector{Int}=[g.id for g in graphs], name::String="eval_graph!")
head = "function $name(root::AbstractVector, leaf::AbstractVector)\n "
body = ""
leafidx = 1
Expand Down Expand Up @@ -91,8 +91,8 @@ function to_julia_str(graphs::AbstractVector{G}; root::AbstractVector{Int}=[g.id
end

"""
function to_julia_str(graphs::AbstractVector{G}, leafMap::Dict{Int,Int}; root::AbstractVector{Int}=[g.id for g in graphs],
name::String="eval_graph!") where {G<:AbstractGraph}
function to_julia_str(graphs::AbstractVector{<:AbstractGraph}, leafMap::Dict{Int,Int}; root::AbstractVector{Int}=[g.id for g in graphs],
name::String="eval_graph!")

Compile a list of Feynman graphs into a string for a julia static function. The complied function takes two arguments: `root` and `leafVal`.
`root` is a vector of the root node ids of the graphs, and `leafVal` is a vector of the leaf nodes' weights of the graphs.
Expand All @@ -103,8 +103,8 @@ Compile a list of Feynman graphs into a string for a julia static function. The
- `root` (AbstractVector{Int}, optional): The vector of the root node ids of the graphs (defaults to `[g.id for g in graphs]`).
- `name` (String,optional): The name of the complied function (defaults to `"eval_graph!"`).
"""
function to_julia_str(graphs::AbstractVector{G}, leafMap::Dict{Int,Int}; root::AbstractVector{Int}=[g.id for g in graphs],
name::String="eval_graph!") where {G<:AbstractGraph}
function to_julia_str(graphs::AbstractVector{<:AbstractGraph}, leafMap::Dict{Int,Int}; root::AbstractVector{Int}=[g.id for g in graphs],
name::String="eval_graph!")
head = "function $name(root::AbstractVector, leafVal::AbstractVector)\n "
body = ""
inds_visitedleaf = Int[]
Expand Down Expand Up @@ -138,7 +138,7 @@ function to_julia_str(graphs::AbstractVector{G}, leafMap::Dict{Int,Int}; root::A
end

"""
function compile(graphs::AbstractVector{G}; root::AbstractVector{Int}=[g.id for g in graphs]) where {G<:AbstractGraph}
function compile(graphs::AbstractVector{<:AbstractGraph}; root::AbstractVector{Int}=[g.id for g in graphs])

Compile a list of graphs into a julia static function.
The function takes two arguments: `root` and `leaf`. `root` is a vector of the root node ids of the graphs, and `leaf` is a vector of the leaf node ids of the graphs.
Expand All @@ -159,16 +159,16 @@ leaf = [1.0, 2.0]
@assert eval_graph!(root, leaf) ≈ (leaf[1] + leaf[2]) * factor
```
"""
function compile(graphs::AbstractVector{G};
root::AbstractVector{Int}=[g.id for g in graphs]) where {G<:AbstractGraph}
function compile(graphs::AbstractVector{<:AbstractGraph};
root::AbstractVector{Int}=[g.id for g in graphs])
# this function return a runtime generated function defined by compile()
func_string = to_julia_str(graphs; root=root, name="func_name!")
func_expr = Meta.parse(func_string)
return @RuntimeGeneratedFunction(func_expr)
end

function compile(graphs::AbstractVector{G}, leafMap::Dict{Int,Int};
root::AbstractVector{Int}=[g.id for g in graphs]) where {G<:AbstractGraph}
function compile(graphs::AbstractVector{<:AbstractGraph}, leafMap::Dict{Int,Int};
root::AbstractVector{Int}=[g.id for g in graphs])
# this function return a runtime generated function defined by compile()
func_string = to_julia_str(graphs, leafMap; root=root, name="func_name!")
func_expr = Meta.parse(func_string)
Expand Down
6 changes: 3 additions & 3 deletions src/computational_graph/abstractgraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ Base.show(io::IO, ::Type{Power{N}}) where {N} = print(io, "^$N")
# Is the unary form of operator 𝓞 trivial: 𝓞(G) ≡ G?
# NOTE: this property implies that 𝓞(c * G) = c * G = c * 𝓞(G), so
# we may propagate the subgraph factor c up to the parent graph.
unary_istrivial(::Type{O}) where {O<:AbstractOperator} = false
unary_istrivial(::Type{O}) where {O<:Union{Sum,Prod}} = true # (+g) ≡ g and (*g) ≡ g
unary_istrivial(::Type{<:AbstractOperator}) = false
unary_istrivial(::Type{<:Union{Sum,Prod}}) = true # (+g) ≡ g and (*g) ≡ g

# Is the operation associative: a 𝓞 (b 𝓞 c) = (a 𝓞 b) 𝓞 c = a 𝓞 b 𝓞 c?
isassociative(::Type{O}) where {O<:AbstractOperator} = false
isassociative(::Type{<:AbstractOperator}) = false
isassociative(::Type{Sum}) = true
# NOTE: Associativity of Prod (graph composition)
# requires Base.*(g1, g2) and Base./(g1, g2)
Expand Down
46 changes: 23 additions & 23 deletions src/computational_graph/feynmangraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ struct GenericDiag <: DiagramType end

# Members:
- `diagtype::DataType` classification of the Feynman diagram. Should be one of the following supported DiagramTypes: Interaction, ExternalVertex, Propagator, SelfEnergy, VertexDiag, GreenDiag, or GenericDiag.
- `orders::Vector{Int}` orders of the diagram, e.g. loop order, derivative order, etc.
- `vertices::Vector{OperatorProduct}` vertices of the diagram. Each index is composited by the product of quantum operators.
- `topology::Vector{Vector{Int}}` topology of the diagram. Each Vector{Int} stores vertices' index connected with each other (as a propagator).
- `external_indices::Vector{Int}` indices of actual external vertices in terms of QuantumOperators
Expand All @@ -23,7 +22,6 @@ struct GenericDiag <: DiagramType end
# TODO: add additional properties, e.g., isconnected::Bool and isreducible::Bool
mutable struct FeynmanProperties
diagtype::DataType # :propagator, :interaction, :sigma, :green, :generic, ...
orders::Vector{Int}
vertices::Vector{OperatorProduct}
topology::Vector{Vector{Int}}
external_indices::Vector{Int}
Expand All @@ -43,7 +41,7 @@ Base.:(==)(a::FeynmanProperties, b::FeynmanProperties) = Base.isequal(a, b)

Returns a copy of the given FeynmanProperties `p` modified to have no topology.
"""
drop_topology(p::FeynmanProperties) = FeynmanProperties(p.diagtype, p.orders, p.vertices, [], p.external_indices, p.external_legs)
drop_topology(p::FeynmanProperties) = FeynmanProperties(p.diagtype, p.vertices, [], p.external_indices, p.external_legs)

"""
mutable struct FeynmanGraph{F,W}
Expand All @@ -53,6 +51,7 @@ drop_topology(p::FeynmanProperties) = FeynmanProperties(p.diagtype, p.orders, p.
# Members:
- `id::Int` the unique hash id to identify the diagram
- `name::Symbol` name of the diagram
- `orders::Vector{Int}` orders associated with the Feynman graph, e.g., loop/derivative orders
- `properties::FeynmanProperties` diagrammatic properties, e.g., the operator vertices and topology
- `subgraphs::Vector{FeynmanGraph{F,W}}` vector of sub-diagrams
- `subgraph_factors::Vector{F}` scalar multiplicative factors associated with each subdiagram
Expand All @@ -75,6 +74,7 @@ julia> g = FeynmanGraph([g1,g2]; vertices=[𝑓⁺(1),𝑓⁻(2),𝑓⁺(3),𝑓
mutable struct FeynmanGraph{F,W} <: AbstractGraph # FeynmanGraph
id::Int
name::String # "" by default
orders::Vector{Int}
properties::FeynmanProperties

subgraphs::Vector{FeynmanGraph{F,W}}
Expand All @@ -101,7 +101,7 @@ mutable struct FeynmanGraph{F,W} <: AbstractGraph # FeynmanGraph
- `name` name of the diagram
- `diagtype::DiagramType` type of the diagram
- `operator::AbstractOperator` node operation, Sum, Prod, etc.
- `orders` orders of the diagram
- `orders` orders associated with the Feynman graph, e.g., loop/derivative orders
- `ftype` typeof(factor)
- `wtype` typeof(weight)
- `factor` overall scalar multiplicative factor for this diagram (e.g., permutation sign)
Expand All @@ -119,8 +119,8 @@ mutable struct FeynmanGraph{F,W} <: AbstractGraph # FeynmanGraph
if isnothing(vertices)
vertices = [external_operators(g) for g in subgraphs if diagram_type(g) != Propagator]
end
properties = FeynmanProperties(typeof(diagtype), orders, vertices, topology, external_indices, external_legs)
return new{ftype,wtype}(uid(), name, properties, subgraphs, subgraph_factors, typeof(operator), factor, weight)
properties = FeynmanProperties(typeof(diagtype), vertices, topology, external_indices, external_legs)
return new{ftype,wtype}(uid(), name, orders, properties, subgraphs, subgraph_factors, typeof(operator), factor, weight)
end

"""
Expand All @@ -143,14 +143,14 @@ mutable struct FeynmanGraph{F,W} <: AbstractGraph # FeynmanGraph
"""
function FeynmanGraph(subgraphs::AbstractVector, properties::FeynmanProperties;
subgraph_factors=one.(eachindex(subgraphs)), name="", operator::AbstractOperator=Sum(),
ftype=_dtype.factor, wtype=_dtype.weight, factor=one(ftype), weight=zero(wtype)
orders=zeros(Int, 16), ftype=_dtype.factor, wtype=_dtype.weight, factor=one(ftype), weight=zero(wtype)
)
@assert length(properties.external_indices) == length(properties.external_legs)
if typeof(operator) <: Power
@assert length(subgraphs) == 1 "FeynmanGraph with Power operator must have one and only one subgraph."
end
# @assert allunique(subgraphs) "all subgraphs must be distinct."
return new{ftype,wtype}(uid(), name, properties, subgraphs, subgraph_factors, typeof(operator), factor, weight)
return new{ftype,wtype}(uid(), name, orders, properties, subgraphs, subgraph_factors, typeof(operator), factor, weight)
end
end

Expand All @@ -171,56 +171,56 @@ is_internal(g::FeynmanGraph, i::Int) = (i in g.properties.external_indices) == f
"""
function diagram_type(g::FeynmanGraph)

Return the diagram type (::DiagramType) of FeynmanGraph `g`.
Returns the diagram type (::DiagramType) of FeynmanGraph `g`.
"""
diagram_type(g::FeynmanGraph) = g.properties.diagtype

"""
function orders(g::FeynmanGraph)

Return the derivative orders (::Vector{Int}) of FeynmanGraph `g`.
Returns the loop/derivative orders (::Vector{Int}) of FeynmanGraph `g`.
"""
orders(g::FeynmanGraph) = g.properties.orders
orders(g::FeynmanGraph) = g.orders

"""
function vertices(g::FeynmanGraph)

Return all vertices (::Vector{OperatorProduct}) of FeynmanGraph `g`.
Returns all vertices (::Vector{OperatorProduct}) of FeynmanGraph `g`.
"""
vertices(g::FeynmanGraph) = g.properties.vertices

"""
function topology(g::FeynmanGraph)

Return the topology (::Vector{Vector{Int}}) of FeynmanGraph `g`.
Returns the topology (::Vector{Vector{Int}}) of FeynmanGraph `g`.
"""
topology(g::FeynmanGraph) = g.properties.topology

"""
function external_legs(g::FeynmanGraph)

Return a list of Boolean indices external_legs (::Vector{Bool}) indicating which external vertices of FeynmanGraph `g` have real legs (true: real leg, false: fake leg).
Returns a list of Boolean indices external_legs (::Vector{Bool}) indicating which external vertices of FeynmanGraph `g` have real legs (true: real leg, false: fake leg).
"""
external_legs(g::FeynmanGraph) = g.properties.external_legs

"""
function external_indices(g::FeynmanGraph)

Return a list of indices (::Vector{Int}}) to the external vertices of the FeynmanGraph `g`.
Returns a list of indices (::Vector{Int}}) to the external vertices of the FeynmanGraph `g`.
"""
external_indices(g::FeynmanGraph) = g.properties.external_indices

"""
function external_operators(g::FeynmanGraph)

Return all physical external operators (::OperatorProduct}) of FeynmanGraph `g`.
Returns all physical external operators (::OperatorProduct}) of FeynmanGraph `g`.
"""
external_operators(g::FeynmanGraph) = OperatorProduct(OperatorProduct(g.properties.vertices)[g.properties.external_indices])

"""
function external_labels(g::FeynmanGraph)

Return the labels of all physical external vertices of FeynmanGraph `g`.
Returns the labels of all physical external vertices of FeynmanGraph `g`.
"""
external_labels(g::FeynmanGraph) = [o.label for o in external_operators(g)]

Expand All @@ -246,7 +246,7 @@ end
- `c2` scalar multiple
"""
function Base.:*(g1::FeynmanGraph{F,W}, c2::C) where {F,W,C}
g = FeynmanGraph([g1,], g1.properties; subgraph_factors=[F(c2),], operator=Prod(), ftype=F, wtype=W)
g = FeynmanGraph([g1,], g1.properties; subgraph_factors=[F(c2),], operator=Prod(), orders=orders(g1), ftype=F, wtype=W)
# Merge multiplicative link
if g1.operator == Prod && onechild(g1)
g.subgraph_factors[1] *= g1.subgraph_factors[1]
Expand All @@ -265,7 +265,7 @@ end
- `g2` Feynman graph
"""
function Base.:*(c1::C, g2::FeynmanGraph{F,W}) where {F,W,C}
g = FeynmanGraph([g2,], g2.properties; subgraph_factors=[F(c1),], operator=Prod(), ftype=F, wtype=W)
g = FeynmanGraph([g2,], g2.properties; subgraph_factors=[F(c1),], operator=Prod(), orders=orders(g2), ftype=F, wtype=W)
# Merge multiplicative link
if g2.operator == Prod && onechild(g2)
g.subgraph_factors[1] *= g2.subgraph_factors[1]
Expand All @@ -292,7 +292,7 @@ function linear_combination(g1::FeynmanGraph{F,W}, g2::FeynmanGraph{F,W}, c1::C=
@assert Set(external_operators(g1)) == Set(external_operators(g2)) "g1 and g2 have different external vertices."
empty_topology = [] # No topology for Sum nodes
total_vertices = union(vertices(g1), vertices(g2))
properties = FeynmanProperties(diagram_type(g1), orders(g1), total_vertices, empty_topology, external_indices(g1), external_legs(g1))
properties = FeynmanProperties(diagram_type(g1), total_vertices, empty_topology, external_indices(g1), external_legs(g1))

subgraphs = [g1, g2]
subgraph_factors = [F(c1), F(c2)]
Expand All @@ -310,7 +310,7 @@ function linear_combination(g1::FeynmanGraph{F,W}, g2::FeynmanGraph{F,W}, c1::C=
if subgraphs[1] == subgraphs[2]
g = FeynmanGraph([subgraphs[1]], properties; subgraph_factors=[sum(subgraph_factors)], operator=Sum(), ftype=F, wtype=W)
else
g = FeynmanGraph(subgraphs, properties; subgraph_factors=subgraph_factors, operator=Sum(), ftype=F, wtype=W)
g = FeynmanGraph(subgraphs, properties; subgraph_factors=subgraph_factors, operator=Sum(), orders=orders(g1), ftype=F, wtype=W)
end
return g
end
Expand Down Expand Up @@ -341,7 +341,7 @@ function linear_combination(graphs::Vector{FeynmanGraph{F,W}}, constants::Vector
g1 = graphs[1]
empty_topology = [] # No topology for Sum nodes
total_vertices = union(Iterators.flatten(vertices.(graphs)))
properties = FeynmanProperties(diagram_type(g1), orders(g1), total_vertices, empty_topology, external_indices(g1), external_legs(g1))
properties = FeynmanProperties(diagram_type(g1), total_vertices, empty_topology, external_indices(g1), external_legs(g1))

subgraphs, subgraph_factors = graphs, constants
# Convert multiplicative links to in-place form
Expand All @@ -363,7 +363,7 @@ function linear_combination(graphs::Vector{FeynmanGraph{F,W}}, constants::Vector
end
end

g = FeynmanGraph(unique_graphs, properties; subgraph_factors=unique_factors, operator=Sum(), ftype=F, wtype=W)
g = FeynmanGraph(unique_graphs, properties; subgraph_factors=unique_factors, operator=Sum(), orders=orders(g1), ftype=F, wtype=W)
return g
end

Expand Down
Loading