Skip to content

Commit

Permalink
merge from master
Browse files Browse the repository at this point in the history
  • Loading branch information
houpc committed Oct 19, 2023
2 parents 17eee01 + 418f8f5 commit fde1864
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 95 deletions.
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

0 comments on commit fde1864

Please sign in to comment.