clog.c 16 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. /* clog.c
  2. *
  3. * Complex natural logarithm
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * void clog();
  10. * cmplx z, w;
  11. *
  12. * clog( &z, &w );
  13. *
  14. *
  15. *
  16. * DESCRIPTION:
  17. *
  18. * Returns complex logarithm to the base e (2.718...) of
  19. * the complex argument x.
  20. *
  21. * If z = x + iy, r = sqrt( x**2 + y**2 ),
  22. * then
  23. * w = log(r) + i arctan(y/x).
  24. *
  25. * The arctangent ranges from -PI to +PI.
  26. *
  27. *
  28. * ACCURACY:
  29. *
  30. * Relative error:
  31. * arithmetic domain # trials peak rms
  32. * DEC -10,+10 7000 8.5e-17 1.9e-17
  33. * IEEE -10,+10 30000 5.0e-15 1.1e-16
  34. *
  35. * Larger relative error can be observed for z near 1 +i0.
  36. * In IEEE arithmetic the peak absolute error is 5.2e-16, rms
  37. * absolute error 1.0e-16.
  38. */
  39. /*
  40. Cephes Math Library Release 2.8: June, 2000
  41. Copyright 1984, 1995, 2000 by Stephen L. Moshier
  42. */
  43. #include <math.h>
  44. #ifdef ANSIPROT
  45. static void cchsh ( double x, double *c, double *s );
  46. static double redupi ( double x );
  47. static double ctans ( cmplx *z );
  48. /* These are supposed to be in some standard place. */
  49. double fabs (double);
  50. double sqrt (double);
  51. double pow (double, double);
  52. double log (double);
  53. double exp (double);
  54. double atan2 (double, double);
  55. double cosh (double);
  56. double sinh (double);
  57. double asin (double);
  58. double sin (double);
  59. double cos (double);
  60. double cabs (cmplx *);
  61. void cadd ( cmplx *, cmplx *, cmplx * );
  62. void cmul ( cmplx *, cmplx *, cmplx * );
  63. void csqrt ( cmplx *, cmplx * );
  64. static void cchsh ( double, double *, double * );
  65. static double redupi ( double );
  66. static double ctans ( cmplx * );
  67. void clog ( cmplx *, cmplx * );
  68. void casin ( cmplx *, cmplx * );
  69. void cacos ( cmplx *, cmplx * );
  70. void catan ( cmplx *, cmplx * );
  71. #else
  72. static void cchsh();
  73. static double redupi();
  74. static double ctans();
  75. double cabs(), fabs(), sqrt(), pow();
  76. double log(), exp(), atan2(), cosh(), sinh();
  77. double asin(), sin(), cos();
  78. void cadd(), cmul(), csqrt();
  79. void clog(), casin(), cacos(), catan();
  80. #endif
  81. extern double MAXNUM, MACHEP, PI, PIO2;
  82. void clog( z, w )
  83. register cmplx *z, *w;
  84. {
  85. double p, rr;
  86. /*rr = sqrt( z->r * z->r + z->i * z->i );*/
  87. rr = cabs(z);
  88. p = log(rr);
  89. #if ANSIC
  90. rr = atan2( z->i, z->r );
  91. #else
  92. rr = atan2( z->r, z->i );
  93. if( rr > PI )
  94. rr -= PI + PI;
  95. #endif
  96. w->i = rr;
  97. w->r = p;
  98. }
  99. /* cexp()
  100. *
  101. * Complex exponential function
  102. *
  103. *
  104. *
  105. * SYNOPSIS:
  106. *
  107. * void cexp();
  108. * cmplx z, w;
  109. *
  110. * cexp( &z, &w );
  111. *
  112. *
  113. *
  114. * DESCRIPTION:
  115. *
  116. * Returns the exponential of the complex argument z
  117. * into the complex result w.
  118. *
  119. * If
  120. * z = x + iy,
  121. * r = exp(x),
  122. *
  123. * then
  124. *
  125. * w = r cos y + i r sin y.
  126. *
  127. *
  128. * ACCURACY:
  129. *
  130. * Relative error:
  131. * arithmetic domain # trials peak rms
  132. * DEC -10,+10 8700 3.7e-17 1.1e-17
  133. * IEEE -10,+10 30000 3.0e-16 8.7e-17
  134. *
  135. */
  136. void cexp( z, w )
  137. register cmplx *z, *w;
  138. {
  139. double r;
  140. r = exp( z->r );
  141. w->r = r * cos( z->i );
  142. w->i = r * sin( z->i );
  143. }
  144. /* csin()
  145. *
  146. * Complex circular sine
  147. *
  148. *
  149. *
  150. * SYNOPSIS:
  151. *
  152. * void csin();
  153. * cmplx z, w;
  154. *
  155. * csin( &z, &w );
  156. *
  157. *
  158. *
  159. * DESCRIPTION:
  160. *
  161. * If
  162. * z = x + iy,
  163. *
  164. * then
  165. *
  166. * w = sin x cosh y + i cos x sinh y.
  167. *
  168. *
  169. *
  170. * ACCURACY:
  171. *
  172. * Relative error:
  173. * arithmetic domain # trials peak rms
  174. * DEC -10,+10 8400 5.3e-17 1.3e-17
  175. * IEEE -10,+10 30000 3.8e-16 1.0e-16
  176. * Also tested by csin(casin(z)) = z.
  177. *
  178. */
  179. void csin( z, w )
  180. register cmplx *z, *w;
  181. {
  182. double ch, sh;
  183. cchsh( z->i, &ch, &sh );
  184. w->r = sin( z->r ) * ch;
  185. w->i = cos( z->r ) * sh;
  186. }
  187. /* calculate cosh and sinh */
  188. static void cchsh( x, c, s )
  189. double x, *c, *s;
  190. {
  191. double e, ei;
  192. if( fabs(x) <= 0.5 )
  193. {
  194. *c = cosh(x);
  195. *s = sinh(x);
  196. }
  197. else
  198. {
  199. e = exp(x);
  200. ei = 0.5/e;
  201. e = 0.5 * e;
  202. *s = e - ei;
  203. *c = e + ei;
  204. }
  205. }
  206. /* ccos()
  207. *
  208. * Complex circular cosine
  209. *
  210. *
  211. *
  212. * SYNOPSIS:
  213. *
  214. * void ccos();
  215. * cmplx z, w;
  216. *
  217. * ccos( &z, &w );
  218. *
  219. *
  220. *
  221. * DESCRIPTION:
  222. *
  223. * If
  224. * z = x + iy,
  225. *
  226. * then
  227. *
  228. * w = cos x cosh y - i sin x sinh y.
  229. *
  230. *
  231. *
  232. * ACCURACY:
  233. *
  234. * Relative error:
  235. * arithmetic domain # trials peak rms
  236. * DEC -10,+10 8400 4.5e-17 1.3e-17
  237. * IEEE -10,+10 30000 3.8e-16 1.0e-16
  238. */
  239. void ccos( z, w )
  240. register cmplx *z, *w;
  241. {
  242. double ch, sh;
  243. cchsh( z->i, &ch, &sh );
  244. w->r = cos( z->r ) * ch;
  245. w->i = -sin( z->r ) * sh;
  246. }
  247. /* ctan()
  248. *
  249. * Complex circular tangent
  250. *
  251. *
  252. *
  253. * SYNOPSIS:
  254. *
  255. * void ctan();
  256. * cmplx z, w;
  257. *
  258. * ctan( &z, &w );
  259. *
  260. *
  261. *
  262. * DESCRIPTION:
  263. *
  264. * If
  265. * z = x + iy,
  266. *
  267. * then
  268. *
  269. * sin 2x + i sinh 2y
  270. * w = --------------------.
  271. * cos 2x + cosh 2y
  272. *
  273. * On the real axis the denominator is zero at odd multiples
  274. * of PI/2. The denominator is evaluated by its Taylor
  275. * series near these points.
  276. *
  277. *
  278. * ACCURACY:
  279. *
  280. * Relative error:
  281. * arithmetic domain # trials peak rms
  282. * DEC -10,+10 5200 7.1e-17 1.6e-17
  283. * IEEE -10,+10 30000 7.2e-16 1.2e-16
  284. * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z.
  285. */
  286. void ctan( z, w )
  287. register cmplx *z, *w;
  288. {
  289. double d;
  290. d = cos( 2.0 * z->r ) + cosh( 2.0 * z->i );
  291. if( fabs(d) < 0.25 )
  292. d = ctans(z);
  293. if( d == 0.0 )
  294. {
  295. mtherr( "ctan", OVERFLOW );
  296. w->r = MAXNUM;
  297. w->i = MAXNUM;
  298. return;
  299. }
  300. w->r = sin( 2.0 * z->r ) / d;
  301. w->i = sinh( 2.0 * z->i ) / d;
  302. }
  303. /* ccot()
  304. *
  305. * Complex circular cotangent
  306. *
  307. *
  308. *
  309. * SYNOPSIS:
  310. *
  311. * void ccot();
  312. * cmplx z, w;
  313. *
  314. * ccot( &z, &w );
  315. *
  316. *
  317. *
  318. * DESCRIPTION:
  319. *
  320. * If
  321. * z = x + iy,
  322. *
  323. * then
  324. *
  325. * sin 2x - i sinh 2y
  326. * w = --------------------.
  327. * cosh 2y - cos 2x
  328. *
  329. * On the real axis, the denominator has zeros at even
  330. * multiples of PI/2. Near these points it is evaluated
  331. * by a Taylor series.
  332. *
  333. *
  334. * ACCURACY:
  335. *
  336. * Relative error:
  337. * arithmetic domain # trials peak rms
  338. * DEC -10,+10 3000 6.5e-17 1.6e-17
  339. * IEEE -10,+10 30000 9.2e-16 1.2e-16
  340. * Also tested by ctan * ccot = 1 + i0.
  341. */
  342. void ccot( z, w )
  343. register cmplx *z, *w;
  344. {
  345. double d;
  346. d = cosh(2.0 * z->i) - cos(2.0 * z->r);
  347. if( fabs(d) < 0.25 )
  348. d = ctans(z);
  349. if( d == 0.0 )
  350. {
  351. mtherr( "ccot", OVERFLOW );
  352. w->r = MAXNUM;
  353. w->i = MAXNUM;
  354. return;
  355. }
  356. w->r = sin( 2.0 * z->r ) / d;
  357. w->i = -sinh( 2.0 * z->i ) / d;
  358. }
  359. /* Program to subtract nearest integer multiple of PI */
  360. /* extended precision value of PI: */
  361. #ifdef UNK
  362. static double DP1 = 3.14159265160560607910E0;
  363. static double DP2 = 1.98418714791870343106E-9;
  364. static double DP3 = 1.14423774522196636802E-17;
  365. #endif
  366. #ifdef DEC
  367. static unsigned short P1[] = {0040511,0007732,0120000,0000000,};
  368. static unsigned short P2[] = {0031010,0055060,0100000,0000000,};
  369. static unsigned short P3[] = {0022123,0011431,0105056,0001560,};
  370. #define DP1 *(double *)P1
  371. #define DP2 *(double *)P2
  372. #define DP3 *(double *)P3
  373. #endif
  374. #ifdef IBMPC
  375. static unsigned short P1[] = {0x0000,0x5400,0x21fb,0x4009};
  376. static unsigned short P2[] = {0x0000,0x1000,0x0b46,0x3e21};
  377. static unsigned short P3[] = {0xc06e,0x3145,0x6263,0x3c6a};
  378. #define DP1 *(double *)P1
  379. #define DP2 *(double *)P2
  380. #define DP3 *(double *)P3
  381. #endif
  382. #ifdef MIEEE
  383. static unsigned short P1[] = {
  384. 0x4009,0x21fb,0x5400,0x0000
  385. };
  386. static unsigned short P2[] = {
  387. 0x3e21,0x0b46,0x1000,0x0000
  388. };
  389. static unsigned short P3[] = {
  390. 0x3c6a,0x6263,0x3145,0xc06e
  391. };
  392. #define DP1 *(double *)P1
  393. #define DP2 *(double *)P2
  394. #define DP3 *(double *)P3
  395. #endif
  396. static double redupi(x)
  397. double x;
  398. {
  399. double t;
  400. long i;
  401. t = x/PI;
  402. if( t >= 0.0 )
  403. t += 0.5;
  404. else
  405. t -= 0.5;
  406. i = t; /* the multiple */
  407. t = i;
  408. t = ((x - t * DP1) - t * DP2) - t * DP3;
  409. return(t);
  410. }
  411. /* Taylor series expansion for cosh(2y) - cos(2x) */
  412. static double ctans(z)
  413. cmplx *z;
  414. {
  415. double f, x, x2, y, y2, rn, t;
  416. double d;
  417. x = fabs( 2.0 * z->r );
  418. y = fabs( 2.0 * z->i );
  419. x = redupi(x);
  420. x = x * x;
  421. y = y * y;
  422. x2 = 1.0;
  423. y2 = 1.0;
  424. f = 1.0;
  425. rn = 0.0;
  426. d = 0.0;
  427. do
  428. {
  429. rn += 1.0;
  430. f *= rn;
  431. rn += 1.0;
  432. f *= rn;
  433. x2 *= x;
  434. y2 *= y;
  435. t = y2 + x2;
  436. t /= f;
  437. d += t;
  438. rn += 1.0;
  439. f *= rn;
  440. rn += 1.0;
  441. f *= rn;
  442. x2 *= x;
  443. y2 *= y;
  444. t = y2 - x2;
  445. t /= f;
  446. d += t;
  447. }
  448. while( fabs(t/d) > MACHEP );
  449. return(d);
  450. }
  451. /* casin()
  452. *
  453. * Complex circular arc sine
  454. *
  455. *
  456. *
  457. * SYNOPSIS:
  458. *
  459. * void casin();
  460. * cmplx z, w;
  461. *
  462. * casin( &z, &w );
  463. *
  464. *
  465. *
  466. * DESCRIPTION:
  467. *
  468. * Inverse complex sine:
  469. *
  470. * 2
  471. * w = -i clog( iz + csqrt( 1 - z ) ).
  472. *
  473. *
  474. * ACCURACY:
  475. *
  476. * Relative error:
  477. * arithmetic domain # trials peak rms
  478. * DEC -10,+10 10100 2.1e-15 3.4e-16
  479. * IEEE -10,+10 30000 2.2e-14 2.7e-15
  480. * Larger relative error can be observed for z near zero.
  481. * Also tested by csin(casin(z)) = z.
  482. */
  483. void casin( z, w )
  484. cmplx *z, *w;
  485. {
  486. static cmplx ca, ct, zz, z2;
  487. double x, y;
  488. x = z->r;
  489. y = z->i;
  490. if( y == 0.0 )
  491. {
  492. if( fabs(x) > 1.0 )
  493. {
  494. w->r = PIO2;
  495. w->i = 0.0;
  496. mtherr( "casin", DOMAIN );
  497. }
  498. else
  499. {
  500. w->r = asin(x);
  501. w->i = 0.0;
  502. }
  503. return;
  504. }
  505. /* Power series expansion */
  506. /*
  507. b = cabs(z);
  508. if( b < 0.125 )
  509. {
  510. z2.r = (x - y) * (x + y);
  511. z2.i = 2.0 * x * y;
  512. cn = 1.0;
  513. n = 1.0;
  514. ca.r = x;
  515. ca.i = y;
  516. sum.r = x;
  517. sum.i = y;
  518. do
  519. {
  520. ct.r = z2.r * ca.r - z2.i * ca.i;
  521. ct.i = z2.r * ca.i + z2.i * ca.r;
  522. ca.r = ct.r;
  523. ca.i = ct.i;
  524. cn *= n;
  525. n += 1.0;
  526. cn /= n;
  527. n += 1.0;
  528. b = cn/n;
  529. ct.r *= b;
  530. ct.i *= b;
  531. sum.r += ct.r;
  532. sum.i += ct.i;
  533. b = fabs(ct.r) + fabs(ct.i);
  534. }
  535. while( b > MACHEP );
  536. w->r = sum.r;
  537. w->i = sum.i;
  538. return;
  539. }
  540. */
  541. ca.r = x;
  542. ca.i = y;
  543. ct.r = -ca.i; /* iz */
  544. ct.i = ca.r;
  545. /* sqrt( 1 - z*z) */
  546. /* cmul( &ca, &ca, &zz ) */
  547. zz.r = (ca.r - ca.i) * (ca.r + ca.i); /*x * x - y * y */
  548. zz.i = 2.0 * ca.r * ca.i;
  549. zz.r = 1.0 - zz.r;
  550. zz.i = -zz.i;
  551. csqrt( &zz, &z2 );
  552. cadd( &z2, &ct, &zz );
  553. clog( &zz, &zz );
  554. w->r = zz.i; /* mult by 1/i = -i */
  555. w->i = -zz.r;
  556. return;
  557. }
  558. /* cacos()
  559. *
  560. * Complex circular arc cosine
  561. *
  562. *
  563. *
  564. * SYNOPSIS:
  565. *
  566. * void cacos();
  567. * cmplx z, w;
  568. *
  569. * cacos( &z, &w );
  570. *
  571. *
  572. *
  573. * DESCRIPTION:
  574. *
  575. *
  576. * w = arccos z = PI/2 - arcsin z.
  577. *
  578. *
  579. *
  580. *
  581. * ACCURACY:
  582. *
  583. * Relative error:
  584. * arithmetic domain # trials peak rms
  585. * DEC -10,+10 5200 1.6e-15 2.8e-16
  586. * IEEE -10,+10 30000 1.8e-14 2.2e-15
  587. */
  588. void cacos( z, w )
  589. cmplx *z, *w;
  590. {
  591. casin( z, w );
  592. w->r = PIO2 - w->r;
  593. w->i = -w->i;
  594. }
  595. /* catan()
  596. *
  597. * Complex circular arc tangent
  598. *
  599. *
  600. *
  601. * SYNOPSIS:
  602. *
  603. * void catan();
  604. * cmplx z, w;
  605. *
  606. * catan( &z, &w );
  607. *
  608. *
  609. *
  610. * DESCRIPTION:
  611. *
  612. * If
  613. * z = x + iy,
  614. *
  615. * then
  616. * 1 ( 2x )
  617. * Re w = - arctan(-----------) + k PI
  618. * 2 ( 2 2)
  619. * (1 - x - y )
  620. *
  621. * ( 2 2)
  622. * 1 (x + (y+1) )
  623. * Im w = - log(------------)
  624. * 4 ( 2 2)
  625. * (x + (y-1) )
  626. *
  627. * Where k is an arbitrary integer.
  628. *
  629. *
  630. *
  631. * ACCURACY:
  632. *
  633. * Relative error:
  634. * arithmetic domain # trials peak rms
  635. * DEC -10,+10 5900 1.3e-16 7.8e-18
  636. * IEEE -10,+10 30000 2.3e-15 8.5e-17
  637. * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2,
  638. * had peak relative error 1.5e-16, rms relative error
  639. * 2.9e-17. See also clog().
  640. */
  641. void catan( z, w )
  642. cmplx *z, *w;
  643. {
  644. double a, t, x, x2, y;
  645. x = z->r;
  646. y = z->i;
  647. if( (x == 0.0) && (y > 1.0) )
  648. goto ovrf;
  649. x2 = x * x;
  650. a = 1.0 - x2 - (y * y);
  651. if( a == 0.0 )
  652. goto ovrf;
  653. #if ANSIC
  654. t = atan2( 2.0 * x, a )/2.0;
  655. #else
  656. t = atan2( a, 2.0 * x )/2.0;
  657. #endif
  658. w->r = redupi( t );
  659. t = y - 1.0;
  660. a = x2 + (t * t);
  661. if( a == 0.0 )
  662. goto ovrf;
  663. t = y + 1.0;
  664. a = (x2 + (t * t))/a;
  665. w->i = log(a)/4.0;
  666. return;
  667. ovrf:
  668. mtherr( "catan", OVERFLOW );
  669. w->r = MAXNUM;
  670. w->i = MAXNUM;
  671. }
  672. /* csinh
  673. *
  674. * Complex hyperbolic sine
  675. *
  676. *
  677. *
  678. * SYNOPSIS:
  679. *
  680. * void csinh();
  681. * cmplx z, w;
  682. *
  683. * csinh( &z, &w );
  684. *
  685. *
  686. * DESCRIPTION:
  687. *
  688. * csinh z = (cexp(z) - cexp(-z))/2
  689. * = sinh x * cos y + i cosh x * sin y .
  690. *
  691. * ACCURACY:
  692. *
  693. * Relative error:
  694. * arithmetic domain # trials peak rms
  695. * IEEE -10,+10 30000 3.1e-16 8.2e-17
  696. *
  697. */
  698. void
  699. csinh (z, w)
  700. cmplx *z, *w;
  701. {
  702. double x, y;
  703. x = z->r;
  704. y = z->i;
  705. w->r = sinh (x) * cos (y);
  706. w->i = cosh (x) * sin (y);
  707. }
  708. /* casinh
  709. *
  710. * Complex inverse hyperbolic sine
  711. *
  712. *
  713. *
  714. * SYNOPSIS:
  715. *
  716. * void casinh();
  717. * cmplx z, w;
  718. *
  719. * casinh (&z, &w);
  720. *
  721. *
  722. *
  723. * DESCRIPTION:
  724. *
  725. * casinh z = -i casin iz .
  726. *
  727. * ACCURACY:
  728. *
  729. * Relative error:
  730. * arithmetic domain # trials peak rms
  731. * IEEE -10,+10 30000 1.8e-14 2.6e-15
  732. *
  733. */
  734. void
  735. casinh (z, w)
  736. cmplx *z, *w;
  737. {
  738. cmplx u;
  739. u.r = 0.0;
  740. u.i = 1.0;
  741. cmul( z, &u, &u );
  742. casin( &u, w );
  743. u.r = 0.0;
  744. u.i = -1.0;
  745. cmul( &u, w, w );
  746. }
  747. /* ccosh
  748. *
  749. * Complex hyperbolic cosine
  750. *
  751. *
  752. *
  753. * SYNOPSIS:
  754. *
  755. * void ccosh();
  756. * cmplx z, w;
  757. *
  758. * ccosh (&z, &w);
  759. *
  760. *
  761. *
  762. * DESCRIPTION:
  763. *
  764. * ccosh(z) = cosh x cos y + i sinh x sin y .
  765. *
  766. * ACCURACY:
  767. *
  768. * Relative error:
  769. * arithmetic domain # trials peak rms
  770. * IEEE -10,+10 30000 2.9e-16 8.1e-17
  771. *
  772. */
  773. void
  774. ccosh (z, w)
  775. cmplx *z, *w;
  776. {
  777. double x, y;
  778. x = z->r;
  779. y = z->i;
  780. w->r = cosh (x) * cos (y);
  781. w->i = sinh (x) * sin (y);
  782. }
  783. /* cacosh
  784. *
  785. * Complex inverse hyperbolic cosine
  786. *
  787. *
  788. *
  789. * SYNOPSIS:
  790. *
  791. * void cacosh();
  792. * cmplx z, w;
  793. *
  794. * cacosh (&z, &w);
  795. *
  796. *
  797. *
  798. * DESCRIPTION:
  799. *
  800. * acosh z = i acos z .
  801. *
  802. * ACCURACY:
  803. *
  804. * Relative error:
  805. * arithmetic domain # trials peak rms
  806. * IEEE -10,+10 30000 1.6e-14 2.1e-15
  807. *
  808. */
  809. void
  810. cacosh (z, w)
  811. cmplx *z, *w;
  812. {
  813. cmplx u;
  814. cacos( z, w );
  815. u.r = 0.0;
  816. u.i = 1.0;
  817. cmul( &u, w, w );
  818. }
  819. /* ctanh
  820. *
  821. * Complex hyperbolic tangent
  822. *
  823. *
  824. *
  825. * SYNOPSIS:
  826. *
  827. * void ctanh();
  828. * cmplx z, w;
  829. *
  830. * ctanh (&z, &w);
  831. *
  832. *
  833. *
  834. * DESCRIPTION:
  835. *
  836. * tanh z = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y) .
  837. *
  838. * ACCURACY:
  839. *
  840. * Relative error:
  841. * arithmetic domain # trials peak rms
  842. * IEEE -10,+10 30000 1.7e-14 2.4e-16
  843. *
  844. */
  845. /* 5.253E-02,1.550E+00 1.643E+01,6.553E+00 1.729E-14 21355 */
  846. void
  847. ctanh (z, w)
  848. cmplx *z, *w;
  849. {
  850. double x, y, d;
  851. x = z->r;
  852. y = z->i;
  853. d = cosh (2.0 * x) + cos (2.0 * y);
  854. w->r = sinh (2.0 * x) / d;
  855. w->i = sin (2.0 * y) / d;
  856. return;
  857. }
  858. /* catanh
  859. *
  860. * Complex inverse hyperbolic tangent
  861. *
  862. *
  863. *
  864. * SYNOPSIS:
  865. *
  866. * void catanh();
  867. * cmplx z, w;
  868. *
  869. * catanh (&z, &w);
  870. *
  871. *
  872. *
  873. * DESCRIPTION:
  874. *
  875. * Inverse tanh, equal to -i catan (iz);
  876. *
  877. * ACCURACY:
  878. *
  879. * Relative error:
  880. * arithmetic domain # trials peak rms
  881. * IEEE -10,+10 30000 2.3e-16 6.2e-17
  882. *
  883. */
  884. void
  885. catanh (z, w)
  886. cmplx *z, *w;
  887. {
  888. cmplx u;
  889. u.r = 0.0;
  890. u.i = 1.0;
  891. cmul (z, &u, &u); /* i z */
  892. catan (&u, w);
  893. u.r = 0.0;
  894. u.i = -1.0;
  895. cmul (&u, w, w); /* -i catan iz */
  896. return;
  897. }
  898. /* cpow
  899. *
  900. * Complex power function
  901. *
  902. *
  903. *
  904. * SYNOPSIS:
  905. *
  906. * void cpow();
  907. * cmplx a, z, w;
  908. *
  909. * cpow (&a, &z, &w);
  910. *
  911. *
  912. *
  913. * DESCRIPTION:
  914. *
  915. * Raises complex A to the complex Zth power.
  916. * Definition is per AMS55 # 4.2.8,
  917. * analytically equivalent to cpow(a,z) = cexp(z clog(a)).
  918. *
  919. * ACCURACY:
  920. *
  921. * Relative error:
  922. * arithmetic domain # trials peak rms
  923. * IEEE -10,+10 30000 9.4e-15 1.5e-15
  924. *
  925. */
  926. void
  927. cpow (a, z, w)
  928. cmplx *a, *z, *w;
  929. {
  930. double x, y, r, theta, absa, arga;
  931. x = z->r;
  932. y = z->i;
  933. absa = cabs (a);
  934. if (absa == 0.0)
  935. {
  936. w->r = 0.0;
  937. w->i = 0.0;
  938. return;
  939. }
  940. arga = atan2 (a->i, a->r);
  941. r = pow (absa, x);
  942. theta = x * arga;
  943. if (y != 0.0)
  944. {
  945. r = r * exp (-y * arga);
  946. theta = theta + y * log (absa);
  947. }
  948. w->r = r * cos (theta);
  949. w->i = r * sin (theta);
  950. return;
  951. }