class_docstr: Context for multiprecision arithmetic with a global precision.
class_docstr_tok: ["Context","for","multiprecision","arithmetic","with","a","global","precision","."]
docstr: Return a wrapped copy of *f* that repeatedly evaluates *f*
  with increasing precision until the result converges to the
  full precision used at the point of the call.
  
  This heuristically protects against rounding errors, at the cost of
  roughly a 2x slowdown compared to manually setting the optimal
  precision. This method can, however, easily be fooled if the results
  from *f* depend "discontinuously" on the precision, for instance
  if catastrophic cancellation can occur. Therefore, :func:`~mpmath.autoprec`
  should be used judiciously.
  
  **Examples**
  
  Many functions are sensitive to perturbations of the input arguments.
  If the arguments are decimal numbers, they may have to be converted
  to binary at a much higher precision. If the amount of required
  extra precision is unknown, :func:`~mpmath.autoprec` is convenient::
  
      >>> from mpmath import *
      >>> mp.dps = 15
      >>> mp.pretty = True
      >>> besselj(5, 125 * 10**28)    # Exact input
      -8.03284785591801e-17
      >>> besselj(5, '1.25e30')   # Bad
      7.12954868316652e-16
      >>> autoprec(besselj)(5, '1.25e30')   # Good
      -8.03284785591801e-17
  
  The following fails to converge because `\sin(\pi) = 0` whereas all
  finite-precision approximations of `\pi` give nonzero values::
  
      >>> autoprec(sin)(pi) # doctest: +IGNORE_EXCEPTION_DETAIL
      Traceback (most recent call last):
        ...
      NoConvergence: autoprec: prec increased to 2910 without convergence
  
  As the following example shows, :func:`~mpmath.autoprec` can protect against
  cancellation, but is fooled by too severe cancellation::
  
      >>> x = 1e-10
      >>> exp(x)-1; expm1(x); autoprec(lambda t: exp(t)-1)(x)
      1.00000008274037e-10
      1.00000000005e-10
      1.00000000005e-10
      >>> x = 1e-50
      >>> exp(x)-1; expm1(x); autoprec(lambda t: exp(t)-1)(x)
      0.0
      1.0e-50
      0.0
  
  With *catch*, an exception or list of exceptions to intercept
  may be specified. The raised exception is interpreted
  as signaling insufficient precision. This permits, for example,
  evaluating a function where a too low precision results in a
  division by zero::
  
      >>> f = lambda x: 1/(exp(x)-1)
      >>> f(1e-30)
      Traceback (most recent call last):
        ...
      ZeroDivisionError
      >>> autoprec(f, catch=ZeroDivisionError)(1e-30)
      1.0e+30
