s_ctanf.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* $OpenBSD: s_ctanf.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */
  2. /*
  3. * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* ctanf()
  18. *
  19. * Complex circular tangent
  20. *
  21. *
  22. *
  23. * SYNOPSIS:
  24. *
  25. * void ctanf();
  26. * cmplxf z, w;
  27. *
  28. * ctanf( &z, &w );
  29. *
  30. *
  31. *
  32. * DESCRIPTION:
  33. *
  34. * If
  35. * z = x + iy,
  36. *
  37. * then
  38. *
  39. * sin 2x + i sinh 2y
  40. * w = --------------------.
  41. * cos 2x + cosh 2y
  42. *
  43. * On the real axis the denominator is zero at odd multiples
  44. * of PI/2. The denominator is evaluated by its Taylor
  45. * series near these points.
  46. *
  47. *
  48. * ACCURACY:
  49. *
  50. * Relative error:
  51. * arithmetic domain # trials peak rms
  52. * IEEE -10,+10 30000 3.3e-7 5.1e-8
  53. */
  54. #include <complex.h>
  55. #include "openlibm.h"
  56. #define MACHEPF 3.0e-8
  57. #define MAXNUMF 1.0e38f
  58. static const double DP1 = 3.140625;
  59. static const double DP2 = 9.67502593994140625E-4;
  60. static const double DP3 = 1.509957990978376432E-7;
  61. static float
  62. _redupif(float xx)
  63. {
  64. float x, t;
  65. long i;
  66. x = xx;
  67. t = x/(float)M_PI;
  68. if(t >= 0.0)
  69. t += 0.5;
  70. else
  71. t -= 0.5;
  72. i = t; /* the multiple */
  73. t = i;
  74. t = ((x - t * DP1) - t * DP2) - t * DP3;
  75. return(t);
  76. }
  77. /* Taylor series expansion for cosh(2y) - cos(2x) */
  78. static float
  79. _ctansf(float complex z)
  80. {
  81. float f, x, x2, y, y2, rn, t, d;
  82. x = fabsf(2.0f * crealf(z));
  83. y = fabsf(2.0f * cimagf(z));
  84. x = _redupif(x);
  85. x = x * x;
  86. y = y * y;
  87. x2 = 1.0f;
  88. y2 = 1.0f;
  89. f = 1.0f;
  90. rn = 0.0f;
  91. d = 0.0f;
  92. do {
  93. rn += 1.0f;
  94. f *= rn;
  95. rn += 1.0f;
  96. f *= rn;
  97. x2 *= x;
  98. y2 *= y;
  99. t = y2 + x2;
  100. t /= f;
  101. d += t;
  102. rn += 1.0f;
  103. f *= rn;
  104. rn += 1.0f;
  105. f *= rn;
  106. x2 *= x;
  107. y2 *= y;
  108. t = y2 - x2;
  109. t /= f;
  110. d += t;
  111. }
  112. while (fabsf(t/d) > MACHEPF)
  113. ;
  114. return(d);
  115. }
  116. float complex
  117. ctanf(float complex z)
  118. {
  119. float complex w;
  120. float d;
  121. d = cosf( 2.0f * crealf(z) ) + coshf( 2.0f * cimagf(z) );
  122. if(fabsf(d) < 0.25f)
  123. d = _ctansf(z);
  124. if (d == 0.0f) {
  125. /*mtherr( "ctanf", OVERFLOW );*/
  126. w = MAXNUMF + MAXNUMF * I;
  127. return (w);
  128. }
  129. w = sinf (2.0f * crealf(z)) / d + (sinhf (2.0f * cimagf(z)) / d) * I;
  130. return (w);
  131. }