1+ export store_colors, gromov_witten_load_color
2+
3+ function store_colors (G:: AbstractGKM_graph , beta:: CurveClass_type )
4+
5+ H2 = GKM_second_homology (G)
6+ R = G. equivariantCohomology
7+ # this part is needed for the generation of colorings
8+ nc:: Dict{Int64,Vector{Int64}} = Dict {Int64,Vector{Int64}} ()
9+ for v in 1 : n_vertices (G. g)
10+ nc[v] = sort (all_neighbors (G. g, v))
11+ end
12+ # ########
13+
14+ counter = 0
15+ max_n_vert:: Int64 = _max_n_edges (H2, beta) + 1
16+
17+ name_file = " ls_color.txt"
18+ io = open (name_file, " a" )
19+
20+ # n_marks = length(classes)
21+ # iterate undecorated trees:
22+ for ls in Iterators. flatten ([TreeIt (i) for i in 2 : max_n_vert]) # generation of level sequences
23+
24+ CI, parents, subgraph_ends = col_it_init (ls, nc) # generation of colorings
25+ # iterate maps from tree to G.g:
26+ for col in CI # colorings Iterator
27+ Serialization. serialize (io, (ls, col, parents, subgraph_ends))
28+ counter += 1
29+ end
30+ end
31+ close (io)
32+ println (" Stored $counter colorings to $name_file " )
33+ end
34+
35+
36+ function gromov_witten_load_color (G:: AbstractGKM_graph , beta:: CurveClass_type , n_marks:: Int64 , P_input:: Array{EquivariantClass} , line_num:: Int64 ; show_bar:: Bool = true , check_degrees:: Bool = false , fast_mode:: Bool = false )
37+
38+ # ########################
39+ # # GENUS ZERO CASE: ##
40+ # ########################
41+
42+ inputLength = length (P_input)
43+ # inputSize = size(P_input)
44+ inputKeys = keys (P_input)
45+ @req inputLength > 0 " gromov_witten needs at least one input for P_input."
46+
47+ @req ! is_zero (beta) " Beta must be non-zero" # != zero(parent(beta)) "Beta must be non-zero"
48+
49+ H2 = GKM_second_homology (G)
50+ R = G. equivariantCohomology
51+
52+ if fast_mode
53+ res = [zero (QQ) for _ in inputKeys] # zeros(QQFieldElem, inputSize)
54+
55+ # if fast_mode is activated, store edge weights and point euler classes locally.
56+ # These are passed to Euler_inv, _h, weight_class, and euler_class to optimize performance.
57+ edge_weight_dict = Dict {Edge, QQFieldElem} ()
58+ point_weight_dict = vcat (Union{Nothing, QQFieldElem}[], repeat ([nothing ], n_vertices (G. g)))
59+ # t are the equivariant parameters.
60+ t = QQ .([(i+ 4 )^ 2 for i in 1 : length (gens (R. coeffRing))])
61+
62+ # ########
63+ # Dict in order to store H
64+ h_dict = Dict {Tuple{Int64, Int64, Int64}, QQFieldElem} () # Lambda_gamma_e_dict
65+ # #######
66+ else
67+ res = [zero (R. coeffRingLocalized) for _ in inputKeys] # zeros(AbstractAlgebra.Generic.FracFieldElem{QQMPolyRingElem}, inputSize)
68+
69+ # if we are not in fast_mode, edge weights and point euler classes are polynomials in the equivariant parameters,
70+ # which are already stored in R.
71+ edge_weight_dict = R. edgeWeightClasses
72+ point_weight_dict = R. pointEulerClasses
73+ # t are the equivariant parameters.
74+ t = gens (R. coeffRing)
75+
76+ # ########
77+ # Dict in order to store H
78+ h_dict = Dict {Tuple{Int64, Int64, Int64}, AbstractAlgebra.Generic.FracFieldElem{QQMPolyRingElem}} () # Lambda_gamma_e_dict
79+ # #######
80+ end
81+
82+
83+ if ! is_effective (H2, beta)
84+ return res
85+ end
86+
87+ P = [P_input[k]. func for k in inputKeys]
88+ con = get_any_connection (G)
89+ @req ! isnothing (con) " GKM graph needs a connection!"
90+
91+ # #######
92+ # this part is needed for the generation of colorings
93+ nc:: Dict{Int64,Vector{Int64}} = Dict {Int64,Vector{Int64}} ()
94+ for v in 1 : n_vertices (G. g)
95+ nc[v] = sort (all_neighbors (G. g, v))
96+ end
97+ # ########
98+
99+
100+ max_n_vert:: Int64 = _max_n_edges (H2, beta) + 1
101+
102+ if show_bar # set up progress data
103+ number_trees = A000055 (max_n_vert)
104+ # Count the number of trees with at most max_n_vert vertices and a graph homomorphism to
105+ # G.g, also counting ways to distribute the marked points among the vertices.
106+ # This does not cound the edge multiplicities.
107+ threshold = n_vertices (G. g) * sum (vert -> number_trees[vert] * ((length (nc[1 ]))^ (vert - 1 )) * binomial (vert+ n_marks- 1 , n_marks), 2 : max_n_vert)
108+ progress_bar:: Progress = Progress (threshold, barglyphs= BarGlyphs (" [=> ]" ), color= :green )
109+ current_graph = 0
110+ end
111+
112+ name_file = " ls_color.txt"
113+ pair = ([0 ], [0 ], [0 ], [0 ]) # dummy initialization
114+ io = open (name_file, " r" )
115+ for i in 1 : line_num
116+ if eof (io)
117+ error (" File has fewer than $line_num lines." )
118+ return res
119+ end
120+ pair = deserialize (io)
121+ if i == line_num
122+ break
123+ end
124+ end
125+ close (io)
126+
127+ (ls, col, parents, subgraph_ends) = pair
128+ # n_marks = length(classes)
129+ # iterate undecorated trees:
130+ # for ls in Iterators.flatten([TreeIt(i) for i in 2:max_n_vert]) # generation of level sequences
131+ tree = LStoGraph (ls) # from level sequence to graph
132+ tree_aut = count_iso (ls)
133+
134+ # CI, parents, subgraph_ends = col_it_init(ls, nc) # generation of colorings
135+ # iterate maps from tree to G.g:
136+ # for col in CI # colorings Iterator
137+ top_aut:: Int64 = count_iso (ls, col)
138+ Multi = _multiplicities (H2, [Edge (col[src (e)], col[dst (e)]) for e in edges (tree)], beta)
139+ # iterate location of marks on the tree
140+ for m_inv in Combinatorics. with_replacement_combinations (1 : nv (tree), n_marks)
141+
142+ aut = count_iso (ls, col, m_inv)
143+
144+ # iterate edge multiplicities
145+ for edgeMult_array in Multi
146+
147+ PROD = prod (edgeMult_array)
148+ euler = zero (t[1 ])
149+
150+ edgeMult = Dict {Edge, Int} (edges (tree) .=> edgeMult_array)
151+
152+ # Iterate numbering of the marks on the tree, picking only one per isomorphism class
153+ # Details here have to do with the colors iterator from Colors.jl.
154+ for m in Base. Iterators. filter (mul_per -> top_aut == 1 || isempty (mul_per) || maximum (mul_per) < 3 || ismin (ls, col, mul_per, parents, subgraph_ends), multiset_permutations (m_inv, n_marks))
155+
156+
157+ dt = decoratedTree (G, tree, col, edgeMult, m)
158+
159+ Class = [Base. invokelatest (P[k], dt) for k in keys (P)]
160+ # TODO : can we pass t directly to each P[k]?
161+
162+ all (c -> is_zero (c), Class) && continue
163+
164+ # println("Class = $Class")
165+
166+ if is_zero (euler) # euler == zero(R.coeffRing)
167+ euler = Euler_inv (dt, t, edge_weight_dict, point_weight_dict; check_degree= check_degrees)// (PROD * aut)
168+ # println("Euler: $euler")
169+ for e in edges (tree)
170+ triple = (edgeMult[e], min (col[src (e)], col[dst (e)]), max (col[src (e)], col[dst (e)]))
171+ if ! haskey (h_dict, triple)
172+ h_dict[triple] = _h (Edge (col[src (e)], col[dst (e)]), triple[1 ], con, R, t, edge_weight_dict; check= false , check_degrees= check_degrees)
173+ end
174+ euler *= h_dict[triple]
175+ end
176+
177+ end
178+ # println("ls = $(ls), col = $(col), aut = $(aut), PRODW = $(PROD), m=$(m), E = $(euler)")
179+ # @req _is_homogeneous(euler) "Euler not homogeneous"
180+ # @req _is_homogeneous(Class[1]) "Class not homogeneous"
181+ if fast_mode
182+ # The isa(...) check below is necessary as sometimes Class[i] is an integer,
183+ # because evaluate(Int64, ...) is not defined.
184+ foreach (i-> res[i] += (isa (Class[i], Union{Number, QQFieldElem}) ? Class[i] : evaluate (Class[i], t))* euler, keys (Class))
185+ # TODO : can we pass t directly to each P[k]? Then we don't need to evaluate here and get rid of this if-else block.
186+ else
187+ res += Class.* euler
188+ end
189+
190+ end
191+ end
192+
193+ if show_bar # update the progress bar
194+ current_graph += tree_aut ÷ top_aut
195+ update! (progress_bar, current_graph,
196+ showvalues= [(:" Total number of graphs" , threshold), (:" Current graph" , current_graph)])
197+ end
198+ end
199+ # end
200+ # end
201+
202+ f = open (" $line_num .txt" , " w" )
203+ println (f, res)
204+ close (f)
205+ return res
206+ end
0 commit comments