Wrong result of evalf in SymPy but only for some values of the precision

193 Views Asked by At

I think I have encountered a bug of Sympy's evalf() method with substitutions passed.

By accident, I found an expression that evaluates to a wrong value if I replace the variable x by an integer rather than a Float. The funny thing is that this happens only for some values of the precision.

The expression looks somewhat arbitrary, but if I attempt to simplify it further the bug disappears. This is a minimal working example

#!/usr/bin/env python
import sympy
from sympy.abc import x

# Some valid mathematical expression
expr = 1/((x - 9)*(x - 8)*(x - 7)*(x - 4)**2*(x - 3)**3*(x - 2))


def example(prec):
    # This is the string 1.( prec-2 zeroes )1
    almost1 = '1.'+(prec-2)*'0'+'1'
    
    # We replace the integer 1
    res1 = expr.evalf(prec, subs={x:1})
    
    # We replace a Float veeery close to 1
    res_almost1 = expr.evalf(prec, subs={x:sympy.Float(almost1,prec)})

    return res1, res_almost1

The expected outcome is that the returned tuple should contain similar numbers since 1 and almost1 are very close. However, for some values of prec the result obtained by replacing 1 to expr is zero. (While the one obtained by replacing almost1 is close to the correct one.)

You may ask: "What are the values of prec for which the expression is wrong?". By running the code

wrong = [str(a) for a in range(10,1001) if example(a)[0] == 0]
print(','.join(wrong))

I obtain this seemingly completely random list

11,20,22,29,31,38,40,49,58,67,76,78,85,87,94,96,105,114,123,132,134,141,143,150,152,159,161,170,179,188,190,197,199,206,208,215,217,226,235,244,253,255,262,264,271,273,282,291,300,309,311,318,320,327,329,338,347,356,365,367,374,376,383,385,392,394,403,412,421,423,430,432,439,441,448,450,459,468,477,486,488,495,497,504,506,515,524,533,542,544,551,553,560,562,571,580,589,598,600,607,609,616,618,625,627,636,645,654,663,665,672,674,681,683,692,701,710,719,721,728,730,737,739,748,757,766,775,777,784,786,793,795,802,804,813,822,831,833,840,842,849,851,858,860,869,878,887,896,898,905,907,914,916,925,934,943,952,954,961,963,970,972,981,990,999

I posted it here so see whether I made some blunder in my code, otherwise I plan to post a bug issue on Sympy's github.

0

There are 0 best solutions below