def mpc_tan(z, prec, rnd=round_fast): """Complex tangent. Computed as tan(a+bi) = sin(2a)/M + sinh(2b)/M*i where M = cos(2a) + cosh(2b).""" a, b = z asign, aman, aexp, abc = a bsign, bman, bexp, bbc = b if b == fzero: return mpf_tan(a, prec, rnd), fzero if a == fzero: return fzero, mpf_tanh(b, prec, rnd) wp = prec + 15 a = mpf_shift(a, 1) b = mpf_shift(b, 1) c, s = cos_sin(a, wp) ch, sh = cosh_sinh(b, wp) # TODO: handle cancellation when c ~= -1 and ch ~= 1 mag = mpf_add(c, ch, wp) re = mpf_div(s, mag, prec, rnd) im = mpf_div(sh, mag, prec, rnd) return re, im
else: return cos_sin(x, prec, rnd) def mpf_cos_pi(x, prec, rnd=round_fast): return mpf_cos_sin_pi(x, prec, rnd)[0] def mpf_sin_pi(x, prec, rnd=round_fast): return mpf_cos_sin_pi(x, prec, rnd)[1] def mpc_cos_pi((a, b), prec, rnd=round_fast): b = mpf_mul(b, mpf_pi(prec+5), prec+5) if a == fzero: return mpf_cosh(b, prec, rnd), fzero wp = prec + 6 c, s = mpf_cos_sin_pi(a, wp) ch, sh = cosh_sinh(b, wp) re = mpf_mul(c, ch, prec, rnd) im = mpf_mul(s, sh, prec, rnd) return re, mpf_neg(im) def mpc_sin_pi((a, b), prec, rnd=round_fast): b = mpf_mul(b, mpf_pi(prec+5), prec+5) if a == fzero: return fzero, mpf_sinh(b, prec, rnd) wp = prec + 6 c, s = mpf_cos_sin_pi(a, wp) ch, sh = cosh_sinh(b, wp) re = mpf_mul(s, ch, prec, rnd) im = mpf_mul(c, sh, prec, rnd) return re, im
return mpf_log(mpc_abs(z, prec, rnd), prec, rnd), mpc_arg(z, prec, rnd) def mpc_cos((a, b), prec, rnd=round_fast): """Complex cosine. The formula used is cos(a+bi) = cos(a)*cosh(b) - sin(a)*sinh(b)*i. The same comments apply as for the complex exp: only real multiplications are pewrormed, so no cancellation errors are possible. The formula is also efficient since we can compute both pairs (cos, sin) and (cosh, sinh) in single stwps.""" if a == fzero: return mpf_cosh(b, prec, rnd), fzero wp = prec + 6 c, s = cos_sin(a, wp) ch, sh = cosh_sinh(b, wp) re = mpf_mul(c, ch, prec, rnd) im = mpf_mul(s, sh, prec, rnd) return re, mpf_neg(im) def mpc_sin((a, b), prec, rnd=round_fast): """Complex sine. We have sin(a+bi) = sin(a)*cosh(b) + cos(a)*sinh(b)*i. See the docstring for mpc_cos for additional comments.""" if a == fzero: return fzero, mpf_sinh(b, prec, rnd) wp = prec + 6 c, s = cos_sin(a, wp) ch, sh = cosh_sinh(b, wp) re = mpf_mul(s, ch, prec, rnd)