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 >
Wrap
Text File
|
1990-07-26
|
8KB
|
333 lines
Listing 4:
/***********************************************
** **
** Complex Function Library **
** **
** Maynard A. Wright, P. E. 4-16-90 **
** **
***********************************************/
/* This library must be linked with the program which
will call the functions defined herein. The call-
ing program must also #include file cmplx.h for
structure and function declarations. Multivalued
functions defined in this library will, in general,
return the solution with the smallest absolute
value. The source code for this library is stored
as cmplxlib.c.
stdlib.h is included because the variable errno is
declared in that header file in Microsoft C.
Range and domain errors are trapped by evaluating
errno. Error diagnostics are directed to stderr and
the program exits, returning the value 1 to the
calling environment. */
/* Preprocessor Directives */
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define LN10 2.3025851
#define PI 3.1415927
/* Declarations */
static struct cmplx_nmbr
{
double real;
double imag;
} arg, arg1, arg2, answer, rtrn;
/* Function Prototypes */
struct cmplx_nmbr csinh(struct cmplx_nmbr);
struct cmplx_nmbr ccosh(struct cmplx_nmbr);
struct cmplx_nmbr ctanh(struct cmplx_nmbr);
struct cmplx_nmbr catnh(struct cmplx_nmbr);
struct cmplx_nmbr csin(struct cmplx_nmbr);
struct cmplx_nmbr ccos(struct cmplx_nmbr);
struct cmplx_nmbr ctan(struct cmplx_nmbr);
struct cmplx_nmbr catn(struct cmplx_nmbr);
struct cmplx_nmbr cexp(struct cmplx_nmbr);
struct cmplx_nmbr cten2x(struct cmplx_nmbr);
struct cmplx_nmbr cloge(struct cmplx_nmbr);
struct cmplx_nmbr clog10(struct cmplx_nmbr);
struct cmplx_nmbr cmplxinv(struct cmplx_nmbr);
struct cmplx_nmbr cmplxadd(struct cmplx_nmbr,
struct cmplx_nmbr);
struct cmplx_nmbr cmplxsub(struct cmplx_nmbr,
struct cmplx_nmbr);
struct cmplx_nmbr cmplxmul(struct cmplx_nmbr,
struct cmplx_nmbr);
struct cmplx_nmbr cmplxdiv(struct cmplx_nmbr,
struct cmplx_nmbr);
void err_hndlr(char *name);
/* Complex Function Definitions */
struct cmplx_nmbr csinh(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = cos(param.imag) * sinh(param.real);
rtrn.imag = sin(param.imag) * cosh(param.real);
if(errno)
err_hndlr("CSINH()");
return rtrn;
}
struct cmplx_nmbr ccosh(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = cos(param.imag) * cosh(param.real);
rtrn.imag = sin(param.imag) * sinh(param.real);
if(errno)
err_hndlr("CCOSH()");
return rtrn;
}
struct cmplx_nmbr ctanh(struct cmplx_nmbr param)
{
double denom;
errno = 0;
denom = cosh(2 * param.real) + cos(2 * param.imag);
rtrn.real = sinh(2 * param.real) / denom;
rtrn.imag = sin(2 * param.imag) / denom;
if(errno)
err_hndlr("CTANH()");
return rtrn;
}
struct cmplx_nmbr catnh(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = 0.25 * log(((1. + param.real) * (1. +
param.real) + param.imag * param.imag) /
((1. - param.real) * (1. - param.real) +
param.imag * param.imag));
rtrn.imag = -0.5 * (PI - atan2((1. + param.real),
-param.imag) - atan2((1. - param.real),
-param.imag));
if(errno)
err_hndlr("CATNH()");
return rtrn;
}
struct cmplx_nmbr csin(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = 0.5 * (exp(param.imag)
+ exp(-param.imag)) * sin(param.real);
rtrn.imag = 0.5 * (exp(param.imag)
- exp(-param.imag)) * cos(param.real);
if(errno)
err_hndlr("CSIN()");
return rtrn;
}
struct cmplx_nmbr ccos(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = 0.5 * (exp(param.imag)
+ exp(-param.imag)) * cos(param.real);
rtrn.imag = 0.5 * (exp(-param.imag)
- exp(param.imag)) * sin(param.real);
if(errno)
err_hndlr("CCOS()");
return rtrn;
}
struct cmplx_nmbr ctan(struct cmplx_nmbr param)
{
struct cmplx_nmbr numerator, denominator;
double texp = exp(-2 * param.imag);
errno = 0;
numerator.real = sin(2 * param.real) * texp;
numerator.imag = 1 - cos(2 * param.real) * texp;
denominator.real = cos(2 * param.real) * texp + 1;
denominator.imag = numerator.real;
rtrn = cmplxdiv(numerator, denominator);
if(errno)
err_hndlr("CTAN()");
return rtrn;
}
struct cmplx_nmbr catn(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = 0.5 * (PI - atan2((1 + param.imag),
param.real) - atan2((1 - param.imag),
param.real));
rtrn.imag = 0.25 * log(((1 + param.imag)
* (1 + param.imag) + (param.real
* param.real)) / ((1 - param.imag) * (1 -
param.imag) + (param.real * param.real)));
if(errno)
err_hndlr("CATN()");
return rtrn;
}
struct cmplx_nmbr cexp(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = exp(param.real) * cos(param.imag);
rtrn.imag = exp(param.real) * sin(param.imag);
if(errno)
err_hndlr("CEXP()");
return rtrn;
}
struct cmplx_nmbr cten2x(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = exp(param.real * LN10) + cos(param.imag
* LN10);
rtrn.imag = exp(param.real * LN10) + sin(param.imag
* LN10);
if(errno)
err_hndlr("CTEN2X()");
return rtrn;
}
struct cmplx_nmbr cloge(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = log(sqrt((param.real * param.real) +
(param.imag * param.imag)));
rtrn.imag = atan2(param.imag, param.real);
if(errno)
err_hndlr("CLOGE()");
return rtrn;
}
struct cmplx_nmbr clog10(struct cmplx_nmbr param)
{
errno = 0;
rtrn.real = log(sqrt((param.real * param.real) +
(param.imag * param.imag))) / LN10;
rtrn.imag = atan2(param.imag, param.real) / LN10;
if(errno)
err_hndlr("CLOG10()");
return rtrn;
}
struct cmplx_nmbr cmplxinv(struct cmplx_nmbr param)
{
struct cmplx_nmbr one;
errno = 0;
one.real = 1.0;
one.imag = 1e-100;
rtrn = cmplxdiv(one, param);
if(errno)
err_hndlr("CMPLXINV()");
return rtrn;
}
struct cmplx_nmbr cmplxadd(struct cmplx_nmbr arg1,
struct cmplx_nmbr arg2)
{
errno = 0;
rtrn.real = arg1.real + arg2.real;
rtrn.imag = arg1.imag + arg2.imag;
if(errno)
err_hndlr("CMPLXADD()");
return rtrn;
}
struct cmplx_nmbr cmplxsub(struct cmplx_nmbr arg1,
struct cmplx_nmbr arg2)
{
errno = 0;
rtrn.real = arg1.real - arg2.real;
rtrn.imag = arg1.imag - arg2.imag;
if(errno)
err_hndlr("CMPLXSUB()");
return rtrn;
}
struct cmplx_nmbr cmplxmul(struct cmplx_nmbr arg1,
struct cmplx_nmbr arg2)
{
errno = 0;
rtrn.real = arg1.real * arg2.real - arg1.imag
* arg2.imag;
rtrn.imag = arg1.real * arg2.imag + arg2.real
* arg1.imag;
if(errno)
err_hndlr("CMPLXMUL()");
return rtrn;
}
struct cmplx_nmbr cmplxdiv(struct cmplx_nmbr arg1,
struct cmplx_nmbr arg2)
{
double mag1, mag2, ang1, ang2;
errno = 0;
ang1 = atan2(arg1.imag, arg1.real);
ang2 = atan2(arg2.imag, arg2.real);
mag1 = arg1.imag / sin(ang1);
mag2 = arg2.imag / sin(ang2);
mag1 /= mag2;
ang1 -= ang2;
rtrn.real = mag1 * cos(ang1);
rtrn.imag = mag1 * sin(ang1);
if(errno)
err_hndlr("CMPLXDIV()");
return rtrn;
}
void err_hndlr(char *func_name)
{
if(errno == ERANGE)
{
fprintf(stderr,
"\n\n\n ");
fprintf(stderr,
"!!! RANGE ERROR IN %s FUNCTION !!!",
func_name);
}
else if(errno == EDOM)
{
fprintf(stderr,
"\n\n\n ");
fprintf(stderr,
"!!! DOMAIN ERROR IN %s FUNCTION !!!",
func_name);
}
else
{
fprintf(stderr,
"\n\n\n ");
fprintf(stderr,
"!!! NON-MATHEMATICAL ERROR IN ");
fprintf(stderr, " %s FUNCTION !!!", func_name);
}
exit(1);
}