def evaluate(expr,context = pc.global_context,cache = None,format = True): if context in __cached_evaluators: main = __cached_evaluators[context] else: main = pc.MultiEvaluator(recursive=True,split_binary=True) main.add_evaluator(context) main.add_evaluator(main_evaluator.main_evaluator) __cached_evaluators[context] = main if cache == None and __use_global_cache: cache = __cached_evaluators expr = main(expr,cache = cache) if format: expr = canonical_form.format_evaluator(expr,cache = cache) return expr
pc.is_in_type(s.n, pc.Types.Integer), s.n > 1) evaluator.add_rule((s.a + s.b)**s.n, (s.a + s.b) * (s.a + s.b)**(s.n - 1), condition=is_positive_numeric_integer) evaluator.add_rule((s.a + s.b)**-s.n, (s.a + s.b)**(-s.n + 1) * (s.a + s.b)**-1, condition=is_positive_numeric_integer) evaluator.add_rule(s.x * s.x, s.x**2, condition=is_atomic(s.x)) evaluator.add_rule(s.x * s.x**s.n, s.x**(s.n + 1), condition=is_atomic(s.x)) evaluator.add_rule(s.x**s.m * s.x**s.n, s.x**(s.n + s.m), condition=is_atomic(s.x)) evaluator.add_rule((s.a * s.b)**s.c, s.a**s.c * s.b**s.c) from .canonical_form import canonical_form from .logic_evaluator import logic_evaluator from .numeric_evaluator import numeric_evaluator from .type_evaluator import type_evaluator from .main_evaluator import evaluator as main_evaluator expand_evaluator = pc.MultiEvaluator(recursive=True, split_binary=True) expand_evaluator.add_evaluator(canonical_form) expand_evaluator.add_evaluator(numeric_evaluator) expand_evaluator.add_evaluator(evaluator) expand_evaluator.add_evaluator(main_evaluator) expand_evaluator.add_evaluator(type_evaluator) expand_evaluator.add_evaluator(logic_evaluator)
import fractions def evaluate_fraction(m): vx = m[s.x].value vy = m[s.y].value res = fractions.Fraction(vx, vy) if (res.numerator, res.denominator) == (vx, vy): return False m[s.a] = res.numerator m[s.b] = res.denominator evaluator.add_rule(s.x * s.y**-1, s.a * s.b**-1, evaluate_fraction, condition=are_explicit_numbers(s.x, s.y)) evaluator.add_rule(s.x**s.c * s.y**-s.c, s.a**s.c * s.b**-s.c, evaluate_fraction, condition=are_explicit_numbers(s.x, s.y)) from .canonical_form import canonical_form from .logic_evaluator import logic_evaluator numeric_evaluator = pc.MultiEvaluator(recursive=True, split_binary=True) numeric_evaluator.add_evaluator(canonical_form) numeric_evaluator.add_evaluator(logic_evaluator) numeric_evaluator.add_evaluator(evaluator)
return False m[s.y] = pc.expresso.create_object(res) except Exception as e: return False compile_evaluator.add_rule(s.x, s.y, fold) compile_evaluator.add_rule(s.x**2, s.x * s.x, condition=is_atomic(s.x)) compile_evaluator.add_rule(s.x * abs(s.y), abs(s.x * s.y), condition=is_mpmath(s.x)) compile_evaluator.add_rule(s.x * (s.y + s.z), (s.x * s.y + s.x * s.z), condition=is_mpmath(s.x)) compiler_opt_evaluator = pc.MultiEvaluator(recursive=True, split_binary=True) compiler_opt_evaluator.add_evaluator(compile_evaluator) compiler_opt_evaluator.add_evaluator(logic_evaluator) def optimize_for_compilation(expr, cache=None, prec=20): global fold_accuracy fold_accuracy = prec opt = None # TODO: why do we need to evaluate multiple times? N = 10 while opt != expr and N > 0: N -= 1 opt = expr expr = compiler_opt_evaluator(expr, cache=cache)