docstr_tok: ["Return","a","wrapped","copy","of","*","f","*","that","repeatedly","evaluates","*","f","*","with","increasing","precision","until","the","result","converges","to","the","full","precision","used","at","the","point","of","the","call",".","This","heuristically","protects","against","rounding","errors",",","at","the","cost","of","roughly","a","2x","slowdown","compared","to","manually","setting","the","optimal","precision",".","This","method","can",",","however",",","easily","be","fooled","if","the","results","from","*","f","*","depend","``","discontinuously","''","on","the","precision",",","for","instance","if","catastrophic","cancellation","can","occur",".","Therefore",",",":","func",":","`","~mpmath.autoprec","`","should","be","used","judiciously",".","*","*","Examples","*","*","Many","functions","are","sensitive","to","perturbations","of","the","input","arguments",".","If","the","arguments","are","decimal","numbers",",","they","may","have","to","be","converted","to","binary","at","a","much","higher","precision",".","If","the","amount","of","required","extra","precision","is","unknown",",",":","func",":","`","~mpmath.autoprec","`","is","convenient",":",":",">",">",">","from","mpmath","import","*",">",">",">","mp.dps","=","15",">",">",">","mp.pretty","=","True",">",">",">","besselj","(","5",",","125","*","10","*","*","28",")","#","Exact","input","-8.03284785591801e-17",">",">",">","besselj","(","5",",","'","1.25e30","'",")","#","Bad","7.12954868316652e-16",">",">",">","autoprec","(","besselj",")","(","5",",","'","1.25e30","'",")","#","Good","-8.03284785591801e-17","The","following","fails","to","converge","because","`","\\sin","(","\\pi",")","=","0","`","whereas","all","finite-precision","approximations","of","`","\\pi","`","give","nonzero","values",":",":",">",">",">","autoprec","(","sin",")","(","pi",")","#","doctest",":","+IGNORE_EXCEPTION_DETAIL","Traceback","(","most","recent","call","last",")",":","...","NoConvergence",":","autoprec",":","prec","increased","to","2910","without","convergence","As","the","following","example","shows",",",":","func",":","`","~mpmath.autoprec","`","can","protect","against","cancellation",",","but","is","fooled","by","too","severe","cancellation",":",":",">",">",">","x","=","1e-10",">",">",">","exp","(","x",")","-1",";","expm1","(","x",")",";","autoprec","(","lambda","t",":","exp","(","t",")","-1",")","(","x",")","1.00000008274037e-10","1.00000000005e-10","1.00000000005e-10",">",">",">","x","=","1e-50",">",">",">","exp","(","x",")","-1",";","expm1","(","x",")",";","autoprec","(","lambda","t",":","exp","(","t",")","-1",")","(","x",")","0.0","1.0e-50","0.0","With","*","catch","*",",","an","exception","or","list","of","exceptions","to","intercept","may","be","specified",".","The","raised","exception","is","interpreted","as","signaling","insufficient","precision",".","This","permits",",","for","example",",","evaluating","a","function","where","a","too","low","precision","results","in","a","division","by","zero",":",":",">",">",">","f","=","lambda","x",":","1\/","(","exp","(","x",")","-1",")",">",">",">","f","(","1e-30",")","Traceback","(","most","recent","call","last",")",":","...","ZeroDivisionError",">",">",">","autoprec","(","f",",","catch=ZeroDivisionError",")","(","1e-30",")","1.0e+30"]
code: def autoprec(ctx, f, maxprec=None, catch=(), verbose=False):
      r"""
      Return a wrapped copy of *f* that repeatedly evaluates *f*
      with increasing precision until the result converges to the
      full precision used at the point of the call.
  
      This heuristically protects against rounding errors, at the cost of
      roughly a 2x slowdown compared to manually setting the optimal
      precision. This method can, however, easily be fooled if the results
      from *f* depend "discontinuously" on the precision, for instance
      if catastrophic cancellation can occur. Therefore, :func:`~mpmath.autoprec`
      should be used judiciously.
  
      **Examples**
  
      Many functions are sensitive to perturbations of the input arguments.
      If the arguments are decimal numbers, they may have to be converted
      to binary at a much higher precision. If the amount of required
      extra precision is unknown, :func:`~mpmath.autoprec` is convenient::
  
          >>> from mpmath import *
          >>> mp.dps = 15
          >>> mp.pretty = True
          >>> besselj(5, 125 * 10**28)    # Exact input
          -8.03284785591801e-17
          >>> besselj(5, '1.25e30')   # Bad
          7.12954868316652e-16
          >>> autoprec(besselj)(5, '1.25e30')   # Good
          -8.03284785591801e-17
  
      The following fails to converge because `\sin(\pi) = 0` whereas all
      finite-precision approximations of `\pi` give nonzero values::
  
          >>> autoprec(sin)(pi) # doctest: +IGNORE_EXCEPTION_DETAIL
          Traceback (most recent call last):
            ...
          NoConvergence: autoprec: prec increased to 2910 without convergence
  
      As the following example shows, :func:`~mpmath.autoprec` can protect against
      cancellation, but is fooled by too severe cancellation::
  
          >>> x = 1e-10
          >>> exp(x)-1; expm1(x); autoprec(lambda t: exp(t)-1)(x)
          1.00000008274037e-10
          1.00000000005e-10
          1.00000000005e-10
          >>> x = 1e-50
          >>> exp(x)-1; expm1(x); autoprec(lambda t: exp(t)-1)(x)
          0.0
          1.0e-50
          0.0
  
      With *catch*, an exception or list of exceptions to intercept
      may be specified. The raised exception is interpreted
      as signaling insufficient precision. This permits, for example,
      evaluating a function where a too low precision results in a
      division by zero::
  
          >>> f = lambda x: 1/(exp(x)-1)
          >>> f(1e-30)
          Traceback (most recent call last):
            ...
          ZeroDivisionError
          >>> autoprec(f, catch=ZeroDivisionError)(1e-30)
          1.0e+30
  
  
      """
  
      def f_autoprec_wrapped(*args, **kwargs):
          prec = ctx.prec
          if maxprec is None:
              maxprec2 = ctx._default_hyper_maxprec(prec)
          else:
              maxprec2 = maxprec
          try:
              ctx.prec = prec + 10
              try:
                  v1 = f(*args, **kwargs)
              except catch:
                  v1 = ctx.nan
              prec2 = prec + 20
              while 1:
                  ctx.prec = prec2
                  try:
                      v2 = f(*args, **kwargs)
                  except catch:
                      v2 = ctx.nan
                  if v1 == v2:
                      break
                  err = ctx.mag(v2 - v1) - ctx.mag(v2)
                  if err < (-prec):
                      break
                  if verbose:
                      print(
                          "autoprec: target=%s, prec=%s, accuracy=%s"
                          % (prec, prec2, -err)
                      )
                  v1 = v2
                  if prec2 >= maxprec2:
                      raise ctx.NoConvergence(
                          "autoprec: prec increased to %i without convergence"
                          % prec2
                      )
                  prec2 += int(prec2 * 2)
                  prec2 = min(prec2, maxprec2)
          finally:
              ctx.prec = prec
          return +v2
  
      return f_autoprec_wrapped
  
