home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_09 / 8n09049a < prev    next >
Text File  |  1990-07-26  |  8KB  |  333 lines

  1.  
  2.  
  3. Listing 4:
  4.  
  5. /***********************************************
  6. **                                            **
  7. **  Complex Function Library                  **
  8. **                                            **
  9. **  Maynard A. Wright, P. E.   4-16-90        **
  10. **                                            **
  11. ***********************************************/
  12.  
  13. /* This library must be linked with the program which
  14.    will call the functions defined herein.  The call-
  15.    ing program must also #include file cmplx.h for
  16.    structure and function declarations.  Multivalued
  17.    functions defined in this library will, in general,
  18.    return the solution with the smallest absolute
  19.    value.  The source code for this library is stored
  20.    as cmplxlib.c.
  21.  
  22.    stdlib.h is included because the variable errno is
  23.    declared in that header file in Microsoft C.
  24.  
  25.    Range and domain errors are trapped by evaluating
  26.    errno. Error diagnostics are directed to stderr and
  27.    the program exits, returning the value 1 to the
  28.    calling environment. */
  29.  
  30. /* Preprocessor Directives */
  31.  
  32. #include <errno.h>
  33. #include <math.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36.  
  37. #define LN10 2.3025851
  38. #define PI 3.1415927
  39.  
  40. /* Declarations */
  41.  
  42. static struct cmplx_nmbr
  43.  
  44. {
  45.    double real;
  46.    double imag;
  47.  
  48. } arg, arg1, arg2, answer, rtrn;
  49.  
  50. /* Function Prototypes */
  51.  
  52. struct cmplx_nmbr csinh(struct cmplx_nmbr);
  53. struct cmplx_nmbr ccosh(struct cmplx_nmbr);
  54. struct cmplx_nmbr ctanh(struct cmplx_nmbr);
  55. struct cmplx_nmbr catnh(struct cmplx_nmbr);
  56. struct cmplx_nmbr csin(struct cmplx_nmbr);
  57. struct cmplx_nmbr ccos(struct cmplx_nmbr);
  58. struct cmplx_nmbr ctan(struct cmplx_nmbr);
  59. struct cmplx_nmbr catn(struct cmplx_nmbr);
  60. struct cmplx_nmbr cexp(struct cmplx_nmbr);
  61. struct cmplx_nmbr cten2x(struct cmplx_nmbr);
  62. struct cmplx_nmbr cloge(struct cmplx_nmbr);
  63. struct cmplx_nmbr clog10(struct cmplx_nmbr);
  64. struct cmplx_nmbr cmplxinv(struct cmplx_nmbr);
  65. struct cmplx_nmbr cmplxadd(struct cmplx_nmbr,
  66.                            struct cmplx_nmbr);
  67. struct cmplx_nmbr cmplxsub(struct cmplx_nmbr,
  68.                            struct cmplx_nmbr);
  69. struct cmplx_nmbr cmplxmul(struct cmplx_nmbr,
  70.                            struct cmplx_nmbr);
  71. struct cmplx_nmbr cmplxdiv(struct cmplx_nmbr,
  72.                            struct cmplx_nmbr);
  73. void err_hndlr(char *name);
  74.  
  75. /* Complex Function Definitions */
  76.  
  77. struct cmplx_nmbr csinh(struct cmplx_nmbr param)
  78.  
  79. {
  80.    errno = 0;
  81.    rtrn.real = cos(param.imag) * sinh(param.real);
  82.    rtrn.imag = sin(param.imag) * cosh(param.real);
  83.    if(errno)
  84.       err_hndlr("CSINH()");
  85.    return rtrn;
  86. }
  87.  
  88. struct cmplx_nmbr ccosh(struct cmplx_nmbr param)
  89.  
  90. {
  91.    errno = 0;
  92.    rtrn.real = cos(param.imag) * cosh(param.real);
  93.    rtrn.imag = sin(param.imag) * sinh(param.real);
  94.    if(errno)
  95.       err_hndlr("CCOSH()");
  96.    return rtrn;
  97. }
  98.  
  99. struct cmplx_nmbr ctanh(struct cmplx_nmbr param)
  100.  
  101. {
  102.    double denom;
  103.    errno = 0;
  104.    denom = cosh(2 * param.real) + cos(2 * param.imag);
  105.    rtrn.real = sinh(2 * param.real) / denom;
  106.    rtrn.imag = sin(2 * param.imag) / denom;
  107.    if(errno)
  108.       err_hndlr("CTANH()");
  109.    return rtrn;
  110. }
  111.  
  112. struct cmplx_nmbr catnh(struct cmplx_nmbr param)
  113.  
  114. {
  115.    errno = 0;
  116.    rtrn.real = 0.25 * log(((1. + param.real) * (1. +
  117.          param.real) + param.imag * param.imag) /
  118.          ((1. - param.real) * (1. - param.real) +
  119.          param.imag * param.imag));
  120.    rtrn.imag = -0.5 * (PI - atan2((1. + param.real),
  121.          -param.imag) - atan2((1. - param.real),
  122.          -param.imag));
  123.    if(errno)
  124.       err_hndlr("CATNH()");
  125.    return rtrn;
  126. }
  127.  
  128. struct cmplx_nmbr csin(struct cmplx_nmbr param)
  129.  
  130. {
  131.    errno = 0;
  132.    rtrn.real = 0.5 * (exp(param.imag) 
  133.          + exp(-param.imag)) * sin(param.real);
  134.    rtrn.imag = 0.5 * (exp(param.imag) 
  135.          - exp(-param.imag)) * cos(param.real);
  136.    if(errno)
  137.       err_hndlr("CSIN()");
  138.    return rtrn;
  139. }
  140.  
  141. struct cmplx_nmbr ccos(struct cmplx_nmbr param)
  142.  
  143. {
  144.    errno = 0;
  145.    rtrn.real = 0.5 * (exp(param.imag) 
  146.          + exp(-param.imag)) * cos(param.real);
  147.    rtrn.imag = 0.5 * (exp(-param.imag) 
  148.          - exp(param.imag)) * sin(param.real);
  149.    if(errno)
  150.       err_hndlr("CCOS()");
  151.    return rtrn;
  152. }
  153.  
  154. struct cmplx_nmbr ctan(struct cmplx_nmbr param)
  155.  
  156. {
  157.    struct cmplx_nmbr numerator, denominator;
  158.    double texp = exp(-2 * param.imag);
  159.    errno = 0;
  160.    numerator.real = sin(2 * param.real) * texp;
  161.    numerator.imag = 1 - cos(2 * param.real) * texp;
  162.    denominator.real = cos(2 * param.real) * texp + 1;
  163.    denominator.imag = numerator.real;
  164.    rtrn = cmplxdiv(numerator, denominator);
  165.    if(errno)
  166.       err_hndlr("CTAN()");
  167.    return rtrn;
  168. }
  169.  
  170. struct cmplx_nmbr catn(struct cmplx_nmbr param)
  171.  
  172. {
  173.    errno = 0;
  174.    rtrn.real = 0.5 * (PI - atan2((1 + param.imag),
  175.          param.real) - atan2((1 - param.imag),
  176.          param.real));
  177.    rtrn.imag = 0.25 * log(((1 + param.imag) 
  178.          * (1 + param.imag) + (param.real
  179.          * param.real)) / ((1 - param.imag) * (1 -
  180.          param.imag) + (param.real * param.real)));
  181.    if(errno)
  182.       err_hndlr("CATN()");
  183.    return rtrn;
  184. }
  185.  
  186. struct cmplx_nmbr cexp(struct cmplx_nmbr param)
  187.  
  188. {
  189.    errno = 0;
  190.    rtrn.real = exp(param.real) * cos(param.imag);
  191.    rtrn.imag = exp(param.real) * sin(param.imag);
  192.    if(errno)
  193.       err_hndlr("CEXP()");
  194.    return rtrn;
  195. }
  196.  
  197. struct cmplx_nmbr cten2x(struct cmplx_nmbr param)
  198.  
  199. {
  200.    errno = 0;
  201.    rtrn.real = exp(param.real * LN10) + cos(param.imag
  202.          * LN10);
  203.    rtrn.imag = exp(param.real * LN10) + sin(param.imag
  204.          * LN10);
  205.    if(errno)
  206.       err_hndlr("CTEN2X()");
  207.    return rtrn;
  208. }
  209.  
  210. struct cmplx_nmbr cloge(struct cmplx_nmbr param)
  211.  
  212. {
  213.    errno = 0;
  214.    rtrn.real =  log(sqrt((param.real * param.real) +
  215.          (param.imag * param.imag)));
  216.    rtrn.imag = atan2(param.imag, param.real);
  217.    if(errno)
  218.       err_hndlr("CLOGE()");
  219.    return rtrn;
  220. }
  221.  
  222. struct cmplx_nmbr clog10(struct cmplx_nmbr param)
  223.  
  224. {
  225.    errno = 0;
  226.    rtrn.real = log(sqrt((param.real * param.real) +
  227.          (param.imag * param.imag))) / LN10;
  228.    rtrn.imag = atan2(param.imag, param.real) / LN10;
  229.    if(errno)
  230.       err_hndlr("CLOG10()");
  231.    return rtrn;
  232. }
  233.  
  234. struct cmplx_nmbr cmplxinv(struct cmplx_nmbr param)
  235.  
  236. {
  237.    struct cmplx_nmbr one;
  238.    errno = 0;
  239.    one.real = 1.0;
  240.    one.imag = 1e-100;
  241.    rtrn = cmplxdiv(one, param);
  242.    if(errno)
  243.       err_hndlr("CMPLXINV()");
  244.    return rtrn;
  245. }
  246.  
  247. struct cmplx_nmbr cmplxadd(struct cmplx_nmbr arg1,
  248.       struct cmplx_nmbr arg2)
  249.  
  250. {
  251.    errno = 0;
  252.    rtrn.real = arg1.real + arg2.real;
  253.    rtrn.imag = arg1.imag + arg2.imag;
  254.    if(errno)
  255.       err_hndlr("CMPLXADD()");
  256.    return rtrn;
  257. }
  258.  
  259. struct cmplx_nmbr cmplxsub(struct cmplx_nmbr arg1,
  260.       struct cmplx_nmbr arg2)
  261.  
  262. {
  263.    errno = 0;
  264.    rtrn.real = arg1.real - arg2.real;
  265.    rtrn.imag = arg1.imag - arg2.imag;
  266.    if(errno)
  267.       err_hndlr("CMPLXSUB()");
  268.    return rtrn;
  269. }
  270.  
  271. struct cmplx_nmbr cmplxmul(struct cmplx_nmbr arg1,
  272.       struct cmplx_nmbr arg2)
  273.  
  274. {
  275.    errno = 0;
  276.    rtrn.real = arg1.real * arg2.real - arg1.imag
  277.          * arg2.imag;
  278.    rtrn.imag = arg1.real * arg2.imag + arg2.real
  279.          * arg1.imag;
  280.    if(errno)
  281.       err_hndlr("CMPLXMUL()");
  282.    return rtrn;
  283. }
  284.  
  285. struct cmplx_nmbr cmplxdiv(struct cmplx_nmbr arg1,
  286.       struct cmplx_nmbr arg2)
  287.  
  288. {
  289.    double mag1, mag2, ang1, ang2;
  290.    errno = 0;
  291.    ang1 = atan2(arg1.imag, arg1.real);
  292.    ang2 = atan2(arg2.imag, arg2.real);
  293.    mag1 = arg1.imag / sin(ang1);
  294.    mag2 = arg2.imag / sin(ang2);
  295.    mag1 /= mag2;
  296.    ang1 -= ang2;
  297.    rtrn.real = mag1 * cos(ang1);
  298.    rtrn.imag = mag1 * sin(ang1);
  299.    if(errno)
  300.       err_hndlr("CMPLXDIV()");
  301.    return rtrn;
  302. }
  303.  
  304. void err_hndlr(char *func_name)
  305. {
  306.    if(errno == ERANGE)
  307.    {
  308.       fprintf(stderr,
  309.               "\n\n\n                      ");
  310.       fprintf(stderr,
  311.               "!!! RANGE ERROR IN %s FUNCTION !!!",
  312.             func_name);
  313.    }
  314.    else if(errno == EDOM)
  315.    {
  316.       fprintf(stderr,
  317.               "\n\n\n                       ");
  318.       fprintf(stderr,
  319.               "!!! DOMAIN ERROR IN %s FUNCTION !!!",
  320.             func_name);
  321.    }
  322.    else
  323.    {
  324.       fprintf(stderr,
  325.               "\n\n\n                       ");
  326.       fprintf(stderr,
  327.               "!!! NON-MATHEMATICAL ERROR IN ");
  328.       fprintf(stderr, " %s FUNCTION !!!", func_name);
  329.    }
  330.    exit(1);
  331. }
  332.  
  333.