cmplxf.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. /* cmplxf.c
  2. *
  3. * Complex number arithmetic
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * typedef struct {
  10. * float r; real part
  11. * float i; imaginary part
  12. * }cmplxf;
  13. *
  14. * cmplxf *a, *b, *c;
  15. *
  16. * caddf( a, b, c ); c = b + a
  17. * csubf( a, b, c ); c = b - a
  18. * cmulf( a, b, c ); c = b * a
  19. * cdivf( a, b, c ); c = b / a
  20. * cnegf( c ); c = -c
  21. * cmovf( b, c ); c = b
  22. *
  23. *
  24. *
  25. * DESCRIPTION:
  26. *
  27. * Addition:
  28. * c.r = b.r + a.r
  29. * c.i = b.i + a.i
  30. *
  31. * Subtraction:
  32. * c.r = b.r - a.r
  33. * c.i = b.i - a.i
  34. *
  35. * Multiplication:
  36. * c.r = b.r * a.r - b.i * a.i
  37. * c.i = b.r * a.i + b.i * a.r
  38. *
  39. * Division:
  40. * d = a.r * a.r + a.i * a.i
  41. * c.r = (b.r * a.r + b.i * a.i)/d
  42. * c.i = (b.i * a.r - b.r * a.i)/d
  43. * ACCURACY:
  44. *
  45. * In DEC arithmetic, the test (1/z) * z = 1 had peak relative
  46. * error 3.1e-17, rms 1.2e-17. The test (y/z) * (z/y) = 1 had
  47. * peak relative error 8.3e-17, rms 2.1e-17.
  48. *
  49. * Tests in the rectangle {-10,+10}:
  50. * Relative error:
  51. * arithmetic function # trials peak rms
  52. * IEEE cadd 30000 5.9e-8 2.6e-8
  53. * IEEE csub 30000 6.0e-8 2.6e-8
  54. * IEEE cmul 30000 1.1e-7 3.7e-8
  55. * IEEE cdiv 30000 2.1e-7 5.7e-8
  56. */
  57. /* cmplx.c
  58. * complex number arithmetic
  59. */
  60. /*
  61. Cephes Math Library Release 2.1: December, 1988
  62. Copyright 1984, 1987, 1988 by Stephen L. Moshier
  63. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  64. */
  65. #include <math.h>
  66. extern float MAXNUMF, MACHEPF, PIF, PIO2F;
  67. #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
  68. #ifdef ANSIC
  69. float sqrtf(float), frexpf(float, int *);
  70. float ldexpf(float, int);
  71. float cabsf(cmplxf *), atan2f(float, float), cosf(float), sinf(float);
  72. #else
  73. float sqrtf(), frexpf(), ldexpf();
  74. float cabsf(), atan2f(), cosf(), sinf();
  75. #endif
  76. /*
  77. typedef struct
  78. {
  79. float r;
  80. float i;
  81. }cmplxf;
  82. */
  83. cmplxf czerof = {0.0, 0.0};
  84. extern cmplxf czerof;
  85. cmplxf conef = {1.0, 0.0};
  86. extern cmplxf conef;
  87. /* c = b + a */
  88. void caddf( a, b, c )
  89. register cmplxf *a, *b;
  90. cmplxf *c;
  91. {
  92. c->r = b->r + a->r;
  93. c->i = b->i + a->i;
  94. }
  95. /* c = b - a */
  96. void csubf( a, b, c )
  97. register cmplxf *a, *b;
  98. cmplxf *c;
  99. {
  100. c->r = b->r - a->r;
  101. c->i = b->i - a->i;
  102. }
  103. /* c = b * a */
  104. void cmulf( a, b, c )
  105. register cmplxf *a, *b;
  106. cmplxf *c;
  107. {
  108. register float y;
  109. y = b->r * a->r - b->i * a->i;
  110. c->i = b->r * a->i + b->i * a->r;
  111. c->r = y;
  112. }
  113. /* c = b / a */
  114. void cdivf( a, b, c )
  115. register cmplxf *a, *b;
  116. cmplxf *c;
  117. {
  118. float y, p, q, w;
  119. y = a->r * a->r + a->i * a->i;
  120. p = b->r * a->r + b->i * a->i;
  121. q = b->i * a->r - b->r * a->i;
  122. if( y < 1.0f )
  123. {
  124. w = MAXNUMF * y;
  125. if( (fabsf(p) > w) || (fabsf(q) > w) || (y == 0.0f) )
  126. {
  127. c->r = MAXNUMF;
  128. c->i = MAXNUMF;
  129. mtherr( "cdivf", OVERFLOW );
  130. return;
  131. }
  132. }
  133. c->r = p/y;
  134. c->i = q/y;
  135. }
  136. /* b = a */
  137. void cmovf( a, b )
  138. register short *a, *b;
  139. {
  140. int i;
  141. i = 8;
  142. do
  143. *b++ = *a++;
  144. while( --i );
  145. }
  146. void cnegf( a )
  147. register cmplxf *a;
  148. {
  149. a->r = -a->r;
  150. a->i = -a->i;
  151. }
  152. /* cabsf()
  153. *
  154. * Complex absolute value
  155. *
  156. *
  157. *
  158. * SYNOPSIS:
  159. *
  160. * float cabsf();
  161. * cmplxf z;
  162. * float a;
  163. *
  164. * a = cabsf( &z );
  165. *
  166. *
  167. *
  168. * DESCRIPTION:
  169. *
  170. *
  171. * If z = x + iy
  172. *
  173. * then
  174. *
  175. * a = sqrt( x**2 + y**2 ).
  176. *
  177. * Overflow and underflow are avoided by testing the magnitudes
  178. * of x and y before squaring. If either is outside half of
  179. * the floating point full scale range, both are rescaled.
  180. *
  181. *
  182. * ACCURACY:
  183. *
  184. * Relative error:
  185. * arithmetic domain # trials peak rms
  186. * IEEE -10,+10 30000 1.2e-7 3.4e-8
  187. */
  188. /*
  189. Cephes Math Library Release 2.1: January, 1989
  190. Copyright 1984, 1987, 1989 by Stephen L. Moshier
  191. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  192. */
  193. /*
  194. typedef struct
  195. {
  196. float r;
  197. float i;
  198. }cmplxf;
  199. */
  200. /* square root of max and min numbers */
  201. #define SMAX 1.3043817825332782216E+19
  202. #define SMIN 7.6664670834168704053E-20
  203. #define PREC 12
  204. #define MAXEXPF 128
  205. #define SMAXT (2.0f * SMAX)
  206. #define SMINT (0.5f * SMIN)
  207. float cabsf( z )
  208. register cmplxf *z;
  209. {
  210. float x, y, b, re, im;
  211. int ex, ey, e;
  212. re = fabsf( z->r );
  213. im = fabsf( z->i );
  214. if( re == 0.0f )
  215. {
  216. return( im );
  217. }
  218. if( im == 0.0f )
  219. {
  220. return( re );
  221. }
  222. /* Get the exponents of the numbers */
  223. x = frexpf( re, &ex );
  224. y = frexpf( im, &ey );
  225. /* Check if one number is tiny compared to the other */
  226. e = ex - ey;
  227. if( e > PREC )
  228. return( re );
  229. if( e < -PREC )
  230. return( im );
  231. /* Find approximate exponent e of the geometric mean. */
  232. e = (ex + ey) >> 1;
  233. /* Rescale so mean is about 1 */
  234. x = ldexpf( re, -e );
  235. y = ldexpf( im, -e );
  236. /* Hypotenuse of the right triangle */
  237. b = sqrtf( x * x + y * y );
  238. /* Compute the exponent of the answer. */
  239. y = frexpf( b, &ey );
  240. ey = e + ey;
  241. /* Check it for overflow and underflow. */
  242. if( ey > MAXEXPF )
  243. {
  244. mtherr( "cabsf", OVERFLOW );
  245. return( MAXNUMF );
  246. }
  247. if( ey < -MAXEXPF )
  248. return(0.0f);
  249. /* Undo the scaling */
  250. b = ldexpf( b, e );
  251. return( b );
  252. }
  253. /* csqrtf()
  254. *
  255. * Complex square root
  256. *
  257. *
  258. *
  259. * SYNOPSIS:
  260. *
  261. * void csqrtf();
  262. * cmplxf z, w;
  263. *
  264. * csqrtf( &z, &w );
  265. *
  266. *
  267. *
  268. * DESCRIPTION:
  269. *
  270. *
  271. * If z = x + iy, r = |z|, then
  272. *
  273. * 1/2
  274. * Im w = [ (r - x)/2 ] ,
  275. *
  276. * Re w = y / 2 Im w.
  277. *
  278. *
  279. * Note that -w is also a square root of z. The solution
  280. * reported is always in the upper half plane.
  281. *
  282. * Because of the potential for cancellation error in r - x,
  283. * the result is sharpened by doing a Heron iteration
  284. * (see sqrt.c) in complex arithmetic.
  285. *
  286. *
  287. *
  288. * ACCURACY:
  289. *
  290. * Relative error:
  291. * arithmetic domain # trials peak rms
  292. * IEEE -10,+10 100000 1.8e-7 4.2e-8
  293. *
  294. */
  295. void csqrtf( z, w )
  296. cmplxf *z, *w;
  297. {
  298. cmplxf q, s;
  299. float x, y, r, t;
  300. x = z->r;
  301. y = z->i;
  302. if( y == 0.0f )
  303. {
  304. if( x < 0.0f )
  305. {
  306. w->r = 0.0f;
  307. w->i = sqrtf(-x);
  308. return;
  309. }
  310. else
  311. {
  312. w->r = sqrtf(x);
  313. w->i = 0.0f;
  314. return;
  315. }
  316. }
  317. if( x == 0.0f )
  318. {
  319. r = fabsf(y);
  320. r = sqrtf(0.5f*r);
  321. if( y > 0 )
  322. w->r = r;
  323. else
  324. w->r = -r;
  325. w->i = r;
  326. return;
  327. }
  328. /* Approximate sqrt(x^2+y^2) - x = y^2/2x - y^4/24x^3 + ... .
  329. * The relative error in the first term is approximately y^2/12x^2 .
  330. */
  331. if( (fabsf(y) < fabsf(0.015f*x))
  332. && (x > 0) )
  333. {
  334. t = 0.25f*y*(y/x);
  335. }
  336. else
  337. {
  338. r = cabsf(z);
  339. t = 0.5f*(r - x);
  340. }
  341. r = sqrtf(t);
  342. q.i = r;
  343. q.r = 0.5f*y/r;
  344. /* Heron iteration in complex arithmetic:
  345. * q = (q + z/q)/2
  346. */
  347. cdivf( &q, z, &s );
  348. caddf( &q, &s, w );
  349. w->r *= 0.5f;
  350. w->i *= 0.5f;
  351. }