@@ -90,6 +90,10 @@ Method Argument
9090 * It accepts keyword arguments `maxorder` (optional) and `r`,
9191 if `r > 1`, one has better precision for coefficients of large order, if `r < 1`,
9292 one has better precision for coefficients of small order.
93+ * `:fitting`, fit the polynomial directly.
94+ * The corresponding tensor element type is floating point numbers like `Base.Float64`.
95+ * It has round-off error.
96+ * BLAS and GPU are supported, it is the fastest among all methods.
9397
9498Graph polynomials are not defined for weighted graph problems.
9599"""
@@ -237,7 +241,7 @@ function solve(gp::GraphProblem, property::AbstractProperty; T=Float64, usecuda=
237241 elseif property isa CountingMin
238242 return post_invert_exponent .(contractx (gp, pre_invert_exponent (TruncatedPoly (ntuple (i-> i == min_k (property) ? one (T) : zero (T), min_k (property)), one (T))); usecuda= usecuda))
239243 elseif property isa GraphPolynomial
240- return graph_polynomial (gp, Val (graph_polynomial_method (property)); usecuda= usecuda, property. kwargs... )
244+ return graph_polynomial (gp, Val (graph_polynomial_method (property)); usecuda= usecuda, T = T, property. kwargs... )
241245 elseif property isa SingleConfigMax{false }
242246 return solutions (gp, CountingTropical{T,T}; all= false , usecuda= usecuda, )
243247 elseif property isa SingleConfigMin{false }
@@ -253,19 +257,19 @@ function solve(gp::GraphProblem, property::AbstractProperty; T=Float64, usecuda=
253257 elseif property isa ConfigsAll
254258 return solutions (gp, Real; all= true , usecuda= usecuda, tree_storage= tree_storage (property))
255259 elseif property isa SingleConfigMax{true }
256- return best_solutions (gp; all= false , usecuda= usecuda)
260+ return best_solutions (gp; all= false , usecuda= usecuda, T = T )
257261 elseif property isa SingleConfigMin{true }
258- return best_solutions (gp; all= false , usecuda= usecuda, invert= true )
262+ return best_solutions (gp; all= false , usecuda= usecuda, invert= true , T = T )
259263 elseif property isa ConfigsMax{1 ,true }
260- return best_solutions (gp; all= true , usecuda= usecuda, tree_storage= tree_storage (property))
264+ return best_solutions (gp; all= true , usecuda= usecuda, tree_storage= tree_storage (property), T = T )
261265 elseif property isa ConfigsMin{1 ,true }
262- return best_solutions (gp; all= true , usecuda= usecuda, invert= true , tree_storage= tree_storage (property))
266+ return best_solutions (gp; all= true , usecuda= usecuda, invert= true , tree_storage= tree_storage (property), T = T )
263267 elseif property isa (ConfigsMax{K,true } where K)
264- return bestk_solutions (gp, max_k (property), tree_storage= tree_storage (property))
268+ return bestk_solutions (gp, max_k (property), tree_storage= tree_storage (property), T = T )
265269 elseif property isa (ConfigsMin{K,true } where K)
266- return bestk_solutions (gp, min_k (property), invert= true , tree_storage= tree_storage (property))
270+ return bestk_solutions (gp, min_k (property), invert= true , tree_storage= tree_storage (property), T = T )
267271 else
268- error (" unknown property $property ." )
272+ error (" unknown property: ` $property ` ." )
269273 end
270274end
271275
379383# convert to Matrix
380384Base. Matrix (ce:: ConfigEnumerator ) = plain_matrix (ce)
381385Base. Vector (ce:: StaticElementVector ) = collect (ce)
386+
387+ # ######### memory estimation ###############
388+ """
389+ estimate_memory(problem, property; T=Float64)
390+
391+ Memory estimation in number of bytes to compute certain `property` of a `problem`.
392+ `T` is the base type.
393+ """
394+ function estimate_memory (problem:: GraphProblem , property:: AbstractProperty ; T= Float64)
395+ _estimate_memory (tensor_element_type (T, length (labels (problem)), nflavor (problem), property), problem)
396+ end
397+ function estimate_memory (problem:: GraphProblem , :: Union{SingleConfigMax{true},SingleConfigMin{true}} ; T= Float64)
398+ tc, sc, rw = timespacereadwrite_complexity (problem. code, _size_dict (problem))
399+ # caching all tensors is equivalent to counting the total number of writes
400+ return ceil (Int, exp2 (rw - 1 )) * sizeof (Tropical{T})
401+ end
402+ function estimate_memory (problem:: GraphProblem , :: GraphPolynomial{:polynomial} ; T= Float64)
403+ # this is the upper bound
404+ return peak_memory (problem. code, _size_dict (problem)) * (sizeof (T) * length (labels (problem)))
405+ end
406+
407+ function _size_dict (problem)
408+ lbs = labels (problem)
409+ nf = nflavor (problem)
410+ return Dict ([lb=> nf for lb in lbs])
411+ end
412+
413+ function _estimate_memory (:: Type{ET} , problem:: GraphProblem ) where ET
414+ if ! isbitstype (ET) && ! (ET <: Mod )
415+ @warn " Target tensor element type `$ET ` is not a bits type, the estimation of memory might be unreliable."
416+ end
417+ return peak_memory (problem. code, _size_dict (problem)) * sizeof (ET)
418+ end
419+
420+ for (PROP, ET) in [(:SizeMax , :(Tropical{T})), (:SizeMin , :(Tropical{T})),
421+ (:(SingleConfigMax{true }), :(Tropical{T})), (:(SingleConfigMin{true }), :(Tropical{T})),
422+ (:(CountingAll), :T ), (:(CountingMax{1 }), :(CountingTropical{T,T})), (:(CountingMin{1 }), :(CountingTropical{T,T})),
423+ (:(CountingMax{K}), :(TruncatedPoly{K,T,T})), (:(CountingMin{K}), :(TruncatedPoly{K,T,T})),
424+ (:(GraphPolynomial{:finitefield }), :(Mod{N,Int32} where N)), (:(GraphPolynomial{:fft }), :(Complex{T})),
425+ (:(GraphPolynomial{:polynomial }), :(Polynomial{T, :x })), (:(GraphPolynomial{:fitting }), :T ),
426+ ]
427+ @eval tensor_element_type (:: Type{T} , n:: Int , nflavor:: Int , :: $PROP ) where {T,K} = $ ET
428+ end
429+
430+ for (PROP, ET) in [(:(SingleConfigMax{false }), :(CountingTropical{T,T})), (:(SingleConfigMin{false }), :(CountingTropical{T,T}))]
431+ @eval function tensor_element_type (:: Type{T} , n:: Int , nflavor:: Int , :: $PROP ) where {T}
432+ sampler_type ($ ET, n, nflavor)
433+ end
434+ end
435+ for (PROP, ET) in [
436+ (:(ConfigsMax{1 }), :(CountingTropical{T,T})), (:(ConfigsMin{1 }), :(CountingTropical{T,T})),
437+ (:(ConfigsMax{K}), :(TruncatedPoly{K,T,T})), (:(ConfigsMin{K}), :(TruncatedPoly{K,T,T})),
438+ (:(ConfigsAll), :(Real))
439+ ]
440+ @eval function tensor_element_type (:: Type{T} , n:: Int , nflavor:: Int , :: $PROP ) where {T,K}
441+ set_type ($ ET, n, nflavor)
442+ end
443+ end
0 commit comments