End of Day; Add topology generation and iterators

This commit is contained in:
Anton Reinhard
2024-04-02 02:12:33 +02:00
parent a959137e22
commit b6728b2236
9 changed files with 230 additions and 0 deletions

37
src/diagrams/diagrams.jl Normal file
View File

@@ -0,0 +1,37 @@
using Combinatorics
struct FeynmanDiagramDefinition
n::Int
end
struct FeynmanDiagramTopology
# largest subtree
subtree1::AbstractTree
# second largest subtree
subtree2::AbstractTree
# third largest subtree
subtree3::AbstractTree
end
struct TopologyPartition
leaves1::Int
leaves2::Int
leaves3::Int
end
function is_valid(partition::TopologyPartition)
if partition.leaves2 > partition.leaves1 || partition.leaves3 > partition.leaves2
return false
end
if partition.leaves1 > partition.leaves2 + partition.leaves3
return false
end
if partition.leaves1 <= 0 || partition.leaves2 <= 0 || partition.leaves3 <= 0
return false
end
return true
end
function leaves(partition::TopologyPartition)
return partition.leaves1 + partition.leaves2 + partition.leaves3
end

92
src/diagrams/iterator.jl Normal file
View File

@@ -0,0 +1,92 @@
"""
iterates inside one partition
"""
mutable struct FeynmanPartitionIterator
topology::TopologyPartition
forest1_iterator::Union{ForestIterator,Missing}
forest2_iterator::Union{ForestIterator,Missing}
forest3_iterator::Union{ForestIterator,Missing}
end
mutable struct FeynmanDiagramTopologyIterator
leaves::Int
partitions_state::Vector{Int64}
partition::FeynmanPartitionIterator
end
function FeynmanPartitionIterator(topology::TopologyPartition)
return FeynmanPartitionIterator(topology, ForestIterator(topology.leaves1), ForestIterator(topology.leaves2), ForestIterator(topology.leaves3))
end
function FeynmanDiagramTopologyIterator(def::FeynmanDiagramDefinition)
@assert def.n >= 4 "A Feynman diagram must have at least 4 legs"
(p, _) = iterate(partitions(def.n))
while length(p) != 3 || !is_valid(TopologyPartition(p[1], p[2], p[3]))
(p, _) = iterate(partitions(def.n), p)
end
return FeynmanDiagramTopologyIterator(def.n, p, FeynmanPartitionIterator(TopologyPartition(p[1], p[2], p[3])))
end
function FeynmanDiagramTopology(iterator::FeynmanPartitionIterator)
return FeynmanDiagramTopology(tree(iterator.forest1_iterator), tree(iterator.forest2_iterator), tree(iterator.forest3_iterator))
end
function FeynmanDiagramTopology(iterator::FeynmanDiagramTopologyIterator)
return FeynmanDiagramTopology(iterator.partition)
end
function _iterate(iterator::FeynmanPartitionIterator)
# todo: need symmetry breaking here
if !is_end(iterator.forest3_iterator)
_iterate(iterator.forest3_iterator)
elseif !is_end(iterator.forest2_iterator)
iterator.forest3_iterator = ForestIterator(iterator.topology.leaves3)
_iterate(iterator.forest2_iterator)
else
iterator.forest3_iterator = ForestIterator(iterator.topology.leaves3)
iterator.forest2_iterator = ForestIterator(iterator.topology.leaves2)
_iterate(iterator.forest1_iterator)
end
return nothing
end
function _iterate(iterator::FeynmanDiagramTopologyIterator)
if !is_end(iterator.partition)
_iterate(iterator.partition)
else
while true
ret = iterate(partitions(iterator.leaves), iterator.partitions_state)
if (isnothing(ret))
return false
end
(p, _) = ret
iterator.partitions_state = p
if length(p) == 3 && is_valid(TopologyPartition(p[1], p[2], p[3]))
iterator.partition = FeynmanPartitionIterator(TopologyPartition(p[1], p[2], p[3]))
break
end
end
end
return true
end
function is_end(iterator::FeynmanPartitionIterator)
return is_end(iterator.forest1_iterator) && is_end(iterator.forest2_iterator) && is_end(iterator.forest3_iterator)
end
function iterate(def::FeynmanDiagramDefinition)
state = FeynmanDiagramTopologyIterator(def)
return (FeynmanDiagramTopology(state), state)
end
function iterate(def::FeynmanDiagramDefinition, state::FeynmanDiagramTopologyIterator)
if !_iterate(state)
return nothing
end
return (FeynmanDiagramTopology(state), state)
end