gsl_complex__math.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. /* complex/math.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Jorma Olavi Tähtinen, Brian Gough
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. /* Basic complex arithmetic functions
  20. * Original version by Jorma Olavi Tähtinen <jotahtin@cc.hut.fi>
  21. *
  22. * Modified for GSL by Brian Gough, 3/2000
  23. */
  24. /* The following references describe the methods used in these
  25. * functions,
  26. *
  27. * T. E. Hull and Thomas F. Fairgrieve and Ping Tak Peter Tang,
  28. * "Implementing Complex Elementary Functions Using Exception
  29. * Handling", ACM Transactions on Mathematical Software, Volume 20
  30. * (1994), pp 215-244, Corrigenda, p553
  31. *
  32. * Hull et al, "Implementing the complex arcsin and arccosine
  33. * functions using exception handling", ACM Transactions on
  34. * Mathematical Software, Volume 23 (1997) pp 299-335
  35. *
  36. * Abramowitz and Stegun, Handbook of Mathematical Functions, "Inverse
  37. * Circular Functions in Terms of Real and Imaginary Parts", Formulas
  38. * 4.4.37, 4.4.38, 4.4.39
  39. */
  40. #include "gsl__config.h"
  41. #include <math.h>
  42. #include "gsl_math.h"
  43. #include "gsl_complex.h"
  44. #include "gsl_complex_math.h"
  45. /**********************************************************************
  46. * Complex numbers
  47. **********************************************************************/
  48. #ifndef HIDE_INLINE_STATIC
  49. gsl_complex
  50. gsl_complex_rect (double x, double y)
  51. { /* return z = x + i y */
  52. gsl_complex z;
  53. GSL_SET_COMPLEX (&z, x, y);
  54. return z;
  55. }
  56. #endif
  57. gsl_complex
  58. gsl_complex_polar (double r, double theta)
  59. { /* return z = r exp(i theta) */
  60. gsl_complex z;
  61. GSL_SET_COMPLEX (&z, r * cos (theta), r * sin (theta));
  62. return z;
  63. }
  64. /**********************************************************************
  65. * Properties of complex numbers
  66. **********************************************************************/
  67. double
  68. gsl_complex_arg (gsl_complex z)
  69. { /* return arg(z), -pi < arg(z) <= +pi */
  70. double x = GSL_REAL (z);
  71. double y = GSL_IMAG (z);
  72. if (x == 0.0 && y == 0.0)
  73. {
  74. return 0;
  75. }
  76. return atan2 (y, x);
  77. }
  78. double
  79. gsl_complex_abs (gsl_complex z)
  80. { /* return |z| */
  81. return hypot (GSL_REAL (z), GSL_IMAG (z));
  82. }
  83. double
  84. gsl_complex_abs2 (gsl_complex z)
  85. { /* return |z|^2 */
  86. double x = GSL_REAL (z);
  87. double y = GSL_IMAG (z);
  88. return (x * x + y * y);
  89. }
  90. double
  91. gsl_complex_logabs (gsl_complex z)
  92. { /* return log|z| */
  93. double xabs = fabs (GSL_REAL (z));
  94. double yabs = fabs (GSL_IMAG (z));
  95. double max, u;
  96. if (xabs >= yabs)
  97. {
  98. max = xabs;
  99. u = yabs / xabs;
  100. }
  101. else
  102. {
  103. max = yabs;
  104. u = xabs / yabs;
  105. }
  106. /* Handle underflow when u is close to 0 */
  107. return log (max) + 0.5 * log1p (u * u);
  108. }
  109. /***********************************************************************
  110. * Complex arithmetic operators
  111. ***********************************************************************/
  112. gsl_complex
  113. gsl_complex_add (gsl_complex a, gsl_complex b)
  114. { /* z=a+b */
  115. double ar = GSL_REAL (a), ai = GSL_IMAG (a);
  116. double br = GSL_REAL (b), bi = GSL_IMAG (b);
  117. gsl_complex z;
  118. GSL_SET_COMPLEX (&z, ar + br, ai + bi);
  119. return z;
  120. }
  121. gsl_complex
  122. gsl_complex_add_real (gsl_complex a, double x)
  123. { /* z=a+x */
  124. gsl_complex z;
  125. GSL_SET_COMPLEX (&z, GSL_REAL (a) + x, GSL_IMAG (a));
  126. return z;
  127. }
  128. gsl_complex
  129. gsl_complex_add_imag (gsl_complex a, double y)
  130. { /* z=a+iy */
  131. gsl_complex z;
  132. GSL_SET_COMPLEX (&z, GSL_REAL (a), GSL_IMAG (a) + y);
  133. return z;
  134. }
  135. gsl_complex
  136. gsl_complex_sub (gsl_complex a, gsl_complex b)
  137. { /* z=a-b */
  138. double ar = GSL_REAL (a), ai = GSL_IMAG (a);
  139. double br = GSL_REAL (b), bi = GSL_IMAG (b);
  140. gsl_complex z;
  141. GSL_SET_COMPLEX (&z, ar - br, ai - bi);
  142. return z;
  143. }
  144. gsl_complex
  145. gsl_complex_sub_real (gsl_complex a, double x)
  146. { /* z=a-x */
  147. gsl_complex z;
  148. GSL_SET_COMPLEX (&z, GSL_REAL (a) - x, GSL_IMAG (a));
  149. return z;
  150. }
  151. gsl_complex
  152. gsl_complex_sub_imag (gsl_complex a, double y)
  153. { /* z=a-iy */
  154. gsl_complex z;
  155. GSL_SET_COMPLEX (&z, GSL_REAL (a), GSL_IMAG (a) - y);
  156. return z;
  157. }
  158. gsl_complex
  159. gsl_complex_mul (gsl_complex a, gsl_complex b)
  160. { /* z=a*b */
  161. double ar = GSL_REAL (a), ai = GSL_IMAG (a);
  162. double br = GSL_REAL (b), bi = GSL_IMAG (b);
  163. gsl_complex z;
  164. GSL_SET_COMPLEX (&z, ar * br - ai * bi, ar * bi + ai * br);
  165. return z;
  166. }
  167. gsl_complex
  168. gsl_complex_mul_real (gsl_complex a, double x)
  169. { /* z=a*x */
  170. gsl_complex z;
  171. GSL_SET_COMPLEX (&z, x * GSL_REAL (a), x * GSL_IMAG (a));
  172. return z;
  173. }
  174. gsl_complex
  175. gsl_complex_mul_imag (gsl_complex a, double y)
  176. { /* z=a*iy */
  177. gsl_complex z;
  178. GSL_SET_COMPLEX (&z, -y * GSL_IMAG (a), y * GSL_REAL (a));
  179. return z;
  180. }
  181. gsl_complex
  182. gsl_complex_div (gsl_complex a, gsl_complex b)
  183. { /* z=a/b */
  184. double ar = GSL_REAL (a), ai = GSL_IMAG (a);
  185. double br = GSL_REAL (b), bi = GSL_IMAG (b);
  186. double s = 1.0 / gsl_complex_abs (b);
  187. double sbr = s * br;
  188. double sbi = s * bi;
  189. double zr = (ar * sbr + ai * sbi) * s;
  190. double zi = (ai * sbr - ar * sbi) * s;
  191. gsl_complex z;
  192. GSL_SET_COMPLEX (&z, zr, zi);
  193. return z;
  194. }
  195. gsl_complex
  196. gsl_complex_div_real (gsl_complex a, double x)
  197. { /* z=a/x */
  198. gsl_complex z;
  199. GSL_SET_COMPLEX (&z, GSL_REAL (a) / x, GSL_IMAG (a) / x);
  200. return z;
  201. }
  202. gsl_complex
  203. gsl_complex_div_imag (gsl_complex a, double y)
  204. { /* z=a/(iy) */
  205. gsl_complex z;
  206. GSL_SET_COMPLEX (&z, GSL_IMAG (a) / y, - GSL_REAL (a) / y);
  207. return z;
  208. }
  209. gsl_complex
  210. gsl_complex_conjugate (gsl_complex a)
  211. { /* z=conj(a) */
  212. gsl_complex z;
  213. GSL_SET_COMPLEX (&z, GSL_REAL (a), -GSL_IMAG (a));
  214. return z;
  215. }
  216. gsl_complex
  217. gsl_complex_negative (gsl_complex a)
  218. { /* z=-a */
  219. gsl_complex z;
  220. GSL_SET_COMPLEX (&z, -GSL_REAL (a), -GSL_IMAG (a));
  221. return z;
  222. }
  223. gsl_complex
  224. gsl_complex_inverse (gsl_complex a)
  225. { /* z=1/a */
  226. double s = 1.0 / gsl_complex_abs (a);
  227. gsl_complex z;
  228. GSL_SET_COMPLEX (&z, (GSL_REAL (a) * s) * s, -(GSL_IMAG (a) * s) * s);
  229. return z;
  230. }
  231. /**********************************************************************
  232. * Elementary complex functions
  233. **********************************************************************/
  234. gsl_complex
  235. gsl_complex_sqrt (gsl_complex a)
  236. { /* z=sqrt(a) */
  237. gsl_complex z;
  238. if (GSL_REAL (a) == 0.0 && GSL_IMAG (a) == 0.0)
  239. {
  240. GSL_SET_COMPLEX (&z, 0, 0);
  241. }
  242. else
  243. {
  244. double x = fabs (GSL_REAL (a));
  245. double y = fabs (GSL_IMAG (a));
  246. double w;
  247. if (x >= y)
  248. {
  249. double t = y / x;
  250. w = sqrt (x) * sqrt (0.5 * (1.0 + sqrt (1.0 + t * t)));
  251. }
  252. else
  253. {
  254. double t = x / y;
  255. w = sqrt (y) * sqrt (0.5 * (t + sqrt (1.0 + t * t)));
  256. }
  257. if (GSL_REAL (a) >= 0.0)
  258. {
  259. double ai = GSL_IMAG (a);
  260. GSL_SET_COMPLEX (&z, w, ai / (2.0 * w));
  261. }
  262. else
  263. {
  264. double ai = GSL_IMAG (a);
  265. double vi = (ai >= 0) ? w : -w;
  266. GSL_SET_COMPLEX (&z, ai / (2.0 * vi), vi);
  267. }
  268. }
  269. return z;
  270. }
  271. gsl_complex
  272. gsl_complex_sqrt_real (double x)
  273. { /* z=sqrt(x) */
  274. gsl_complex z;
  275. if (x >= 0)
  276. {
  277. GSL_SET_COMPLEX (&z, sqrt (x), 0.0);
  278. }
  279. else
  280. {
  281. GSL_SET_COMPLEX (&z, 0.0, sqrt (-x));
  282. }
  283. return z;
  284. }
  285. gsl_complex
  286. gsl_complex_exp (gsl_complex a)
  287. { /* z=exp(a) */
  288. double rho = exp (GSL_REAL (a));
  289. double theta = GSL_IMAG (a);
  290. gsl_complex z;
  291. GSL_SET_COMPLEX (&z, rho * cos (theta), rho * sin (theta));
  292. return z;
  293. }
  294. gsl_complex
  295. gsl_complex_pow (gsl_complex a, gsl_complex b)
  296. { /* z=a^b */
  297. gsl_complex z;
  298. if (GSL_REAL (a) == 0 && GSL_IMAG (a) == 0.0)
  299. {
  300. if (GSL_REAL (b) == 0 && GSL_IMAG (b) == 0.0)
  301. {
  302. GSL_SET_COMPLEX (&z, 1.0, 0.0);
  303. }
  304. else
  305. {
  306. GSL_SET_COMPLEX (&z, 0.0, 0.0);
  307. }
  308. }
  309. else if (GSL_REAL (b) == 1.0 && GSL_IMAG (b) == 0.0)
  310. {
  311. return a;
  312. }
  313. else if (GSL_REAL (b) == -1.0 && GSL_IMAG (b) == 0.0)
  314. {
  315. return gsl_complex_inverse (a);
  316. }
  317. else
  318. {
  319. double logr = gsl_complex_logabs (a);
  320. double theta = gsl_complex_arg (a);
  321. double br = GSL_REAL (b), bi = GSL_IMAG (b);
  322. double rho = exp (logr * br - bi * theta);
  323. double beta = theta * br + bi * logr;
  324. GSL_SET_COMPLEX (&z, rho * cos (beta), rho * sin (beta));
  325. }
  326. return z;
  327. }
  328. gsl_complex
  329. gsl_complex_pow_real (gsl_complex a, double b)
  330. { /* z=a^b */
  331. gsl_complex z;
  332. if (GSL_REAL (a) == 0 && GSL_IMAG (a) == 0)
  333. {
  334. GSL_SET_COMPLEX (&z, 0, 0);
  335. }
  336. else
  337. {
  338. double logr = gsl_complex_logabs (a);
  339. double theta = gsl_complex_arg (a);
  340. double rho = exp (logr * b);
  341. double beta = theta * b;
  342. GSL_SET_COMPLEX (&z, rho * cos (beta), rho * sin (beta));
  343. }
  344. return z;
  345. }
  346. gsl_complex
  347. gsl_complex_log (gsl_complex a)
  348. { /* z=log(a) */
  349. double logr = gsl_complex_logabs (a);
  350. double theta = gsl_complex_arg (a);
  351. gsl_complex z;
  352. GSL_SET_COMPLEX (&z, logr, theta);
  353. return z;
  354. }
  355. gsl_complex
  356. gsl_complex_log10 (gsl_complex a)
  357. { /* z = log10(a) */
  358. return gsl_complex_mul_real (gsl_complex_log (a), 1 / log (10.));
  359. }
  360. gsl_complex
  361. gsl_complex_log_b (gsl_complex a, gsl_complex b)
  362. {
  363. return gsl_complex_div (gsl_complex_log (a), gsl_complex_log (b));
  364. }
  365. /***********************************************************************
  366. * Complex trigonometric functions
  367. ***********************************************************************/
  368. gsl_complex
  369. gsl_complex_sin (gsl_complex a)
  370. { /* z = sin(a) */
  371. double R = GSL_REAL (a), I = GSL_IMAG (a);
  372. gsl_complex z;
  373. if (I == 0.0)
  374. {
  375. /* avoid returing negative zero (-0.0) for the imaginary part */
  376. GSL_SET_COMPLEX (&z, sin (R), 0.0);
  377. }
  378. else
  379. {
  380. GSL_SET_COMPLEX (&z, sin (R) * cosh (I), cos (R) * sinh (I));
  381. }
  382. return z;
  383. }
  384. gsl_complex
  385. gsl_complex_cos (gsl_complex a)
  386. { /* z = cos(a) */
  387. double R = GSL_REAL (a), I = GSL_IMAG (a);
  388. gsl_complex z;
  389. if (I == 0.0)
  390. {
  391. /* avoid returing negative zero (-0.0) for the imaginary part */
  392. GSL_SET_COMPLEX (&z, cos (R), 0.0);
  393. }
  394. else
  395. {
  396. GSL_SET_COMPLEX (&z, cos (R) * cosh (I), sin (R) * sinh (-I));
  397. }
  398. return z;
  399. }
  400. gsl_complex
  401. gsl_complex_tan (gsl_complex a)
  402. { /* z = tan(a) */
  403. double R = GSL_REAL (a), I = GSL_IMAG (a);
  404. gsl_complex z;
  405. if (fabs (I) < 1)
  406. {
  407. double D = pow (cos (R), 2.0) + pow (sinh (I), 2.0);
  408. GSL_SET_COMPLEX (&z, 0.5 * sin (2 * R) / D, 0.5 * sinh (2 * I) / D);
  409. }
  410. else
  411. {
  412. double u = exp (-I);
  413. double C = 2 * u / (1 - pow (u, 2.0));
  414. double D = 1 + pow (cos (R), 2.0) * pow (C, 2.0);
  415. double S = pow (C, 2.0);
  416. double T = 1.0 / tanh (I);
  417. GSL_SET_COMPLEX (&z, 0.5 * sin (2 * R) * S / D, T / D);
  418. }
  419. return z;
  420. }
  421. gsl_complex
  422. gsl_complex_sec (gsl_complex a)
  423. { /* z = sec(a) */
  424. gsl_complex z = gsl_complex_cos (a);
  425. return gsl_complex_inverse (z);
  426. }
  427. gsl_complex
  428. gsl_complex_csc (gsl_complex a)
  429. { /* z = csc(a) */
  430. gsl_complex z = gsl_complex_sin (a);
  431. return gsl_complex_inverse(z);
  432. }
  433. gsl_complex
  434. gsl_complex_cot (gsl_complex a)
  435. { /* z = cot(a) */
  436. gsl_complex z = gsl_complex_tan (a);
  437. return gsl_complex_inverse (z);
  438. }
  439. /**********************************************************************
  440. * Inverse Complex Trigonometric Functions
  441. **********************************************************************/
  442. gsl_complex
  443. gsl_complex_arcsin (gsl_complex a)
  444. { /* z = arcsin(a) */
  445. double R = GSL_REAL (a), I = GSL_IMAG (a);
  446. gsl_complex z;
  447. if (I == 0)
  448. {
  449. z = gsl_complex_arcsin_real (R);
  450. }
  451. else
  452. {
  453. double x = fabs (R), y = fabs (I);
  454. double r = hypot (x + 1, y), s = hypot (x - 1, y);
  455. double A = 0.5 * (r + s);
  456. double B = x / A;
  457. double y2 = y * y;
  458. double real, imag;
  459. const double A_crossover = 1.5, B_crossover = 0.6417;
  460. if (B <= B_crossover)
  461. {
  462. real = asin (B);
  463. }
  464. else
  465. {
  466. if (x <= 1)
  467. {
  468. double D = 0.5 * (A + x) * (y2 / (r + x + 1) + (s + (1 - x)));
  469. real = atan (x / sqrt (D));
  470. }
  471. else
  472. {
  473. double Apx = A + x;
  474. double D = 0.5 * (Apx / (r + x + 1) + Apx / (s + (x - 1)));
  475. real = atan (x / (y * sqrt (D)));
  476. }
  477. }
  478. if (A <= A_crossover)
  479. {
  480. double Am1;
  481. if (x < 1)
  482. {
  483. Am1 = 0.5 * (y2 / (r + (x + 1)) + y2 / (s + (1 - x)));
  484. }
  485. else
  486. {
  487. Am1 = 0.5 * (y2 / (r + (x + 1)) + (s + (x - 1)));
  488. }
  489. imag = log1p (Am1 + sqrt (Am1 * (A + 1)));
  490. }
  491. else
  492. {
  493. imag = log (A + sqrt (A * A - 1));
  494. }
  495. GSL_SET_COMPLEX (&z, (R >= 0) ? real : -real, (I >= 0) ? imag : -imag);
  496. }
  497. return z;
  498. }
  499. gsl_complex
  500. gsl_complex_arcsin_real (double a)
  501. { /* z = arcsin(a) */
  502. gsl_complex z;
  503. if (fabs (a) <= 1.0)
  504. {
  505. GSL_SET_COMPLEX (&z, asin (a), 0.0);
  506. }
  507. else
  508. {
  509. if (a < 0.0)
  510. {
  511. GSL_SET_COMPLEX (&z, -M_PI_2, acosh (-a));
  512. }
  513. else
  514. {
  515. GSL_SET_COMPLEX (&z, M_PI_2, -acosh (a));
  516. }
  517. }
  518. return z;
  519. }
  520. gsl_complex
  521. gsl_complex_arccos (gsl_complex a)
  522. { /* z = arccos(a) */
  523. double R = GSL_REAL (a), I = GSL_IMAG (a);
  524. gsl_complex z;
  525. if (I == 0)
  526. {
  527. z = gsl_complex_arccos_real (R);
  528. }
  529. else
  530. {
  531. double x = fabs (R), y = fabs (I);
  532. double r = hypot (x + 1, y), s = hypot (x - 1, y);
  533. double A = 0.5 * (r + s);
  534. double B = x / A;
  535. double y2 = y * y;
  536. double real, imag;
  537. const double A_crossover = 1.5, B_crossover = 0.6417;
  538. if (B <= B_crossover)
  539. {
  540. real = acos (B);
  541. }
  542. else
  543. {
  544. if (x <= 1)
  545. {
  546. double D = 0.5 * (A + x) * (y2 / (r + x + 1) + (s + (1 - x)));
  547. real = atan (sqrt (D) / x);
  548. }
  549. else
  550. {
  551. double Apx = A + x;
  552. double D = 0.5 * (Apx / (r + x + 1) + Apx / (s + (x - 1)));
  553. real = atan ((y * sqrt (D)) / x);
  554. }
  555. }
  556. if (A <= A_crossover)
  557. {
  558. double Am1;
  559. if (x < 1)
  560. {
  561. Am1 = 0.5 * (y2 / (r + (x + 1)) + y2 / (s + (1 - x)));
  562. }
  563. else
  564. {
  565. Am1 = 0.5 * (y2 / (r + (x + 1)) + (s + (x - 1)));
  566. }
  567. imag = log1p (Am1 + sqrt (Am1 * (A + 1)));
  568. }
  569. else
  570. {
  571. imag = log (A + sqrt (A * A - 1));
  572. }
  573. GSL_SET_COMPLEX (&z, (R >= 0) ? real : M_PI - real, (I >= 0) ? -imag : imag);
  574. }
  575. return z;
  576. }
  577. gsl_complex
  578. gsl_complex_arccos_real (double a)
  579. { /* z = arccos(a) */
  580. gsl_complex z;
  581. if (fabs (a) <= 1.0)
  582. {
  583. GSL_SET_COMPLEX (&z, acos (a), 0);
  584. }
  585. else
  586. {
  587. if (a < 0.0)
  588. {
  589. GSL_SET_COMPLEX (&z, M_PI, -acosh (-a));
  590. }
  591. else
  592. {
  593. GSL_SET_COMPLEX (&z, 0, acosh (a));
  594. }
  595. }
  596. return z;
  597. }
  598. gsl_complex
  599. gsl_complex_arctan (gsl_complex a)
  600. { /* z = arctan(a) */
  601. double R = GSL_REAL (a), I = GSL_IMAG (a);
  602. gsl_complex z;
  603. if (I == 0)
  604. {
  605. GSL_SET_COMPLEX (&z, atan (R), 0);
  606. }
  607. else
  608. {
  609. /* FIXME: This is a naive implementation which does not fully
  610. take into account cancellation errors, overflow, underflow
  611. etc. It would benefit from the Hull et al treatment. */
  612. double r = hypot (R, I);
  613. double imag;
  614. double u = 2 * I / (1 + r * r);
  615. /* FIXME: the following cross-over should be optimized but 0.1
  616. seems to work ok */
  617. if (fabs (u) < 0.1)
  618. {
  619. imag = 0.25 * (log1p (u) - log1p (-u));
  620. }
  621. else
  622. {
  623. double A = hypot (R, I + 1);
  624. double B = hypot (R, I - 1);
  625. imag = 0.5 * log (A / B);
  626. }
  627. if (R == 0)
  628. {
  629. if (I > 1)
  630. {
  631. GSL_SET_COMPLEX (&z, M_PI_2, imag);
  632. }
  633. else if (I < -1)
  634. {
  635. GSL_SET_COMPLEX (&z, -M_PI_2, imag);
  636. }
  637. else
  638. {
  639. GSL_SET_COMPLEX (&z, 0, imag);
  640. };
  641. }
  642. else
  643. {
  644. GSL_SET_COMPLEX (&z, 0.5 * atan2 (2 * R, ((1 + r) * (1 - r))), imag);
  645. }
  646. }
  647. return z;
  648. }
  649. gsl_complex
  650. gsl_complex_arcsec (gsl_complex a)
  651. { /* z = arcsec(a) */
  652. gsl_complex z = gsl_complex_inverse (a);
  653. return gsl_complex_arccos (z);
  654. }
  655. gsl_complex
  656. gsl_complex_arcsec_real (double a)
  657. { /* z = arcsec(a) */
  658. gsl_complex z;
  659. if (a <= -1.0 || a >= 1.0)
  660. {
  661. GSL_SET_COMPLEX (&z, acos (1 / a), 0.0);
  662. }
  663. else
  664. {
  665. if (a >= 0.0)
  666. {
  667. GSL_SET_COMPLEX (&z, 0, acosh (1 / a));
  668. }
  669. else
  670. {
  671. GSL_SET_COMPLEX (&z, M_PI, -acosh (-1 / a));
  672. }
  673. }
  674. return z;
  675. }
  676. gsl_complex
  677. gsl_complex_arccsc (gsl_complex a)
  678. { /* z = arccsc(a) */
  679. gsl_complex z = gsl_complex_inverse (a);
  680. return gsl_complex_arcsin (z);
  681. }
  682. gsl_complex
  683. gsl_complex_arccsc_real (double a)
  684. { /* z = arccsc(a) */
  685. gsl_complex z;
  686. if (a <= -1.0 || a >= 1.0)
  687. {
  688. GSL_SET_COMPLEX (&z, asin (1 / a), 0.0);
  689. }
  690. else
  691. {
  692. if (a >= 0.0)
  693. {
  694. GSL_SET_COMPLEX (&z, M_PI_2, -acosh (1 / a));
  695. }
  696. else
  697. {
  698. GSL_SET_COMPLEX (&z, -M_PI_2, acosh (-1 / a));
  699. }
  700. }
  701. return z;
  702. }
  703. gsl_complex
  704. gsl_complex_arccot (gsl_complex a)
  705. { /* z = arccot(a) */
  706. gsl_complex z;
  707. if (GSL_REAL (a) == 0.0 && GSL_IMAG (a) == 0.0)
  708. {
  709. GSL_SET_COMPLEX (&z, M_PI_2, 0);
  710. }
  711. else
  712. {
  713. z = gsl_complex_inverse (a);
  714. z = gsl_complex_arctan (z);
  715. }
  716. return z;
  717. }
  718. /**********************************************************************
  719. * Complex Hyperbolic Functions
  720. **********************************************************************/
  721. gsl_complex
  722. gsl_complex_sinh (gsl_complex a)
  723. { /* z = sinh(a) */
  724. double R = GSL_REAL (a), I = GSL_IMAG (a);
  725. gsl_complex z;
  726. GSL_SET_COMPLEX (&z, sinh (R) * cos (I), cosh (R) * sin (I));
  727. return z;
  728. }
  729. gsl_complex
  730. gsl_complex_cosh (gsl_complex a)
  731. { /* z = cosh(a) */
  732. double R = GSL_REAL (a), I = GSL_IMAG (a);
  733. gsl_complex z;
  734. GSL_SET_COMPLEX (&z, cosh (R) * cos (I), sinh (R) * sin (I));
  735. return z;
  736. }
  737. gsl_complex
  738. gsl_complex_tanh (gsl_complex a)
  739. { /* z = tanh(a) */
  740. double R = GSL_REAL (a), I = GSL_IMAG (a);
  741. gsl_complex z;
  742. if (fabs(R) < 1.0)
  743. {
  744. double D = pow (cos (I), 2.0) + pow (sinh (R), 2.0);
  745. GSL_SET_COMPLEX (&z, sinh (R) * cosh (R) / D, 0.5 * sin (2 * I) / D);
  746. }
  747. else
  748. {
  749. double D = pow (cos (I), 2.0) + pow (sinh (R), 2.0);
  750. double F = 1 + pow (cos (I) / sinh (R), 2.0);
  751. GSL_SET_COMPLEX (&z, 1.0 / (tanh (R) * F), 0.5 * sin (2 * I) / D);
  752. }
  753. return z;
  754. }
  755. gsl_complex
  756. gsl_complex_sech (gsl_complex a)
  757. { /* z = sech(a) */
  758. gsl_complex z = gsl_complex_cosh (a);
  759. return gsl_complex_inverse (z);
  760. }
  761. gsl_complex
  762. gsl_complex_csch (gsl_complex a)
  763. { /* z = csch(a) */
  764. gsl_complex z = gsl_complex_sinh (a);
  765. return gsl_complex_inverse (z);
  766. }
  767. gsl_complex
  768. gsl_complex_coth (gsl_complex a)
  769. { /* z = coth(a) */
  770. gsl_complex z = gsl_complex_tanh (a);
  771. return gsl_complex_inverse (z);
  772. }
  773. /**********************************************************************
  774. * Inverse Complex Hyperbolic Functions
  775. **********************************************************************/
  776. gsl_complex
  777. gsl_complex_arcsinh (gsl_complex a)
  778. { /* z = arcsinh(a) */
  779. gsl_complex z = gsl_complex_mul_imag(a, 1.0);
  780. z = gsl_complex_arcsin (z);
  781. z = gsl_complex_mul_imag (z, -1.0);
  782. return z;
  783. }
  784. gsl_complex
  785. gsl_complex_arccosh (gsl_complex a)
  786. { /* z = arccosh(a) */
  787. gsl_complex z = gsl_complex_arccos (a);
  788. z = gsl_complex_mul_imag (z, GSL_IMAG(z) > 0 ? -1.0 : 1.0);
  789. return z;
  790. }
  791. gsl_complex
  792. gsl_complex_arccosh_real (double a)
  793. { /* z = arccosh(a) */
  794. gsl_complex z;
  795. if (a >= 1)
  796. {
  797. GSL_SET_COMPLEX (&z, acosh (a), 0);
  798. }
  799. else
  800. {
  801. if (a >= -1.0)
  802. {
  803. GSL_SET_COMPLEX (&z, 0, acos (a));
  804. }
  805. else
  806. {
  807. GSL_SET_COMPLEX (&z, acosh (-a), M_PI);
  808. }
  809. }
  810. return z;
  811. }
  812. gsl_complex
  813. gsl_complex_arctanh (gsl_complex a)
  814. { /* z = arctanh(a) */
  815. if (GSL_IMAG (a) == 0.0)
  816. {
  817. return gsl_complex_arctanh_real (GSL_REAL (a));
  818. }
  819. else
  820. {
  821. gsl_complex z = gsl_complex_mul_imag(a, 1.0);
  822. z = gsl_complex_arctan (z);
  823. z = gsl_complex_mul_imag (z, -1.0);
  824. return z;
  825. }
  826. }
  827. gsl_complex
  828. gsl_complex_arctanh_real (double a)
  829. { /* z = arctanh(a) */
  830. gsl_complex z;
  831. if (a > -1.0 && a < 1.0)
  832. {
  833. GSL_SET_COMPLEX (&z, atanh (a), 0);
  834. }
  835. else
  836. {
  837. GSL_SET_COMPLEX (&z, atanh (1 / a), (a < 0) ? M_PI_2 : -M_PI_2);
  838. }
  839. return z;
  840. }
  841. gsl_complex
  842. gsl_complex_arcsech (gsl_complex a)
  843. { /* z = arcsech(a); */
  844. gsl_complex t = gsl_complex_inverse (a);
  845. return gsl_complex_arccosh (t);
  846. }
  847. gsl_complex
  848. gsl_complex_arccsch (gsl_complex a)
  849. { /* z = arccsch(a) */
  850. gsl_complex t = gsl_complex_inverse (a);
  851. return gsl_complex_arcsinh (t);
  852. }
  853. gsl_complex
  854. gsl_complex_arccoth (gsl_complex a)
  855. { /* z = arccoth(a) */
  856. gsl_complex t = gsl_complex_inverse (a);
  857. return gsl_complex_arctanh (t);
  858. }