Skip to content

Commit

Permalink
Bugfix for conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
dcerkoney committed Oct 24, 2023
1 parent 6db6d5b commit 465c1ab
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/FeynmanDiagram.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export Graph, FeynmanGraph, FeynmanProperties

export isequiv, drop_topology, is_external, is_internal, diagram_type, orders, vertices, topology
export external_legs, external_indices, external_operators, external_labels
export linear_combination, feynman_diagram, propagator, interaction, external_vertex
export multi_product, linear_combination, feynman_diagram, propagator, interaction, external_vertex
# export DiagramType, Interaction, ExternalVertex, Propagator, SelfEnergy, VertexDiag, GreenDiag, GenericDiag

# export standardize_order!
Expand Down
2 changes: 1 addition & 1 deletion src/computational_graph/ComputationalGraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export Graph, FeynmanGraph, FeynmanProperties

export isequiv, drop_topology, is_external, is_internal, diagram_type, orders, vertices, topology
export external_legs, external_indices, external_operators, external_labels
export linear_combination, feynman_diagram, propagator, interaction, external_vertex
export multi_product, linear_combination, feynman_diagram, propagator, interaction, external_vertex

# export Prod, Sum
# export DiagramType, Interaction, ExternalVertex, Propagator, SelfEnergy, VertexDiag, GreenDiag, GenericDiag
Expand Down
12 changes: 6 additions & 6 deletions src/computational_graph/conversions.jl
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@

"""
function Base.convert(Graph, g::FeynmanGraph)
function Base.convert(::Type{G}, g::FeynmanGraph{F,W}) where {F,W,G<:Graph}
Converts a FeynmanGraph `g` into a Graph, discarding its Feynman properties.
After conversion, graph `g` is no longer guaranteed to be a valid (group of) Feynman diagram(s).
# Arguments:
- `g` computational graph
"""
function Base.convert(::Type{Graph{F,W}}, g::FeynmanGraph{F,W}) where {F,W}
return Graph{F,W}(g.subgraphs; subgraph_factors=g.subgraph_factors, name=g.name, operator=g.operator, orders=g.orders, factor=g.factor, weight=g.weight)
function Base.convert(::Type{G}, g::FeynmanGraph{F,W}) where {F,W,G<:Graph}
return Graph(g.subgraphs; subgraph_factors=g.subgraph_factors, name=g.name, operator=g.operator(), orders=g.orders, ftype=F, wtype=W, factor=g.factor, weight=g.weight)
end

