home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 05 / titel / complex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-03  |  14.9 KB  |  519 lines

  1. /**********************************************************/
  2. /*                                                        */
  3. /*                       COMPLEX.C                        */
  4. /*    INCLUDE-Datei zum Rechnen mit komplexen Zahlen.     */
  5. /*                                                        */
  6. /*                  Sprache: Turbo C 2.0                  */
  7. /*                                                        */
  8. /*               Autor: Ralf Baethke-Franke               */
  9. /*              (C) 1991 Ralf Baethke-Franke              */
  10. /*                                                        */
  11. /**********************************************************/
  12.  
  13.  
  14. /**********************************************************/
  15. /*                                                        */
  16. /* Die Funktionen und ihre Berechnung:                    */
  17. /* -----------------------------------                    */
  18. /*                                                        */
  19. /* Es gilt grundsätzlich: z = x + iy                      */
  20. /*                        mit x = z.re und y = z.im       */
  21. /* Absolutbetrag:         r = abs_c(z)                    */
  22. /*                        r = |z| = √(x² + y²)            */
  23. /* Argument:              w =       atan(y/x)             */
  24. /*                                                        */
  25. /* 1. Grundrechenarten                                    */
  26. /* 1.1. Addition        z = add_c(z1,z2)                  */
  27. /*      z1 + z2 = (x1 + x2) + i(y1 + y2)                  */
  28. /* 1.2. Subtraktion     z = sub_c(z1,z2)                  */
  29. /*      z1 - z2 = (x1 - x2) - i(y1 - y2)                  */
  30. /* 1.3. Multiplikation  z = mul_c(z1,z2)                  */
  31. /*      z1 * z2 = x1x2 - y1y2 + i(x1y2 + y1x2)            */
  32. /* 1.4. Division        z = div_c(z1,z2)                  */
  33. /*        z1    x1x2 + y1y2     x1y2 - y1x2               */
  34. /*        --  = ----------- + i -----------               */
  35. /*        z2        |z|²            |z|²                  */
  36. /*                                                        */
  37. /* 2. Potenzen und Wurzeln                                */
  38. /* 2.1. Potenzen und Exponentialfunktion                  */
  39. /* 2.1.1. Quadrat         z = sqr_c(z1)                   */
  40. /*        z² = (x1² - y1²) + 2*i*x1y1                     */
  41. /* 2.1.2. reelle Potenz   z = pot_c(z1,n)                 */
  42. /*        z1ⁿ = r1ⁿ (cos(nw1) + isin(nw1))                */
  43. /* 2.1.3. komplexe Potenz z = pot_cc(z1,z2)               */
  44. /*        z1^z2 = exp(z2*ln(z1))                          */
  45. /* 2.1.4. Exponentialfkt. z = exp_c(z1)                   */
  46. /*        exp(z1) = exp(x1)*(cos(y1) + isin(y1))          */
  47. /* 2.2. Wurzeln und natürl. Logarithmus                   */
  48. /* 2.2.1. Quadratwurzel   z = sqrt_c(z1)                  */
  49. /*        √z1 =  ±√ ((r1 + x1)/2) ± i * √((r1 - x1)/2)    */
  50. /*  Es wird nur die erste der 4 mögl. Wurzeln berechnet   */
  51. /* 2.2.2. reelle Wurzel   z = rad_c(z1,n)                 */
  52. /*     ⁿ√z1 = z1^(1/n)                                    */
  53. /* 2.2.3. komplexe Wurzel z = rad_cc(z1,z2)               */
  54. /*        (z2)√z1 = z1^(1/z2)                             */
  55. /* 2.2.4. Logarithmus     z = ln_c(z1)                    */
  56. /*        ln(z1) = ln(r1) + i*w1                          */
  57. /* Es wird der Hauptzweig des nat. Logarithmus berechnet  */
  58. /*                                                        */
  59. /* 3. Trigonometrische Funktionen                         */
  60. /* 3.1. Sinus           z = sin_c(z1)                     */
  61. /*      sin(z1) = sin(x1)cosh(y1) + i * cos(x1)sinh(y1)   */
  62. /* 3.2. Cosinus         z = cos_c(z1)                     */
  63. /*      cos(z1) = cos(x1)cosh(y1) - i * sin(x1)sinh(y1)   */
  64. /* 3.3. Tangens         z = tan_c(z1)                     */
  65. /*      tan(z1) = sin(z1)/cos(z1)                         */
  66. /* 3.4. Cotangens       z = cot_c(z1)                     */
  67. /*      cot(z1) = cos(z1)/sin(z1)                         */
  68. /*                                                        */
  69. /* 4. Trigonometrische Umkehrfunktionen                   */
  70. /* 4.1. Arcussinus      z = asin_c(z1)                    */
  71. /*      asin(z1) = -i*ln(i*z1 + √(1 - z²))                */
  72. /* 4.2. Arcuscosinus    z = acos_c(z1)                    */
  73. /*      acos(z1) = -i*ln(z1 + √(z1² -1))                  */
  74. /* 4.3. Arcustangens    z = atan_c(z1)                    */
  75. /*                  1       1 + i*z1²                     */
  76. /*      atan(z1) = --- * ln(---------)                    */
  77. /*                 2*i      1 - i*z1²                     */
  78. /* 4.4. Arcuscotangens  z = acot_c(z1)                    */
  79. /*                 -1       i*z1² + 1                     */
  80. /*      acot(z1) = --- * ln(---------)                    */
  81. /*                 2*i      i*z1² - 1                     */
  82. /*                                                        */
  83. /* 5. Hyperbelfunktionen                                  */
  84. /* 5.1. Hyperbelsinus     z = sinh_c(z1)                  */
  85. /*      sinh(z1) = sinh(x1)cos(y1) + i*cosh(x1)sin(y1)    */
  86. /* 5.2. Hyperbelcosinus   z = cosh_c(z1)                  */
  87. /*      cosh(z1) = cosh(x1)cos(y1) + i*sinh(x1)sin(y1)    */
  88. /* 5.3. Hyperbeltangens   z = tanh_c(z1)                  */
  89. /*      tanh(z1) = sinh(z1) / cosh(z1)                    */
  90. /* 5.4. Hyperbelcotangens z = coth_c(z1)                  */
  91. /*      coth(z1) = cosh(z1) / sinh(z1)                    */
  92. /*                                                        */
  93. /* 6. Umkehrungen der Hyperbelfunktionen                  */
  94. /* 6.1. Arcus-Hyperbelsinus     z = asinh_c(z1)           */
  95. /*      asinh(z1) = ln(z1 + √(z1² + 1))                   */
  96. /* 6.2. Arcus-Hyperbelcosinus   z = acosh_c(z1)           */
  97. /*      acosh(z1) = ln(z1 + √(z1² - 1))                   */
  98. /* 6.3. Arcus-Hyperbeltangens   z = atanh_c(z1)           */
  99. /*                  1      1 + z                          */
  100. /*      atanh(z1) = - * ln(-----)                         */
  101. /*                  2      1 - z                          */
  102. /* 6.4. Arcus-Hyperbelcotangens z = atanh_c(z1)           */
  103. /*                  1      z + 1                          */
  104. /*      atanh(z1) = - * ln(-----)                         */
  105. /*                  2      z - 1                          */
  106. /*                                                        */
  107. /**********************************************************/
  108.  
  109. #include <math.h>
  110.  
  111. #define PI M_PI
  112. #define PI_HALBE PI/2
  113. #define ZWEI_PI 2 * PI
  114. #define INF 9e307
  115.  
  116. typedef struct
  117. {
  118.    double re, im;
  119. } compl;
  120.  
  121. /******************* Funktionsprototypen *****************/
  122.  
  123. double arg_opt ( double arg );
  124. double sqr ( double x );
  125. int sgn ( double i );
  126. int sign ( double i );
  127. double abs_c ( compl z );
  128. double arg_c ( compl z );
  129. compl konj_kompl ( compl z );
  130. compl add_c ( compl z1, compl z2 );
  131. compl sub_c ( compl z1, compl z2 );
  132. compl mul_c ( compl z1, compl z2 );
  133. compl div_c ( compl z1, compl z2 );
  134. compl sqr_c ( compl z1 );
  135. compl sqrt_c ( compl z1 );
  136. compl pot_c ( compl z1, double p);
  137. compl rad_c ( compl z1, double r );
  138. compl pot_cc ( compl z1, compl z2 );
  139. compl rad_cc ( compl z1, compl z2 );
  140. compl exp_c ( compl z1 );
  141. compl ln_c ( compl z1 );
  142. compl sin_c ( compl z1 );
  143. compl cos_c(compl z1);
  144. compl tan_c ( compl z1 );
  145. compl cot_c ( compl z1 );
  146. compl asin_c ( compl z1 );
  147. compl acos_c ( compl z1 );
  148. compl atan_c ( compl z1 );
  149. compl acot_c ( compl z1 );
  150. compl sinh_c ( compl z1 );
  151. compl cosh_c ( compl z1 );
  152. compl tanh_c ( compl z1 );
  153. compl coth_c ( compl z1 );
  154. compl asinh_c ( compl z1 );
  155. compl acosh_c ( compl z1 );
  156. compl atanh_c ( compl z1 );
  157. compl acoth_c ( compl z1 );
  158.  
  159. /********************* Hilfsfunktionen ********************/
  160.  
  161. double arg_opt ( double arg )
  162. /* dient zur Vermeidung von zu großen / kleinen Argu-     */
  163. /* menten bei Winkelfunktionen                            */
  164. {
  165.    if ( arg > ZWEI_PI )
  166.                    arg -= floor ( arg / ZWEI_PI ) * ZWEI_PI;
  167.    if ( arg < - ZWEI_PI )
  168.                    arg += floor ( arg / ZWEI_PI ) * ZWEI_PI;
  169.    return ( arg );
  170. }
  171.  
  172. double sqr ( double x )     /* Quadrat einer reellen Zahl */
  173. {
  174.    return( x * x );
  175. }
  176.  
  177. int sgn ( double i )     /* Vorzeichen einer reellen Zahl */
  178. {                        /* sgn(0) = +1                   */
  179.    int sgn;
  180.    sgn = ( i < 0 ) ? -1 : 1;
  181.    return ( sgn );
  182. }
  183.  
  184. int sign ( double i )    /* Vorzeichen einer reellen Zahl */
  185. {                        /* sign(0) = 0                   */
  186.    int sign;
  187.    sign = ( !i ) ? 0 : sgn ( i );
  188.    return ( sign );
  189. }
  190.  
  191. double abs_c ( compl z )   /* Betrag einer komplexen Zahl */
  192. {
  193.    return ( hypot ( z.re, z.im ) );
  194. }
  195.  
  196. double arg_c ( compl z )    /* Argument einer kompl. Zahl */
  197. {
  198.    double arg;
  199.    if ( !z.re ) arg = sign ( z.im ) * PI_HALBE;
  200.    else arg = ( z.re > 0 ) ? atan ( z.im / z.re ) :
  201.                    atan ( z.im / z.re ) + sgn ( z.im ) * PI;
  202.    return ( arg );
  203. }
  204.  
  205. compl konj_kompl ( compl z )  /* konjugiert komplexe Zahl */
  206. {                             /* zu z -> z'               */
  207.    z.im = -z.im;
  208.    return ( z );
  209. }
  210.  
  211. /************** Grundrechenarten: +, -, *, / **************/
  212.  
  213. compl add_c ( compl z1, compl z2 )
  214. {
  215.    compl z;
  216.    z.re = z1.re + z2.re;
  217.    z.im = z1.im + z2.im;
  218.    return ( z );
  219. }
  220.  
  221. compl sub_c ( compl z1, compl z2 )
  222. {
  223.    compl z;
  224.    z.re = z1.re - z2.re;
  225.    z.im = z1.im - z2.im;
  226.    return ( z );
  227. }
  228.  
  229. compl mul_c ( compl z1, compl z2 )
  230. {
  231.    compl z;
  232.    z.re = z1.re * z2.re - z1.im * z2.im;
  233.    z.im = z1.re * z2.im + z1.im * z2.re;
  234.    return ( z );
  235. }
  236.  
  237. compl div_c ( compl z1, compl z2 )
  238. {
  239.    compl z;
  240.    if ( abs_c ( z2 ) == 0 )
  241.    {
  242.       z.re =  INF * sign ( z2.re );
  243.       z.im = -INF * sign ( z2.im );
  244.    }
  245.    else
  246.    {
  247.       z.re = ( z1.re * z2.re + z1.im * z2.im ) /
  248.                                        sqr ( abs_c ( z2 ) );
  249.       z.im = ( z1.im * z2.re - z1.re * z2.im ) /
  250.                                        sqr ( abs_c ( z2 ) );
  251.    }
  252.    return ( z );
  253. }
  254.  
  255. /***************** Potenzen und Wurzeln *******************/
  256.  
  257. compl sqr_c ( compl z1 )
  258. {
  259.    compl z;
  260.    z.re = sqr ( z1.re ) - sqr ( z1.im );
  261.    z.im = 2 * z1.re * z1.im;
  262.    return ( z );
  263. }
  264.  
  265. compl sqrt_c ( compl z1 )
  266. {
  267.    compl z;
  268.    z.re = sqrt ( ( abs_c ( z1 ) + z1.re ) / 2 );
  269.    z.im = sqrt ( ( abs_c ( z1 ) - z1.re ) / 2 );
  270.    return(z);
  271. }
  272.  
  273. compl pot_c ( compl z1, double p)
  274. {
  275.    compl z;
  276.    double betr, arg;
  277.    if ( p == 1 ) z = z1;
  278.    else if ( p == -1 )
  279.    {
  280.       z.re = 1;
  281.       z.im = 0;
  282.       z = div_c ( z, z1 );
  283.    }
  284.    else
  285.    {
  286.       betr = pow ( abs_c ( z1 ), p );
  287.       arg  = arg_opt ( p * arg_c ( z1 ) );
  288.       z.re = betr * cos ( arg );
  289.       z.im = betr * sin ( arg );
  290.    }
  291.    return ( z );
  292. }
  293.  
  294. compl rad_c ( compl z1, double r )
  295. {
  296.    compl z;
  297.    z = pot_c ( z1, 1 / r );
  298.    return ( z );
  299. }
  300.  
  301. compl pot_cc ( compl z1, compl z2 )
  302. {
  303.    compl z;
  304.    z = exp_c ( mul_c ( z2, ln_c ( z1 ) ) );
  305.    return ( z );
  306. }
  307.  
  308. compl rad_cc ( compl z1, compl z2 )
  309. {
  310.    compl z;
  311.    z.re = 1; z.im = 0;
  312.    z = pot_cc ( z1, div_c ( z, z2 ) );
  313.    return ( z );
  314. }
  315.  
  316. compl exp_c ( compl z1 )
  317. {
  318.    compl z;
  319.    z1.im = arg_opt ( z1.im );
  320.    z1.re = exp ( z1.re );
  321.    z.re  = z1.re * cos ( z1.im );
  322.    z.im  = z1.re * sin ( z1.im );
  323.    return ( z );
  324. }
  325.  
  326. compl ln_c ( compl z1 )
  327. {
  328.    compl z;
  329.    z.re = log ( abs_c ( z1 ) );
  330.    z.im = arg_c ( z1 );
  331.    return(z);
  332. }
  333.  
  334. /************** Trigonometrische Funktionen ***************/
  335.  
  336. compl sin_c ( compl z1 )
  337. {
  338.    compl z;
  339.    z1.re = arg_opt ( z1.re );
  340.    z.re = sin ( z1.re ) * cosh ( z1.im );
  341.    z.im = cos ( z1.re ) * sinh ( z1.im );
  342.    return(z);
  343. }
  344.  
  345. compl cos_c(compl z1)
  346. {
  347.    compl z;
  348.    z1.re = arg_opt ( z1.re );
  349.    z.re =  cos ( z1.re ) * cosh ( z1.im );
  350.    z.im = -sin ( z1.re ) * sinh ( z1.im );
  351.    return(z);
  352. }
  353.  
  354. compl tan_c ( compl z1 )
  355. {
  356.    compl z;
  357.    z = div_c ( sin_c ( z1 ), cos_c ( z1 ) );
  358.    return ( z );
  359. }
  360.  
  361. compl cot_c ( compl z1 )
  362. {
  363.    compl z;
  364.    z = div_c ( cos_c ( z1 ), sin_c ( z1 ) );
  365.    return ( z );
  366. }
  367.  
  368. /****** Umkehrungen der trigonometrischen Funktionen ******/
  369.  
  370. compl asin_c ( compl z1 )
  371. {
  372.    compl z, c1, c2, c3;
  373.    c1.re = 1; c1.im = 0;
  374.    c2.re = 0; c2.im = 1;
  375.    c3.re = 0; c3.im = -1;
  376.    z = sqr_c ( z1 );
  377.    z = sub_c ( c1, z);
  378.    z = sqrt_c ( z );
  379.    z = add_c ( mul_c ( c2, z1 ), z );
  380.    z = ln_c ( z );
  381.    z = mul_c ( c3, z );
  382.    return ( z );
  383. }
  384.  
  385. compl acos_c ( compl z1 )
  386. {
  387.    compl z, c1, c2;
  388.    c1.re = 1; c1.im = 0;
  389.    c2.re = 0; c2.im = -1;
  390.    z = sqr_c ( z1 );
  391.    z = sub_c ( z, c1);
  392.    z = sqrt_c ( z );
  393.    z = add_c ( z1, z );
  394.    z = ln_c ( z );
  395.    z = mul_c ( c2, z );
  396.    return ( z );
  397. }
  398.  
  399. compl atan_c ( compl z1 )
  400. {
  401.    compl z, c1, c2, c3, a1, a2;
  402.    c1.re = 0; c1.im = 1;
  403.    c2.re = 1; c2.im = 0;
  404.    c3.re = 0; c3.im = 2;
  405.    z = mul_c ( c1, z1 );
  406.    a1 = add_c ( c2, z );
  407.    a2 = sub_c ( c2, z );
  408.    z = div_c ( a1, a2 );
  409.    z = ln_c ( z );
  410.    a1 = div_c ( c2, c3 );
  411.    z = mul_c ( a1, z );
  412.    return ( z );
  413. }
  414.  
  415. compl acot_c ( compl z1 )
  416. {
  417.    compl z, c1, c2, c3, a1, a2;
  418.    c1.re = 0; c1.im = 1;
  419.    c2.re = 1; c2.im = 0;
  420.    c3.re = 0; c3.im = -2;
  421.    z = mul_c ( c1, z1 );
  422.    a1 = add_c ( z, c2 );
  423.    a2 = sub_c ( z, c2 );
  424.    z = div_c ( a1, a2 );
  425.    z = ln_c ( z );
  426.    a1 = div_c ( c2, c3 );
  427.    z = mul_c ( a1, z );
  428.    return ( z );
  429. }
  430.  
  431. /******************* Hyperbel-Funktionen ******************/
  432.  
  433. compl sinh_c ( compl z1 )
  434. {
  435.    compl z;
  436.    z1.im = arg_opt ( z1.im );
  437.    z.re = sinh ( z1.re ) * cos ( z1.im );
  438.    z.im = cosh ( z1.re ) * sin ( z1.im );
  439.    return ( z );
  440. }
  441.  
  442. compl cosh_c ( compl z1 )
  443.  
  444. {
  445.    compl z;
  446.    z1.im = arg_opt ( z1.im );
  447.    z.re = cosh ( z1.re ) * cos ( z1.im );
  448.    z.im = sinh ( z1.re ) * sin ( z1.im );
  449.    return ( z );
  450. }
  451.  
  452. compl tanh_c ( compl z1 )
  453. {
  454.    compl z;
  455.    z = div_c ( sinh_c ( z1 ), cosh_c ( z1 ) );
  456.    return ( z );
  457. }
  458.  
  459. compl coth_c ( compl z1 )
  460. {
  461.    compl z;
  462.    z = div_c ( cosh_c ( z1 ), sinh_c ( z1 ) );
  463.    return ( z );
  464. }
  465.  
  466. /*********** Umkehrungen der Hyperbel-Funktionen **********/
  467.  
  468. compl asinh_c ( compl z1 )
  469. {
  470.    compl z, c;
  471.    c.re = 1; c.im = 0;
  472.    z = sqr_c ( z1 );
  473.    z = add_c ( z, c );
  474.    z = sqrt_c ( z );
  475.    z = add_c ( z1, z );
  476.    z = ln_c ( z );
  477.    return ( z );
  478. }
  479.  
  480. compl acosh_c ( compl z1 )
  481. {
  482.    compl z, c;
  483.    c.re = -1; c.im = 0;
  484.    z = sqr_c ( z1 );
  485.    z = add_c ( z, c );
  486.    z = sqrt_c ( z );
  487.    z = add_c ( z1, z );
  488.    z = ln_c ( z );
  489.    return ( z );
  490. }
  491.  
  492. compl atanh_c ( compl z1 )
  493. {
  494.    compl z, c1, c2, a1, a2;
  495.    c1.re = 1; c1.im = 0;
  496.    c2.re = 2; c2.im = 0;
  497.    a1 = add_c ( c1, z1 );
  498.    a2 = sub_c ( c1, z1 );
  499.    z = div_c ( a1, a2 );
  500.    z = ln_c ( z );
  501.    z = div_c ( z, c2 );
  502.    return ( z );
  503. }
  504.  
  505. compl acoth_c ( compl z1 )
  506. {
  507.    compl z, c1, c2, a1, a2;
  508.    c1.re = 1; c1.im = 0;
  509.    c2.re = 2; c2.im = 0;
  510.    a1 = add_c ( z1, c1 );
  511.    a2 = sub_c ( z1, c1 );
  512.    z = div_c ( a1, a2 );
  513.    z = ln_c ( z );
  514.    z = div_c ( z, c2 );
  515.    return ( z );
  516. }
  517.  
  518. /******************* Ende von COMPLEX.C ******************/
  519.