imports: import functools
  import re
  from .ctx_base import StandardBaseContext
  from .libmp.backend import basestring, BACKEND
  from .None import libmp
  from .libmp import MPZ, MPZ_ZERO, MPZ_ONE, int_types, repr_dps, round_floor, round_ceiling, dps_to_prec, round_nearest, prec_to_dps, ComplexResult, to_pickable, from_pickable, normalize, from_int, from_float, from_str, to_int, to_float, to_str, from_rational, from_man_exp, fone, fzero, finf, fninf, fnan, mpf_abs, mpf_pos, mpf_neg, mpf_add, mpf_sub, mpf_mul, mpf_mul_int, mpf_div, mpf_rdiv_int, mpf_pow_int, mpf_mod, mpf_eq, mpf_cmp, mpf_lt, mpf_gt, mpf_le, mpf_ge, mpf_hash, mpf_rand, mpf_sum, bitcount, to_fixed, mpc_to_str, mpc_to_complex, mpc_hash, mpc_pos, mpc_is_nonzero, mpc_neg, mpc_conjugate, mpc_abs, mpc_add, mpc_add_mpf, mpc_sub, mpc_sub_mpf, mpc_mul, mpc_mul_mpf, mpc_mul_int, mpc_div, mpc_div_mpf, mpc_pow, mpc_pow_mpf, mpc_pow_int, mpc_mpf_div, mpf_pow, mpf_pi, mpf_degree, mpf_e, mpf_phi, mpf_ln2, mpf_ln10, mpf_euler, mpf_catalan, mpf_apery, mpf_khinchin, mpf_glaisher, mpf_twinprime, mpf_mertens, int_types
  from .None import function_docs
  from .None import rational
  from .ctx_mp_python import _mpf, _mpc, mpnumeric
label_desc: Use image node_id 29 for calling the MPContext obj's underlying member method code with example usage: obj.autoprec(ctx, f, maxprec, catch, verbose) and returns: f_autoprec_wrapped, unknown