From 04ebdb34ae4268d4df364c79f111e9d91934ed60 Mon Sep 17 00:00:00 2001 From: mmatera Date: Sat, 6 Feb 2021 15:27:31 -0300 Subject: [PATCH 1/2] * a fraction is zero if the numerator is zero and the denominator is not zero. \n* fix MachineReal.is_approx_zero --- mathics/builtin/arithmetic.py | 5 +++++ mathics/core/evaluation.py | 2 -- mathics/core/expression.py | 9 +++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/mathics/builtin/arithmetic.py b/mathics/builtin/arithmetic.py index 0c7b055476..611c17adf6 100644 --- a/mathics/builtin/arithmetic.py +++ b/mathics/builtin/arithmetic.py @@ -1346,6 +1346,11 @@ def apply(self, expr, evaluation): sympy_expr = expr.to_sympy() result = _iszero(sympy_expr) + if result is None: + # try expanding the expression + exprexp = Expression("ExpandAll", expr).evaluate(evaluation) + exprexp = exprexp.to_sympy() + result = _iszero(exprexp) if result is None: # Can't get exact answer, so try approximate equal numeric_val = Expression("N", expr).evaluate(evaluation) diff --git a/mathics/core/evaluation.py b/mathics/core/evaluation.py index acbef039cb..0d7e582ce6 100644 --- a/mathics/core/evaluation.py +++ b/mathics/core/evaluation.py @@ -264,7 +264,6 @@ def __init__( def parse(self, query): "Parse a single expression and print the messages." from mathics.core.parser import SingleLineFeeder - return self.parse_feeder(SingleLineFeeder(query)) def parse_evaluate(self, query, timeout=None): @@ -278,7 +277,6 @@ def parse_feeder(self, feeder): def parse_feeder_returning_code(self, feeder): "Parse a single expression from feeder and print the messages." from mathics.core.parser.util import parse_returning_code - try: result, source_code = parse_returning_code(self.definitions, feeder) except TranslateError: diff --git a/mathics/core/expression.py b/mathics/core/expression.py index 263690d680..772da90b26 100644 --- a/mathics/core/expression.py +++ b/mathics/core/expression.py @@ -2109,7 +2109,7 @@ def __neg__(self) -> 'Rational': @property def is_zero(self) -> bool: - return self.numerator().is_zero + return self.numerator().is_zero and not self.denominator().is_zero() class Real(Number): @@ -2257,9 +2257,10 @@ def is_zero(self) -> bool: @property def is_approx_zero(self) -> bool: - # FIXME: figure out how to hook int $MachinePrecision and - # what the right definition here would be. - return abs(self.value) <= 10**-14 + # In WMA, Chop[10.^(-10)] == 0, + # so, lets take it. + res = abs(self.value) <= 1e-10 + return res class PrecisionReal(Real): From d686e8f897ea1fa6edec923d41edf3cb3f048bd9 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 6 Feb 2021 14:28:16 -0500 Subject: [PATCH 2/2] Reinstate PossibleZeroTests --- mathics/builtin/arithmetic.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mathics/builtin/arithmetic.py b/mathics/builtin/arithmetic.py index 91769bcbec..0c7b055476 100644 --- a/mathics/builtin/arithmetic.py +++ b/mathics/builtin/arithmetic.py @@ -1309,19 +1309,19 @@ class PossibleZeroQ(SympyFunction):
returns 'True' if basic symbolic and numerical methods suggest that expr has value zero, and 'False' otherwise. - ## Test whether a numeric expression is zero: - ## >> PossibleZeroQ[E^(I Pi/4) - (-1)^(1/4)] - ## = True + Test whether a numeric expression is zero: + >> PossibleZeroQ[E^(I Pi/4) - (-1)^(1/4)] + = True - ## The determination is approximate. + The determination is approximate. Test whether a symbolic expression is likely to be identically zero: >> PossibleZeroQ[(x + 1) (x - 1) - x^2 + 1] = True - ## >> PossibleZeroQ[(E + Pi)^2 - E^2 - Pi^2 - 2 E Pi] - ## = True + >> PossibleZeroQ[(E + Pi)^2 - E^2 - Pi^2 - 2 E Pi] + = True Show that a numeric expression is nonzero: >> PossibleZeroQ[E^Pi - Pi^E]