2 #if A_PREREQ_GNUC(3, 0)
3 #pragma GCC diagnostic ignored "-Wfloat-conversion"
4 #endif /* -Wfloat-conversion */
5 #if A_PREREQ_GNUC(3, 0) || __has_warning("-Wfloat-equal")
6 #pragma GCC diagnostic ignored "-Wfloat-equal"
7 #endif /* -Wfloat-equal */
10 /* compiler built-in complex number type */
11 #if A_PREREQ_MSVC(18, 0)
12 #include <complex.h> /* 12.0 */
13 #if A_FLOAT_TYPE + 0 == A_FLOAT_SINGLE
14 #define A_COMPLEX _Fcomplex
15 #elif A_FLOAT_TYPE + 0 == A_FLOAT_DOUBLE
16 #define A_COMPLEX _Dcomplex
17 #elif A_FLOAT_TYPE + 0 == A_FLOAT_EXTEND
18 #define A_COMPLEX _Lcomplex
19 #endif /* A_COMPLEX */
20 #elif defined(__GNUC__) || defined(__clang__)
22 #define A_COMPLEX _Complex A_FLOAT
23 #else /* !A_FLOAT_TYPE */
24 #if A_PREREQ_GNUC(2, 95) || __has_warning("-Waggregate-return")
25 #pragma GCC diagnostic ignored "-Waggregate-return"
26 #endif /* -Waggregate-return */
27 #endif /* A_FLOAT_TYPE */
31 void a_complex_polar(a_complex
*ctx
, a_float rho
, a_float theta
)
33 ctx
->real
= rho
* a_float_cos(theta
);
34 ctx
->imag
= rho
* a_float_sin(theta
);
37 unsigned int a_complex_parse(a_complex
*ctx
, char const *str
)
39 #if A_FLOAT_TYPE + 0 == A_FLOAT_SINGLE
40 #define strtonum(string, endptr) strtof(string, endptr)
41 #elif A_FLOAT_TYPE + 0 == A_FLOAT_DOUBLE
42 #define strtonum(string, endptr) strtod(string, endptr)
43 #elif A_FLOAT_TYPE + 0 == A_FLOAT_EXTEND
44 #define strtonum(string, endptr) strtold(string, endptr)
45 #endif /* A_FLOAT_TYPE */
52 if (!str
) { return 0; }
53 for (ctx
->real
= 0; *u
.s
; ++u
.s
)
55 if (*u
.s
== '+' || *u
.s
== '-' || ('0' <= *u
.s
&& *u
.s
<= '9') || *u
.s
== '.')
57 ctx
->real
= strtonum(u
.s
, &u
.p
);
61 for (ctx
->imag
= 0; *u
.s
; ++u
.s
)
63 if (*u
.s
== '+' || *u
.s
== '-' || ('0' <= *u
.s
&& *u
.s
<= '9') || *u
.s
== '.')
65 ctx
->imag
= strtonum(u
.s
, &u
.p
);
69 return (unsigned int)(u
.s
- str
);
72 a_bool
a_complex_eq(a_complex x
, a_complex y
)
74 return x
.real
== y
.real
&& x
.imag
== y
.imag
;
77 a_bool
a_complex_ne(a_complex x
, a_complex y
)
79 return x
.real
!= y
.real
|| x
.imag
!= y
.imag
;
82 a_float
a_complex_logabs(a_complex z
)
85 a_float
const xabs
= a_float_abs(z
.real
);
86 a_float
const yabs
= a_float_abs(z
.imag
);
97 return a_float_log(r
) + A_FLOAT_C(0.5) * a_float_log1p(u
* u
);
100 a_float
a_complex_abs2(a_complex z
)
102 return z
.real
* z
.real
+ z
.imag
* z
.imag
;
105 a_float
a_complex_abs(a_complex z
)
107 return a_float_hypot(z
.real
, z
.imag
);
110 a_float
a_complex_arg(a_complex z
)
112 if (z
.real
!= 0 || z
.imag
!= 0)
114 return a_float_atan2(z
.imag
, z
.real
);
119 void a_complex_proj_(a_complex
*ctx
)
121 if (isinf(ctx
->real
) || isinf(ctx
->imag
))
123 ctx
->real
= A_FLOAT_INF
;
124 ctx
->imag
= a_float_copysign(0, ctx
->imag
);
128 void a_complex_mul_(a_complex
*ctx
, a_complex z
)
130 a_float
const real
= ctx
->real
;
131 ctx
->real
= real
* z
.real
- ctx
->imag
* z
.imag
;
132 ctx
->imag
= real
* z
.imag
+ ctx
->imag
* z
.real
;
135 void a_complex_div_(a_complex
*ctx
, a_complex z
)
137 a_float
const inv
= 1 / a_complex_abs(z
);
138 a_float
const xr
= ctx
->real
* inv
;
139 a_float
const xi
= ctx
->imag
* inv
;
140 a_float
const yr
= z
.real
* inv
;
141 a_float
const yi
= z
.imag
* inv
;
142 ctx
->real
= xr
* yr
+ xi
* yi
;
143 ctx
->imag
= xi
* yr
- xr
* yi
;
146 void a_complex_inv_(a_complex
*ctx
)
148 a_float
const inv
= 1 / a_complex_abs(*ctx
);
149 ctx
->real
= +inv
* ctx
->real
* inv
;
150 ctx
->imag
= -inv
* ctx
->imag
* inv
;
153 #if A_PREREQ_GNUC(2, 95) || __has_warning("-Wimplicit-function-declaration")
154 #pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
155 #endif /* gcc 2.95+ */
156 #if __has_warning("-Wincompatible-library-redeclaration")
157 #pragma clang diagnostic ignored "-Wincompatible-library-redeclaration"
158 #endif /* clang 4.0+ */
159 #if A_PREREQ_GNUC(10, 0)
160 #pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
161 #endif /* gcc 10.0+ */
163 #if defined(A_HAVE_CSQRT) && (A_HAVE_CSQRT + 0 < 1)
165 #endif /* A_HAVE_CSQRT */
166 #if defined(A_HAVE_CSQRT) && !defined A_COMPLEX
167 a_complex
A_FLOAT_F(csqrt
)(a_complex
);
168 #endif /* A_HAVE_CSQRT */
169 void a_complex_sqrt_(a_complex
*ctx
)
171 #if defined(A_HAVE_CSQRT) && defined(A_COMPLEX)
172 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
173 *x
= A_FLOAT_F(csqrt
)(*x
);
174 #elif defined(A_HAVE_CSQRT)
175 *ctx
= A_FLOAT_F(csqrt
)(*ctx
);
176 #else /* !A_HAVE_CSQRT */
177 if (ctx
->real
!= 0 || ctx
->imag
!= 0)
179 a_float
const x
= a_float_abs(ctx
->real
);
180 a_float
const y
= a_float_abs(ctx
->imag
);
185 w
= A_FLOAT_SQRT1_2
* a_float_sqrt(x
) * a_float_sqrt(a_float_sqrt(u
* u
+ 1) + 1);
190 w
= A_FLOAT_SQRT1_2
* a_float_sqrt(y
) * a_float_sqrt(a_float_sqrt(u
* u
+ 1) + u
);
195 ctx
->imag
= ctx
->imag
/ (2 * w
);
199 ctx
->real
= ctx
->imag
/ (2 * w
);
200 ctx
->imag
= ctx
->imag
< 0 ? -w
: w
;
203 #endif /* A_HAVE_CSQRT */
206 void a_complex_sqrt_real(a_complex
*ctx
, a_float x
)
210 ctx
->real
= a_float_sqrt(x
);
216 ctx
->imag
= a_float_sqrt(-x
);
220 #if defined(A_HAVE_CPOW) && (A_HAVE_CPOW + 0 < 1)
222 #endif /* A_HAVE_CPOW */
223 #if defined(A_HAVE_CPOW) && !defined A_COMPLEX
224 a_complex
A_FLOAT_F(cpow
)(a_complex
, a_complex
);
225 #endif /* A_HAVE_CPOW */
226 void a_complex_pow_(a_complex
*ctx
, a_complex a
)
228 #if defined(A_HAVE_CPOW) && defined(A_COMPLEX)
229 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
230 A_COMPLEX
*const y
= (A_COMPLEX
*)&a
;
231 *x
= A_FLOAT_F(cpow
)(*x
, *y
);
232 #elif defined(A_HAVE_CPOW)
233 *ctx
= A_FLOAT_F(cpow
)(*ctx
, a
);
234 #else /* !A_HAVE_CPOW */
235 if (ctx
->real
!= 0 || ctx
->imag
!= 0)
237 a_float
const logr
= a_complex_logabs(*ctx
);
238 a_float
const theta
= a_complex_arg(*ctx
);
239 a_float
const rho
= a_float_exp(logr
* a
.real
- theta
* a
.imag
);
240 a_float
const beta
= theta
* a
.real
+ logr
* a
.imag
;
241 a_complex_polar(ctx
, rho
, beta
);
245 ctx
->real
= (a
.real
== 0 && a
.imag
== 0) ? 1 : 0;
247 #endif /* A_HAVE_CPOW */
250 void a_complex_pow_real_(a_complex
*ctx
, a_float a
)
252 if (ctx
->real
!= 0 || ctx
->imag
!= 0)
254 a_float
const logr
= a_complex_logabs(*ctx
);
255 a_float
const theta
= a_complex_arg(*ctx
);
256 a_float
const rho
= a_float_exp(logr
* a
);
257 a_float
const beta
= theta
* a
;
258 a_complex_polar(ctx
, rho
, beta
);
262 ctx
->real
= (a
== 0) ? 1 : 0;
266 #if defined(A_HAVE_CEXP) && (A_HAVE_CEXP + 0 < 1)
268 #endif /* A_HAVE_CEXP */
269 #if defined(A_HAVE_CEXP) && !defined A_COMPLEX
270 a_complex
A_FLOAT_F(cexp
)(a_complex
);
271 #endif /* A_HAVE_CEXP */
272 void a_complex_exp_(a_complex
*ctx
)
274 #if defined(A_HAVE_CEXP) && defined(A_COMPLEX)
275 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
276 *x
= A_FLOAT_F(cexp
)(*x
);
277 #elif defined(A_HAVE_CEXP)
278 *ctx
= A_FLOAT_F(cexp
)(*ctx
);
279 #else /* !A_HAVE_CEXP */
280 a_complex_polar(ctx
, a_float_exp(ctx
->real
), ctx
->imag
);
281 #endif /* A_HAVE_CEXP */
284 #if defined(A_HAVE_CLOG) && (A_HAVE_CLOG + 0 < 1)
286 #endif /* A_HAVE_CLOG */
287 #if defined(A_HAVE_CLOG) && !defined A_COMPLEX
288 a_complex
A_FLOAT_F(clog
)(a_complex
);
289 #endif /* A_HAVE_CLOG */
290 void a_complex_log_(a_complex
*ctx
)
292 #if defined(A_HAVE_CLOG) && defined(A_COMPLEX)
293 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
294 *x
= A_FLOAT_F(clog
)(*x
);
295 #elif defined(A_HAVE_CLOG)
296 *ctx
= A_FLOAT_F(clog
)(*ctx
);
297 #else /* !A_HAVE_CLOG */
298 ctx
->real
= a_complex_logabs(*ctx
);
299 ctx
->imag
= a_complex_arg(*ctx
);
300 #endif /* A_HAVE_CLOG */
303 void a_complex_log2_(a_complex
*ctx
)
306 a_complex_mul_real_(ctx
, A_FLOAT_LN1_2
);
309 void a_complex_log10_(a_complex
*ctx
)
312 a_complex_mul_real_(ctx
, A_FLOAT_LN1_10
);
315 void a_complex_logb_(a_complex
*ctx
, a_complex b
)
319 a_complex_div_(ctx
, b
);
322 #if defined(A_HAVE_CSIN) && (A_HAVE_CSIN + 0 < 1)
324 #endif /* A_HAVE_CSIN */
325 #if defined(A_HAVE_CSIN) && !defined A_COMPLEX
326 a_complex
A_FLOAT_F(csin
)(a_complex
);
327 #endif /* A_HAVE_CSIN */
328 void a_complex_sin_(a_complex
*ctx
)
330 #if defined(A_HAVE_CSIN) && defined(A_COMPLEX)
331 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
332 *x
= A_FLOAT_F(csin
)(*x
);
333 #elif defined(A_HAVE_CSIN)
334 *ctx
= A_FLOAT_F(csin
)(*ctx
);
335 #else /* !A_HAVE_CSIN */
338 a_float
const real
= ctx
->real
;
339 ctx
->real
= a_float_sin(real
) * a_float_cosh(ctx
->imag
);
340 ctx
->imag
= a_float_cos(real
) * a_float_sinh(ctx
->imag
);
344 ctx
->real
= a_float_sin(ctx
->real
);
346 #endif /* A_HAVE_CSIN */
349 #if defined(A_HAVE_CCOS) && (A_HAVE_CCOS + 0 < 1)
351 #endif /* A_HAVE_CCOS */
352 #if defined(A_HAVE_CCOS) && !defined A_COMPLEX
353 a_complex
A_FLOAT_F(ccos
)(a_complex
);
354 #endif /* A_HAVE_CCOS */
355 void a_complex_cos_(a_complex
*ctx
)
357 #if defined(A_HAVE_CCOS) && defined(A_COMPLEX)
358 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
359 *x
= A_FLOAT_F(ccos
)(*x
);
360 #elif defined(A_HAVE_CCOS)
361 *ctx
= A_FLOAT_F(ccos
)(*ctx
);
362 #else /* !A_HAVE_CCOS */
365 a_float
const real
= ctx
->real
;
366 ctx
->real
= a_float_cos(real
) * a_float_cosh(+ctx
->imag
);
367 ctx
->imag
= a_float_sin(real
) * a_float_sinh(-ctx
->imag
);
371 ctx
->real
= a_float_cos(ctx
->real
);
373 #endif /* A_HAVE_CCOS */
376 #if defined(A_HAVE_CTAN) && (A_HAVE_CTAN + 0 < 1)
378 #endif /* A_HAVE_CTAN */
379 #if defined(A_HAVE_CTAN) && !defined A_COMPLEX
380 a_complex
A_FLOAT_F(ctan
)(a_complex
);
381 #endif /* A_HAVE_CTAN */
382 void a_complex_tan_(a_complex
*ctx
)
384 #if defined(A_HAVE_CTAN) && defined(A_COMPLEX)
385 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
386 *x
= A_FLOAT_F(ctan
)(*x
);
387 #elif defined(A_HAVE_CTAN)
388 *ctx
= A_FLOAT_F(ctan
)(*ctx
);
389 #else /* !A_HAVE_CTAN */
390 a_float
const cr
= a_float_cos(ctx
->real
);
391 a_float
const si
= a_float_sinh(ctx
->imag
);
392 a_float
const den
= cr
* cr
+ si
* si
;
393 ctx
->real
= A_FLOAT_C(0.5) * a_float_sin(2 * ctx
->real
) / den
;
394 if (a_float_abs(ctx
->imag
) < 1)
396 ctx
->imag
= A_FLOAT_C(0.5) * a_float_sinh(2 * ctx
->imag
) / den
;
400 a_float
const d
= a_float_pow(cr
/ si
, 2) + 1;
401 ctx
->imag
= 1 / (a_float_tanh(ctx
->imag
) * d
);
403 #endif /* A_HAVE_CTAN */
406 void a_complex_sec_(a_complex
*ctx
)
412 void a_complex_csc_(a_complex
*ctx
)
418 void a_complex_cot_(a_complex
*ctx
)
424 #if defined(A_HAVE_CASIN) && (A_HAVE_CASIN + 0 < 1)
426 #endif /* A_HAVE_CASIN */
427 #if defined(A_HAVE_CASIN) && !defined A_COMPLEX
428 a_complex
A_FLOAT_F(casin
)(a_complex
);
429 #endif /* A_HAVE_CASIN */
430 void a_complex_asin_(a_complex
*ctx
)
432 #if defined(A_HAVE_CASIN) && defined(A_COMPLEX)
433 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
434 *x
= A_FLOAT_F(casin
)(*x
);
435 #elif defined(A_HAVE_CASIN)
436 *ctx
= A_FLOAT_F(casin
)(*ctx
);
437 #else /* !A_HAVE_CASIN */
440 a_float
const a_crossover
= A_FLOAT_C(1.5);
441 a_float
const b_crossover
= A_FLOAT_C(0.6417);
442 a_float
const x
= a_float_abs(ctx
->real
);
443 a_float
const y
= a_float_abs(ctx
->imag
);
444 a_float
const r
= a_float_hypot(x
+ 1, y
);
445 a_float
const s
= a_float_hypot(x
- 1, y
);
446 a_float
const a
= A_FLOAT_C(0.5) * (r
+ s
);
447 a_float
const b
= x
/ a
;
448 a_float
const y2
= y
* y
;
449 a_float
const real
= ctx
->real
;
450 a_float
const imag
= ctx
->imag
;
451 if (b
<= b_crossover
)
453 ctx
->real
= a_float_asin(b
);
457 a_float
const den
= A_FLOAT_C(0.5) * (a
+ x
) * (y2
/ (r
+ x
+ 1) + (s
+ 1 - x
));
458 ctx
->real
= a_float_atan(x
/ a_float_sqrt(den
));
462 a_float
const apx
= a
+ x
;
463 a_float
const den
= A_FLOAT_C(0.5) * (apx
/ (r
+ x
+ 1) + apx
/ (s
+ x
- 1));
464 ctx
->real
= a_float_atan(x
/ (a_float_sqrt(den
) * y
));
466 if (a
<= a_crossover
)
471 am1
= A_FLOAT_C(0.5) * (y2
/ (r
+ x
+ 1) + y2
/ (s
+ 1 - x
));
475 am1
= A_FLOAT_C(0.5) * (y2
/ (r
+ x
+ 1) + (s
+ x
- 1));
477 ctx
->imag
= a_float_log1p(am1
+ a_float_sqrt((a
+ 1) * am1
));
481 ctx
->imag
= a_float_log(a
+ a_float_sqrt(a
* a
- 1));
483 if (real
< 0) { ctx
->real
= -ctx
->real
; }
484 if (imag
< 0) { ctx
->imag
= -ctx
->imag
; }
488 a_complex_asin_real(ctx
, ctx
->real
);
490 #endif /* A_HAVE_CASIN */
493 void a_complex_asin_real(a_complex
*ctx
, a_float x
)
495 if (a_float_abs(x
) <= 1)
497 ctx
->real
= a_float_asin(x
);
504 ctx
->real
= +A_FLOAT_PI_2
;
505 ctx
->imag
= -a_float_acosh(+x
);
509 ctx
->real
= -A_FLOAT_PI_2
;
510 ctx
->imag
= +a_float_acosh(-x
);
515 #if defined(A_HAVE_CACOS) && (A_HAVE_CACOS + 0 < 1)
517 #endif /* A_HAVE_CACOS */
518 #if defined(A_HAVE_CACOS) && !defined A_COMPLEX
519 a_complex
A_FLOAT_F(cacos
)(a_complex
);
520 #endif /* A_HAVE_CACOS */
521 void a_complex_acos_(a_complex
*ctx
)
523 #if defined(A_HAVE_CACOS) && defined(A_COMPLEX)
524 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
525 *x
= A_FLOAT_F(cacos
)(*x
);
526 #elif defined(A_HAVE_CACOS)
527 *ctx
= A_FLOAT_F(cacos
)(*ctx
);
528 #else /* !A_HAVE_CACOS */
531 a_float
const a_crossover
= A_FLOAT_C(1.5);
532 a_float
const b_crossover
= A_FLOAT_C(0.6417);
533 a_float
const x
= a_float_abs(ctx
->real
);
534 a_float
const y
= a_float_abs(ctx
->imag
);
535 a_float
const r
= a_float_hypot(x
+ 1, y
);
536 a_float
const s
= a_float_hypot(x
- 1, y
);
537 a_float
const a
= A_FLOAT_C(0.5) * (r
+ s
);
538 a_float
const b
= x
/ a
;
539 a_float
const y2
= y
* y
;
540 a_float
const real
= ctx
->real
;
541 a_float
const imag
= ctx
->imag
;
542 if (b
<= b_crossover
)
544 ctx
->real
= a_float_acos(b
);
548 a_float
const den
= A_FLOAT_C(0.5) * (a
+ x
) * (y2
/ (r
+ x
+ 1) + (s
+ 1 - x
));
549 ctx
->real
= a_float_atan(a_float_sqrt(den
) / x
);
553 a_float
const apx
= a
+ x
;
554 a_float
const den
= A_FLOAT_C(0.5) * (apx
/ (r
+ x
+ 1) + apx
/ (s
+ x
- 1));
555 ctx
->real
= a_float_atan(a_float_sqrt(den
) * y
/ x
);
557 if (a
<= a_crossover
)
562 am1
= A_FLOAT_C(0.5) * (y2
/ (r
+ x
+ 1) + y2
/ (s
+ 1 - x
));
566 am1
= A_FLOAT_C(0.5) * (y2
/ (r
+ x
+ 1) + (s
+ x
- 1));
568 ctx
->imag
= a_float_log1p(am1
+ a_float_sqrt((a
+ 1) * am1
));
572 ctx
->imag
= a_float_log(a
+ a_float_sqrt(a
* a
- 1));
574 if (real
< 0) { ctx
->real
= A_FLOAT_PI
- ctx
->real
; }
575 if (imag
>= 0) { ctx
->imag
= -ctx
->imag
; }
579 a_complex_acos_real(ctx
, ctx
->real
);
581 #endif /* A_HAVE_CACOS */
584 void a_complex_acos_real(a_complex
*ctx
, a_float x
)
586 if (a_float_abs(x
) <= 1)
588 ctx
->real
= a_float_acos(x
);
596 ctx
->imag
= +a_float_acosh(+x
);
600 ctx
->real
= A_FLOAT_PI
;
601 ctx
->imag
= -a_float_acosh(-x
);
606 #if defined(A_HAVE_CATAN) && (A_HAVE_CATAN + 0 < 1)
608 #endif /* A_HAVE_CATAN */
609 #if defined(A_HAVE_CATAN) && !defined A_COMPLEX
610 a_complex
A_FLOAT_F(catan
)(a_complex
);
611 #endif /* A_HAVE_CATAN */
612 void a_complex_atan_(a_complex
*ctx
)
614 #if defined(A_HAVE_CATAN) && defined(A_COMPLEX)
615 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
616 *x
= A_FLOAT_F(catan
)(*x
);
617 #elif defined(A_HAVE_CATAN)
618 *ctx
= A_FLOAT_F(catan
)(*ctx
);
619 #else /* !A_HAVE_CATAN */
622 a_float
const r
= a_float_hypot(ctx
->real
, ctx
->imag
);
623 a_float
const u
= 2 * ctx
->imag
/ (r
* r
+ 1);
624 a_float
const imag
= ctx
->imag
;
625 if (a_float_abs(u
) < A_FLOAT_C(0.1))
627 ctx
->imag
= A_FLOAT_C(0.25) * (a_float_log1p(u
) - a_float_log1p(-u
));
631 a_float
const a
= a_float_hypot(ctx
->real
, ctx
->imag
+ 1);
632 a_float
const b
= a_float_hypot(ctx
->real
, ctx
->imag
- 1);
633 ctx
->imag
= A_FLOAT_C(0.5) * a_float_log(a
/ b
);
637 ctx
->real
= A_FLOAT_C(0.5) * a_float_atan2(2 * ctx
->real
, (1 + r
) * (1 - r
));
643 ctx
->real
= +A_FLOAT_PI
;
647 ctx
->real
= -A_FLOAT_PI
;
657 ctx
->real
= a_float_atan(ctx
->real
);
659 #endif /* A_HAVE_CATAN */
662 void a_complex_asec_(a_complex
*ctx
)
665 a_complex_acos_(ctx
);
668 void a_complex_asec_real(a_complex
*ctx
, a_float x
)
670 if (x
<= -1 || x
>= 1)
672 ctx
->real
= a_float_acos(1 / x
);
680 ctx
->imag
= +a_float_acosh(+1 / x
);
684 ctx
->real
= A_FLOAT_PI
;
685 ctx
->imag
= -a_float_acosh(-1 / x
);
690 void a_complex_acsc_(a_complex
*ctx
)
693 a_complex_asin_(ctx
);
696 void a_complex_acsc_real(a_complex
*ctx
, a_float x
)
698 if (x
<= -1 || x
>= 1)
700 ctx
->real
= a_float_asin(1 / x
);
707 ctx
->real
= +A_FLOAT_PI_2
;
708 ctx
->imag
= -a_float_acosh(+1 / x
);
712 ctx
->real
= -A_FLOAT_PI_2
;
713 ctx
->imag
= +a_float_acosh(-1 / x
);
718 void a_complex_acot_(a_complex
*ctx
)
720 if (ctx
->real
!= 0 || ctx
->imag
!= 0)
723 a_complex_atan_(ctx
);
727 ctx
->real
= A_FLOAT_PI_2
;
731 #if defined(A_HAVE_CSINH) && (A_HAVE_CSINH + 0 < 1)
733 #endif /* A_HAVE_CSINH */
734 #if defined(A_HAVE_CSINH) && !defined A_COMPLEX
735 a_complex
A_FLOAT_F(csinh
)(a_complex
);
736 #endif /* A_HAVE_CSINH */
737 void a_complex_sinh_(a_complex
*ctx
)
739 #if defined(A_HAVE_CSINH) && defined(A_COMPLEX)
740 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
741 *x
= A_FLOAT_F(csinh
)(*x
);
742 #elif defined(A_HAVE_CSINH)
743 *ctx
= A_FLOAT_F(csinh
)(*ctx
);
744 #else /* !A_HAVE_CSINH */
745 a_float
const real
= ctx
->real
;
746 ctx
->real
= a_float_sinh(real
) * a_float_cos(ctx
->imag
);
747 ctx
->imag
= a_float_cosh(real
) * a_float_sin(ctx
->imag
);
748 #endif /* A_HAVE_CSINH */
751 #if defined(A_HAVE_CCOSH) && (A_HAVE_CCOSH + 0 < 1)
753 #endif /* A_HAVE_CCOSH */
754 #if defined(A_HAVE_CCOSH) && !defined A_COMPLEX
755 a_complex
A_FLOAT_F(ccosh
)(a_complex
);
756 #endif /* A_HAVE_CCOSH */
757 void a_complex_cosh_(a_complex
*ctx
)
759 #if defined(A_HAVE_CCOSH) && defined(A_COMPLEX)
760 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
761 *x
= A_FLOAT_F(ccosh
)(*x
);
762 #elif defined(A_HAVE_CCOSH)
763 *ctx
= A_FLOAT_F(ccosh
)(*ctx
);
764 #else /* !A_HAVE_CCOSH */
765 a_float
const real
= ctx
->real
;
766 ctx
->real
= a_float_cosh(real
) * a_float_cos(ctx
->imag
);
767 ctx
->imag
= a_float_sinh(real
) * a_float_sin(ctx
->imag
);
768 #endif /* A_HAVE_CCOSH */
771 #if defined(A_HAVE_CTANH) && (A_HAVE_CTANH + 0 < 1)
773 #endif /* A_HAVE_CTANH */
774 #if defined(A_HAVE_CTANH) && !defined A_COMPLEX
775 a_complex
A_FLOAT_F(ctanh
)(a_complex
);
776 #endif /* A_HAVE_CTANH */
777 void a_complex_tanh_(a_complex
*ctx
)
779 #if defined(A_HAVE_CTANH) && defined(A_COMPLEX)
780 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
781 *x
= A_FLOAT_F(ctanh
)(*x
);
782 #elif defined(A_HAVE_CTANH)
783 *ctx
= A_FLOAT_F(ctanh
)(*ctx
);
784 #else /* !A_HAVE_CTANH */
785 a_float
const ci
= a_float_cos(ctx
->imag
);
786 a_float
const sr
= a_float_sinh(ctx
->real
);
787 a_float
const den
= ci
* ci
+ sr
* sr
;
788 ctx
->imag
= A_FLOAT_C(0.5) * a_float_sin(2 * ctx
->imag
) / den
;
789 if (a_float_abs(ctx
->real
) < 1)
791 ctx
->real
= a_float_sinh(ctx
->real
) * a_float_cosh(ctx
->real
) / den
;
795 a_float
const d
= a_float_pow(ci
/ sr
, 2) + 1;
796 ctx
->real
= 1 / (a_float_tanh(ctx
->real
) * d
);
798 #endif /* A_HAVE_CTANH */
801 void a_complex_sech_(a_complex
*ctx
)
803 a_complex_cosh_(ctx
);
807 void a_complex_csch_(a_complex
*ctx
)
809 a_complex_sinh_(ctx
);
813 void a_complex_coth_(a_complex
*ctx
)
815 a_complex_tanh_(ctx
);
819 #if defined(A_HAVE_CASINH) && (A_HAVE_CASINH + 0 < 1)
821 #endif /* A_HAVE_CASINH */
822 #if defined(A_HAVE_CASINH) && !defined A_COMPLEX
823 a_complex
A_FLOAT_F(casinh
)(a_complex
);
824 #endif /* A_HAVE_CASINH */
825 void a_complex_asinh_(a_complex
*ctx
)
827 #if defined(A_HAVE_CASINH) && defined(A_COMPLEX)
828 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
829 *x
= A_FLOAT_F(casinh
)(*x
);
830 #elif defined(A_HAVE_CASINH)
831 *ctx
= A_FLOAT_F(casinh
)(*ctx
);
832 #else /* !A_HAVE_CASINH */
833 a_complex_mul_imag_(ctx
, +1);
834 a_complex_asin_(ctx
);
835 a_complex_mul_imag_(ctx
, -1);
836 #endif /* A_HAVE_CASINH */
839 #if defined(A_HAVE_CACOSH) && (A_HAVE_CACOSH + 0 < 1)
841 #endif /* A_HAVE_CACOSH */
842 #if defined(A_HAVE_CACOSH) && !defined A_COMPLEX
843 a_complex
A_FLOAT_F(cacosh
)(a_complex
);
844 #endif /* A_HAVE_CACOSH */
845 void a_complex_acosh_(a_complex
*ctx
)
847 #if defined(A_HAVE_CACOSH) && defined(A_COMPLEX)
848 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
849 *x
= A_FLOAT_F(cacosh
)(*x
);
850 #elif defined(A_HAVE_CACOSH)
851 *ctx
= A_FLOAT_F(cacosh
)(*ctx
);
852 #else /* !A_HAVE_CACOSH */
853 a_complex_acsc_(ctx
);
854 a_complex_mul_imag_(ctx
, ctx
->imag
> 0 ? -1 : +1);
855 #endif /* A_HAVE_CACOSH */
858 void a_complex_acosh_real(a_complex
*ctx
, a_float x
)
862 ctx
->real
= a_float_acosh(+x
);
868 ctx
->imag
= a_float_acos(x
);
872 ctx
->real
= a_float_acosh(-x
);
873 ctx
->imag
= A_FLOAT_PI
;
878 #if defined(A_HAVE_CATANH) && (A_HAVE_CATANH + 0 < 1)
880 #endif /* A_HAVE_CATANH */
881 #if defined(A_HAVE_CATANH) && !defined A_COMPLEX
882 a_complex
A_FLOAT_F(catanh
)(a_complex
);
883 #endif /* A_HAVE_CATANH */
884 void a_complex_atanh_(a_complex
*ctx
)
886 #if defined(A_HAVE_CATANH) && defined(A_COMPLEX)
887 A_COMPLEX
*const x
= (A_COMPLEX
*)ctx
;
888 *x
= A_FLOAT_F(catanh
)(*x
);
889 #elif defined(A_HAVE_CATANH)
890 *ctx
= A_FLOAT_F(catanh
)(*ctx
);
891 #else /* !A_HAVE_CATANH */
894 a_complex_mul_imag_(ctx
, +1);
895 a_complex_atan_(ctx
);
896 a_complex_mul_imag_(ctx
, -1);
900 a_complex_atanh_real(ctx
, ctx
->real
);
902 #endif /* A_HAVE_CATANH */
905 void a_complex_atanh_real(a_complex
*ctx
, a_float x
)
909 ctx
->real
= a_float_atanh(x
);
914 ctx
->real
= a_float_atanh(1 / x
);
915 ctx
->imag
= (x
< 0) ? +A_FLOAT_PI_2
: -A_FLOAT_PI_2
;
919 void a_complex_asech_(a_complex
*ctx
)
922 a_complex_acosh_(ctx
);
925 void a_complex_acsch_(a_complex
*ctx
)
928 a_complex_asinh_(ctx
);
931 void a_complex_acoth_(a_complex
*ctx
)
934 a_complex_atanh_(ctx
);