namespace cln {
-// Hilfsfunktion für atanh und atan: u+iv := artanh(x+iy). Liefert cl_C_R(u,v).
+// Hilfsfunktion für atanh und atan: u+iv := artanh(x+iy). Liefert cl_C_R(u,v).
const cl_C_R atanh (const cl_R& x, const cl_R& y)
{
// =0 -> Error,
// >0 (also |x|<1) -> u = 1/2 log((1+x)/(1-x)), v = 0.
// <0 (also |x|>1) -> u = 1/2 log(-(1+x)/(1-x)),
-// v = (-pi/2 für x>1, pi/2 für x<-1).
+// v = (-pi/2 für x>1, pi/2 für x<-1).
// Sonst:
// 1+x und 1-x errechnen.
// x und y in Floats umwandeln.
// |4x| und 1+x^2+y^2 errechnen,
// |4x| < 1+x^2+y^2 -> u = 1/2 atanh(2x/(1+x^2+y^2)),
// |4x| >= 1+x^2+y^2 -> u = 1/4 ln ((1+x^2+y^2)+2x)/((1+x^2+y^2)-2x)
-// oder besser (an der Singularität: |x|-1,|y| klein):
+// oder besser (an der Singularität: |x|-1,|y| klein):
// u = 1/4 ln ((1+x)^2+y^2)/((1-x)^2+y^2).
// v = 1/2 atan(X=(1-x)(1+x)-y^2,Y=2y) * (-1 falls Y=0.0 und X<0.0 und x>=0.0,
// 1 sonst)
// Ergebnis ist reell nur, wenn z reell.
-// Real- und Imaginärteil des Ergebnisses sind Floats, außer wenn z reell oder
-// rein imaginär ist.
+// Real- und Imaginärteil des Ergebnisses sind Floats, außer wenn z reell oder
+// rein imaginär ist.
if (eq(x,0))
// x=0 -> u=0, v=atan(X=1,Y=y) (Fall y=0 ist inbegriffen)
var cl_R v;
if (!minusp(xx)) {
if (zerop(xx))
- { cl_error_division_by_0(); }
+ { throw division_by_0_exception(); }
v = 0;
} else {
- // (1+x)/(1-x) < 0 -> Betrag nehmen, Imaginärteil berechnen:
+ // (1+x)/(1-x) < 0 -> Betrag nehmen, Imaginärteil berechnen:
xx = - xx;
v = scale_float(pi(),-1); // (scale-float pi -1) = pi/2
if (minusp(xx_den))
var cl_F num = _1_plus_x*_1_plus_x + yf_2; // (1+x)^2+y^2, ein Float >=0
var cl_F den = _1_minus_x*_1_minus_x + yf_2; // (1-x)^2+y^2, ein Float >=0
if (zerop(den))
- { cl_error_division_by_0(); }
+ { throw division_by_0_exception(); }
u = scale_float(ln(num/den),-2);
}
}