def mpi_atan2(y, x, prec): ya, yb = y xa, xb = x # Constrained to the real line if ya == yb == fzero: if mpf_ge(xa, fzero): return mpi_zero return mpi_pi(prec) # Right half-plane if mpf_ge(xa, fzero): if mpf_ge(ya, fzero): a = mpf_atan2(ya, xb, prec, round_floor) else: a = mpf_atan2(ya, xa, prec, round_floor) if mpf_ge(yb, fzero): b = mpf_atan2(yb, xa, prec, round_ceiling) else: b = mpf_atan2(yb, xb, prec, round_ceiling) # Upper half-plane elif mpf_ge(ya, fzero): b = mpf_atan2(ya, xa, prec, round_ceiling) if mpf_le(xb, fzero): a = mpf_atan2(yb, xb, prec, round_floor) else: a = mpf_atan2(ya, xb, prec, round_floor) # Lower half-plane elif mpf_le(yb, fzero): a = mpf_atan2(yb, xa, prec, round_floor) if mpf_le(xb, fzero): b = mpf_atan2(ya, xb, prec, round_ceiling) else: b = mpf_atan2(yb, xb, prec, round_ceiling) # Covering the origin else: b = mpf_pi(prec, round_ceiling) a = mpf_neg(b) return a, b
def mpc_arg(z, prec, rnd=round_fast): """Argument of a complex number. Returns an mpf value.""" a, b = z return mpf_atan2(b, a, prec, rnd)
return mpf_pos(a, prec, rnd), mpf_pos(b, prec, rnd) def mpc_neg((a, b), prec=None, rnd=round_fast): return mpf_neg(a, prec, rnd), mpf_neg(b, prec, rnd) def mpc_shift((a, b), n): return mpf_shift(a, n), mpf_shift(b, n) def mpc_abs((a, b), prec, rnd=round_fast): """Absolute value of a complex number, |a+bi|. Returns an mpf value.""" return mpf_hypot(a, b, prec, rnd) def mpc_arg((a, b), prec, rnd=round_fast): """Argument of a complex number. Returns an mpf value.""" return mpf_atan2(b, a, prec, rnd) def mpc_floor((a, b), prec, rnd=round_fast): return mpf_floor(a, prec, rnd), mpf_floor(b, prec, rnd) def mpc_ceil((a, b), prec, rnd=round_fast): return mpf_ceil(a, prec, rnd), mpf_ceil(b, prec, rnd) def mpc_mul((a, b), (c, d), prec, rnd=round_fast): """Complex multiplication. Returns the real and imaginary part of (a+bi)*(c+di), rounded to the specified precision. The rounding mode applies to the real and imaginary parts separately.""" asign, aman, aexp, abc = a
def atan2(ctx, y, x): x = ctx.convert(x) y = ctx.convert(y) return ctx.make_mpf(libelefun.mpf_atan2(y._mpf_, x._mpf_, *ctx._prec_rounding))
def atan2(y,x): """atan2(y, x) has the same magnitude as atan(y/x) but accounts for the signs of y and x. (Defined for real x and y only.)""" x = convert_lossless(x) y = convert_lossless(y) return make_mpf(libelefun.mpf_atan2(y._mpf_, x._mpf_, *prec_rounding))
return mpf_neg(a, prec, rnd), mpf_neg(b, prec, rnd) def mpc_shift((a, b), n): return mpf_shift(a, n), mpf_shift(b, n) def mpc_abs((a, b), prec, rnd=round_fast): """Absolute value of a complex number, |a+bi|. Returns an mpf value.""" return mpf_hypot(a, b, prec, rnd) def mpc_arg((a, b), prec, rnd=round_fast): """Argument of a complex number. Returns an mpf value.""" return mpf_atan2(b, a, prec, rnd) def mpc_floor((a, b), prec, rnd=round_fast): return mpf_floor(a, prec, rnd), mpf_floor(b, prec, rnd) def mpc_ceil((a, b), prec, rnd=round_fast): return mpf_ceil(a, prec, rnd), mpf_ceil(b, prec, rnd) def mpc_mul((a, b), (c, d), prec, rnd=round_fast): """Complex multiplication. Returns the real and imaginary part of (a+bi)*(c+di), rounded to the specified precision. The rounding mode applies to the real and
def atan2(y, x): """atan2(y, x) has the same magnitude as atan(y/x) but accounts for the signs of y and x. (Defined for real x and y only.)""" x = convert_lossless(x) y = convert_lossless(y) return make_mpf(libelefun.mpf_atan2(y._mpf_, x._mpf_, *prec_rounding))
def atan2(ctx, y, x): x = ctx.convert(x) y = ctx.convert(y) return ctx.make_mpf( libelefun.mpf_atan2(y._mpf_, x._mpf_, *ctx._prec_rounding))