function Base.convert(::Type{FeynmanGraph{F,W}}, g::Graph{F,W}) where {F,W}
function Base.convert(::Type{FeynmanGraph}, g::Graph{F,W}) where {F,W}
error(
"A set of Feynman properties (operator vertices, topology, etc.) must be specified to convert an object of type Graph to FeynmanGraph. " *
"Please use constructor `FeynmanGraph(g::Graph, properties::FeynmanProperties)` instead."
Expand All @@ -33,5 +33,5 @@ Base.:*(g1::Graph, g2::FeynmanGraph) = error("Multiplication of Feynman graphs i
Base.:*(g1::FeynmanGraph, g2::Graph) = error("Multiplication of Feynman graphs is not well defined!")
Base.:+(g1::Graph{F,W}, g2::FeynmanGraph{F,W}) where {F,W} = Base.:+(Base.promote(g1, g2)...)
Base.:+(g1::FeynmanGraph{F,W}, g2::Graph{F,W}) where {F,W} = Base.:+(Base.promote(g1, g2)...)
Base.:-(g1::Graph{F,W}, g2::FeynmanGraph{F,W}) where {F,W} = Base.:+(Base.promote(g1, g2)...)
Base.:-(g1::FeynmanGraph{F,W}, g2::Graph{F,W}) where {F,W} = Base.:+(Base.promote(g1, g2)...)
Base.:-(g1::Graph{F,W}, g2::FeynmanGraph{F,W}) where {F,W} = Base.:-(Base.promote(g1, g2)...)
Base.:-(g1::FeynmanGraph{F,W}, g2::Graph{F,W}) where {F,W} = Base.:-(Base.promote(g1, g2)...)
4 changes: 2 additions & 2 deletions src/computational_graph/feynmangraph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ mutable struct FeynmanGraph{F,W} <: AbstractGraph # FeynmanGraph
- `g` computational graph
- `properties::FeynmanProperties` diagrammatic properties, e.g., the operator vertices and topology
"""
function FeynmanGraph(g::Graph, properties::FeynmanProperties)
function FeynmanGraph(g::Graph{F,W}, properties::FeynmanProperties) where {F,W}
@assert length(properties.external_indices) == length(properties.external_legs)
# @assert allunique(subgraphs) "all subgraphs must be distinct."
return new{ftype,wtype}(uid(), g.name, g.orders, properties, g.subgraphs, g.subgraph_factors, typeof(g.operator), g.factor, g.weight)
return new{F,W}(uid(), g.name, g.orders, properties, g.subgraphs, g.subgraph_factors, g.operator, g.factor, g.weight)
end
end

Expand Down
77 changes: 69 additions & 8 deletions test/computational_graph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ Graphs.unary_istrivial(::Type{O}) where {O<:Union{O1,O2,O3}} = true
subgraph_factors::Vector{Float64}
factor::Float64
weight::Float64
function ConcreteGraph(subgraphs=[]; name="", orders=zeros(Int, 0), operator=O, subgraph_factors=[], factor=1.0, weight=1.0)
return new(Graphs.uid(), name, orders, operator, subgraphs, subgraph_factors, factor, weight)
function ConcreteGraph(subgraphs=[]; name="", orders=zeros(Int, 0), operator=O(), subgraph_factors=[], factor=1.0, weight=1.0)
return new(Graphs.uid(), name, orders, typeof(operator), subgraphs, subgraph_factors, factor, weight)
end
end

Graphs.uidreset()
g1 = ConcreteGraph(; operator=O1)
g2 = ConcreteGraph(; operator=O2)
g3 = ConcreteGraph(; operator=O3)
g = ConcreteGraph([g1, g2, g3]; subgraph_factors=[2, 3, 5], operator=O)
gp = ConcreteGraph([g1, g2, g3]; subgraph_factors=[2, 3, 5], operator=O)
h = ConcreteGraph([g1, g2, g3]; name="h", subgraph_factors=[2, 3, 5], operator=O)
g1 = ConcreteGraph(; operator=O1())
g2 = ConcreteGraph(; operator=O2())
g3 = ConcreteGraph(; operator=O3())
g = ConcreteGraph([g1, g2, g3]; subgraph_factors=[2, 3, 5], operator=O())
gp = ConcreteGraph([g1, g2, g3]; subgraph_factors=[2, 3, 5], operator=O())
h = ConcreteGraph([g1, g2, g3]; name="h", subgraph_factors=[2, 3, 5], operator=O())

# weight(g::AbstractGraph) is an abstract method
@test isnothing(Graphs.weight(ConcreteGraph()))
Expand Down Expand Up @@ -853,6 +853,67 @@ end
end
end

@testset verbose = true "Conversions" begin
# Test constructor for FeynmanGraph from Graph and FeynmanProperties
g = Graph([]; factor=-1.0, operator=Graphs.Sum())
g1 = Graph([]; operator=O1())
g2 = Graph([]; operator=O2())
g_feyn = propagator(𝑓⁺(1)𝑓⁻(2)) # equivalent to g after conversion
g_feyn_conv = FeynmanGraph(g, g_feyn.properties)
@test isequiv(g_feyn, g_feyn_conv, :id)

# Test automatic FeynmanGraph -> Graph conversion
g_conv::Graph = g_feyn
@test isequiv(g, g_conv, :id)

# Test automatic FeynmanGraph -> Graph promotion in arithmetic operations
conversion_successful = true
local l1, l2, l3, l4, l5, l6, l7, r7, l8, r8
try
l1 = g_feyn + g1
l2 = g_feyn - g1
l3 = linear_combination(g_feyn, g1, 2, 3)
l4 = linear_combination(g_feyn, g, 2, 3)
l5 = linear_combination([g_feyn, g, g1, g2], [2, 5, 3, 9])
l6 = multi_product(g_feyn, g1, 2, 3)
l7 = multi_product(g_feyn, g, 2, 3)
l8 = multi_product([g_feyn, g, g1, g2], [2, 5, 3, 9])
r7 = multi_product(g, g, 2, 3)
r8 = multi_product([g, g, g1, g2], [2, 5, 3, 9])
catch
conversion_successful = false
end
@test conversion_successful
Graphs.optimize!([l1, l2, l3, l4, l5, l6, l7, r7, l8, r8]) # cache unique leaves

@test isequiv(l1, g + g1, :id)
@test isequiv(l2, g - g1, :id)
@test isequiv(l3, 2 * g + 3 * g1, :id)
@test isequiv(l4, linear_combination([g], [5]), :id)
@test isequiv(l5, linear_combination([g, g1, g2], [7, 3, 9]), :id)
@test isequiv(l6, multi_product(g, g1, 2, 3), :id)

# TODO: Refine multiple Prod -> Power conversion
@test_broken isequiv(l7, r7, :id)
@test_broken isequiv(l8, r8, :id)

# FeynmanGraph multiplication is undefined
err1 = AssertionError()
err2 = AssertionError()
try
g * g_feyn
catch err1
end
try
g_feyn * g
catch err2
end
@test err1 isa ErrorException
@test err2 isa ErrorException
@test err1.msg == "Multiplication of Feynman graphs is not well defined!"
@test err2.msg == "Multiplication of Feynman graphs is not well defined!"
end

@testset verbose = true "Evaluation" begin
using FeynmanDiagram.ComputationalGraphs:
eval!
Expand Down

0 comments on commit 465c1ab

Please sign in to comment.