Post Reply 
A little help understanding math....
08-26-2021, 02:31 PM (This post was last modified: 08-26-2021 06:27 PM by Albert Chan.)
Post: #7
RE: A little help understanding math....
(12-16-2013 11:56 PM)Thomas Klemm Wrote:  From \(x=cos(u)cosh(v)\) we conclude:
\[
2x=2cos(u)cosh(v) \\
cos(u)=\frac{2x}{|z+1|+|z-1|}
\]

There is an issue of recovering u from acos()
Accuracy may be bad. Worse, it might hit outside valid range (-1 ≤ cos(u) ≤ 1)
Similarly, recovering v from acosh() might hit by same issue, since cosh(v) ≥ 1

>>> z = 1.5430806348152439+0j # acos(z) = u + i*v
>>> a, b = abs(1+z), abs(1-z)
>>> V = (a+b) / 2
>>> U = z.real / V
>>> U, V                                     # U, V = cos(u), cosh(v)
(1.0000000000000002, 1.5430806348152437)

---

Kahan's algorithm avoided these problems, using atan/asinh for complex acos

From complex.c, cacos(z), https://opensource.apple.com/source/Libm....auto.html
Code:
real(cacos(z)) = 2.0*atan(real(csqrt(1.0-z)/real(csqrt(1.0+z))))
imag(cacos(z)) = arcsinh(imag(csqrt(1.0-z)*csqrt(cconj(1.0+z))))

z = x+i*y = cos(u+i*v) = cos(u)*cosh(v) - i*sin(u)*sinh(v)       ..... (1)

Let U = cos(u), V = cosh(v), we have x = U*V

Let t = tan(u/2)
Since u = acos(U) = 0 to pi, non-negative, t = |t|

cos(u) = U = (1-t^2)/(1+t^2)       → t = |t| = √((1-U)/(1+U))

Again, from the same source, for csqrt(z)
Code:
sqrt(x + i*y) = sqrt((|z| + Real(z))/2) + i*sqrt((|z| - Real(z))/2) and
sqrt(x - i*y) = sqrt((|z| + Real(z))/2) - i*sqrt((|z| - Real(z))/2)

Previously, we showed |1±z| = cosh(v) ± cos(u) = V ± U
Assumed we have sign-zero, let s = sign(imag(z)) = ± 1

√(1+z) = √(((V+U)+(1+U*V))/2) + i*s*√(((V+U)−(1+U*V))/2) = √((1+U)*(V+1)/2) + i*s*√((1−U)*(V−1)/2)
√(1−z) = √(((V−U)+(1−U*V))/2) − i*s*√(((V−U)−(1−U*V))/2) = √((1−U)*(V+1)/2) − i*s*√((1+U)*(V−1)/2)

real(√(1-z)) / real(√(1+z)) = √((1-U)/(1+U)) = t = tan(u/2)

u = atan(real(√(1-z))/real(√(1+z))) * 2

real(√(1+z)) * imag(√(1-z)) = -s * (1+U)/2 * √(V*V-1)       ..... (2)
-imag(√(1+z)) * real(√(1-z)) = -s * (1-U)/2 * √(V*V-1)       ..... (3)

(2) and (3) have the same sign, sum is free from subtraction cancellation.

(2)+(3)       → RHS = -s * √(V*V-1) = -s * |sinh(v)| = sinh(-s*|v|)

From (1), sign(v) = sign(-y) = -s:

v = asinh(real(√(1+z))*imag(√(1-z)) - imag(√(1+z)) * real(√(1-z)))

Code:
Complex Cacos(Complex z)
{
  Complex a = csqrt(1+z), b = csqrt(1-z);
  double x2 = atan (Real(b)/Real(a)) * 2;
  double y2 = asinh(Real(a)*Imag(b) - Imag(a)*Real(b));
  return CMPLX(x2, copysign(y2, -Imag(z)));
}
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: A little help understanding math.... - Albert Chan - 08-26-2021 02:31 PM



User(s) browsing this thread: 1 Guest(s)