Exemple #1
0
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;
}