code: def mpf_agm(a, b, prec, rnd=round_fast):
      """
      Computes the arithmetic-geometric mean agm(a,b) for
      nonnegative mpf values a, b.
      """
      asign, aman, aexp, abc = a
      bsign, bman, bexp, bbc = b
      if asign or bsign:
          raise ComplexResult("agm of a negative number")
      # Handle inf, nan or zero in either operand
      if not (aman and bman):
          if a == fnan or b == fnan:
              return fnan
          if a == finf:
              if b == fzero:
                  return fnan
              return finf
          if b == finf:
              if a == fzero:
                  return fnan
              return finf
          # agm(0,x) = agm(x,0) = 0
          return fzero
      wp = prec + 20
      amag = aexp + abc
      bmag = bexp + bbc
      mag_delta = amag - bmag
      # Reduce to roughly the same magnitude using floating-point AGM
      abs_mag_delta = abs(mag_delta)
      if abs_mag_delta > 10:
          while abs_mag_delta > 10:
              a, b = mpf_shift(mpf_add(a, b, wp), -1), mpf_sqrt(
                  mpf_mul(a, b, wp), wp
              )
              abs_mag_delta //= 2
          asign, aman, aexp, abc = a
          bsign, bman, bexp, bbc = b
          amag = aexp + abc
          bmag = bexp + bbc
          mag_delta = amag - bmag
      # print to_float(a), to_float(b)
      # Use agm(a,b) = agm(x*a,x*b)/x to obtain a, b ~= 1
      min_mag = min(amag, bmag)
      max_mag = max(amag, bmag)
      n = 0
      # If too small, we lose precision when going to fixed-point
      if min_mag < -8:
          n = -min_mag
      # If too large, we waste time using fixed-point with large numbers
      elif max_mag > 20:
          n = -max_mag
      if n:
          a = mpf_shift(a, n)
          b = mpf_shift(b, n)
      # print to_float(a), to_float(b)
      af = to_fixed(a, wp)
      bf = to_fixed(b, wp)
      g = agm_fixed(af, bf, wp)
      return from_man_exp(g, -wp - n, prec, rnd)
  
imports: import operator
  import math
  from .backend import MPZ_ZERO, MPZ_ONE, BACKEND, xrange, exec_
  from .libintmath import gcd
  from .libmpf import ComplexResult, round_fast, round_nearest, negative_rnd, bitcount, to_fixed, from_man_exp, from_int, to_int, from_rational, fzero, fone, fnone, ftwo, finf, fninf, fnan, mpf_sign, mpf_add, mpf_abs, mpf_pos, mpf_cmp, mpf_lt, mpf_le, mpf_gt, mpf_min_max, mpf_perturb, mpf_neg, mpf_shift, mpf_sub, mpf_mul, mpf_div, sqrt_fixed, mpf_sqrt, mpf_rdiv_int, mpf_pow_int, to_rational
  from .libelefun import mpf_pi, mpf_exp, mpf_log, pi_fixed, mpf_cos_sin, mpf_cos, mpf_sin, mpf_sqrt, agm_fixed
  from .libmpc import mpc_one, mpc_sub, mpc_mul_mpf, mpc_mul, mpc_neg, complex_int_pow, mpc_div, mpc_add_mpf, mpc_sub_mpf, mpc_log, mpc_add, mpc_pos, mpc_shift, mpc_is_infnan, mpc_zero, mpc_sqrt, mpc_abs, mpc_mpf_div, mpc_square, mpc_exp
  from .libintmath import ifac
  from .gammazeta import mpf_gamma_int, mpf_euler, euler_fixed
label_desc: Use image node_id 23 for calling a global function with example usage: mpf_agm(a, b, prec, rnd) and returns: from_man_exp, fzero, fnan, finf, finf, fnan, fnan