def closed_form(polynomial, roots, symbolic=False): ''' A simple heuristic to check if an approximate root is close to some algebraically expressible number. :param symbolic: Return an exact symbolic representation (via sympy), for LaTeX ''' x = [] for root in roots: rl = mpmath.identify(root.real, tol=1e-4, maxcoeff=30) im = mpmath.identify(root.imag, tol=1e-4, maxcoeff=30) if not rl: rl = root.real if not symbolic else sympify(rl).evalf(5) if not im: im = root.imag if not symbolic else sympify(im).evalf(5) new = float(sympify(rl)) + float(sympify(im))*1j # Arbitrary roundoff if abs(polynomial(root)) > abs(polynomial(new)) or abs(polynomial(new)) < 1e-10: if symbolic: x.append(sympify(rl) + sympify(im) * 1j) else: x.append(new) else: if symbolic: x.append(sympify(root)) else: x.append(root) return array(x)
def inverse_symbolic(n, threshold=1e-5): rl = mpmath.identify(n.real, tol=1e-3, maxcoeff=30) im = mpmath.identify(n.imag, tol=1e-3, maxcoeff=30) if not rl or abs(n.real - (nsimplify(rl).evalf())) > threshold: rl = nsimplify(n.real).evalf(5) if not im or abs(n.imag - (nsimplify(im).evalf())) > threshold: im = nsimplify(n.imag).evalf(5) return (sympify(rl) + sympify(im) * 1j)
def handleIdentify( result ): formula = identify( result ) if formula is None: base = [ 'pi', 'e', 'euler' ] formula = identify( result, base ) if formula is None: print( ' = [formula cannot be found]' ) else: print( ' = ' + formula )
def handleIdentify( result, file=sys.stdout ): '''Calls the mpmath identify function to try to identify a constant.''' formula = identify( result ) if formula is None: base = [ 'pi', 'e', 'euler' ] formula = identify( result, base ) if formula is None: print( ' = [formula cannot be found]', file=file ) else: print( ' = ' + formula, file=file )
def nsimplify_real(x): orig = mpmath.mp.dps xv = x._to_mpmath(bprec) try: # We'll be happy with low precision if a simple fraction if not (tolerance or full): mpmath.mp.dps = 15 rat = mpmath.findpoly(xv, 1) if rat is not None: return Rational(-int(rat[1]), int(rat[0])) mpmath.mp.dps = prec newexpr = mpmath.identify(xv, constants=constants_dict, tol=tolerance, full=full) if not newexpr: raise ValueError if full: newexpr = newexpr[0] expr = sympify(newexpr) if x and not expr: # don't let x become 0 raise ValueError if expr.is_finite is False and xv not in [mpmath.inf, mpmath.ninf]: raise ValueError return expr finally: # even though there are returns above, this is executed # before leaving mpmath.mp.dps = orig
def nsimplify_real(x): orig = mpmath.mp.dps xv = x._to_mpmath(bprec) try: # We'll be happy with low precision if a simple fraction if not (tolerance or full): mpmath.mp.dps = 15 rat = mpmath.pslq([xv, 1]) if rat is not None: return Rational(-int(rat[1]), int(rat[0])) mpmath.mp.dps = prec newexpr = mpmath.identify(xv, constants=constants_dict, tol=tolerance, full=full) if not newexpr: raise ValueError if full: newexpr = newexpr[0] expr = sympify(newexpr) if x and not expr: # don't let x become 0 raise ValueError if expr.is_finite is False and not xv in [mpmath.inf, mpmath.ninf]: raise ValueError return expr finally: # even though there are returns above, this is executed # before leaving mpmath.mp.dps = orig
def handleIdentify(result, file=sys.stdout): '''Calls the mpmath identify function to try to identify a constant.''' if isinstance(result, (list, RPNGenerator)): print('foo!', result) for i in list(result): print('i', i) handleIdentify(i) return formula = identify(result) if formula is None: base = ['pi', 'e', 'euler', 'sqrt(pi)', 'phi'] formula = identify(result, base) if formula is None: print(' = [formula cannot be found]', file=file) else: print(' = ' + formula, file=file)
def identify(a, abs_tol=1.0e-15): sols = mpmath.identify(a, ["pi"], tol=abs_tol, full=True) return list(set([sympify(sol) for sol in sols]))