Source code for prodigy.analysis.evtinvariants.heuristics.templates.rational_function

import itertools
from typing import Collection, Iterator

import sympy

from prodigy.analysis.evtinvariants.heuristics.templates.templates import TemplateHeuristic
from prodigy.distribution import CommonDistributionsFactory, Distribution
from prodigy.util import make_poly_clause


[docs] class RationalFunctionMaxDeg(TemplateHeuristic): """ This heuristic enumerates rational functions with increasing total degree. It does so my increasing the denominator degree first and then tries all numerator polynomials upto the current denominator degree before increasing the numerator degree. """ def __init__(self, max_deg: int, variables: Collection[str], dist_factory: CommonDistributionsFactory): self.max_deg = max_deg self.variables = variables self.dist_fact = dist_factory
[docs] def generate(self) -> Iterator[Distribution]: for max_powers_denom in sympy.utilities.iterables.iproduct(*[range(self.max_deg + 1) for _ in self.variables]): degrees = [range(max_powers_denom[i] + 1) for i, _ in enumerate(self.variables)] numerator = " + ".join((make_poly_clause(f"n_{c}", self.variables, pows) for c, pows in enumerate(itertools.product(*degrees)))) for max_powers_num in sympy.utilities.iterables.iproduct( *[range(sum(max_powers_denom) + 1) for _ in self.variables]): if sum(max_powers_num) > sum(max_powers_denom): continue denom_degrees = [range(max_powers_num[i] + 1) for i, _ in enumerate(self.variables)] denominator = " + ".join((make_poly_clause(f"d_{c}", self.variables, pows) for c, pows in enumerate(itertools.product(*denom_degrees)))) yield self.dist_fact.from_expr(f"({numerator}) / ({denominator})", *self.variables)