void gsl_complex_arccos (complex_t const *a, complex_t *res) { /* z = arccos(a) */ gnm_float R = GSL_REAL (a), I = GSL_IMAG (a); if (I == 0) { gsl_complex_arccos_real (R, res); } else { gnm_float x = gnm_abs (R); gnm_float y = gnm_abs (I); gnm_float r = gnm_hypot (x + 1, y); gnm_float s = gnm_hypot (x - 1, y); gnm_float A = 0.5 * (r + s); gnm_float B = x / A; gnm_float y2 = y * y; gnm_float real, imag; const gnm_float A_crossover = 1.5; const gnm_float B_crossover = 0.6417; if (B <= B_crossover) { real = gnm_acos (B); } else { if (x <= 1) { gnm_float D = 0.5 * (A + x) * (y2 / (r + x + 1) + (s + (1 - x))); real = gnm_atan (gnm_sqrt (D) / x); } else { gnm_float Apx = A + x; gnm_float D = 0.5 * (Apx / (r + x + 1) + Apx / (s + (x - 1))); real = gnm_atan ((y * gnm_sqrt (D)) / x); } } if (A <= A_crossover) { gnm_float Am1; if (x < 1) { Am1 = 0.5 * (y2 / (r + (x + 1)) + y2 / (s + (1 - x))); } else { Am1 = 0.5 * (y2 / (r + (x + 1)) + (s + (x - 1))); } imag = gnm_log1p (Am1 + gnm_sqrt (Am1 * (A + 1))); } else { imag = gnm_log (A + gnm_sqrt (A * A - 1)); } complex_init (res, (R >= 0) ? real : M_PIgnum - real, (I >= 0) ? -imag : imag); } }
gsl_complex gsl_complex_arccos(gsl_complex a) { /* z = arccos(a) */ double R = GSL_REAL(a), I = GSL_IMAG(a); gsl_complex z; if (I == 0) { z = gsl_complex_arccos_real(R); } else { double x = fabs(R), y = fabs(I); double r = hypot(x + 1, y), s = hypot(x - 1, y); double A = 0.5 * (r + s); double B = x / A; double y2 = y * y; double real, imag; const double A_crossover = 1.5, B_crossover = 0.6417; if (B <= B_crossover) { real = acos(B); } else { if (x <= 1) { double D = 0.5 * (A + x) * (y2 / (r + x + 1) + (s + (1 - x))); real = atan(sqrt(D) / x); } else { double Apx = A + x; double D = 0.5 * (Apx / (r + x + 1) + Apx / (s + (x - 1))); real = atan((y * sqrt(D)) / x); } } if (A <= A_crossover) { double Am1; if (x < 1) { Am1 = 0.5 * (y2 / (r + (x + 1)) + y2 / (s + (1 - x))); } else { Am1 = 0.5 * (y2 / (r + (x + 1)) + (s + (x - 1))); } imag = log1p(Am1 + sqrt(Am1 * (A + 1))); } else { imag = log(A + sqrt(A * A - 1)); } GSL_SET_COMPLEX(&z, (R >= 0) ? real : M_PI - real, (I >= 0) ? -imag : imag); } return z; }