Users can perform computations with complex arithmetic by using predefined data types. These types are available in two floating-point precisions:
• f_complex z for single-precision complex values
• d_complex w for double-precision complex values
Each complex value is a C language structure that consists of a pair of real values, the real and imaginary part of the complex number. To access the real part of a single-precision complex number z, use the subexpression z.re. For the imaginary part, use the subexpression z.im. Use subexpressions w.re and w.im for the real and imaginary parts of a double-precision complex number w. The structure is declared within imsl.h as follows:
typedef
struct{
float
re;
float
im;
} f_complex;
Several standard operations and functions are available for users to perform calculations with complex numbers within their programs. The operations are provided for both single and double precision data types. Notice that even the ordinary arithmetic operations of “+”, “-”, “*”, and “/” must be performed using the appropriate functions.
A uniform prefix name is used as part of the names for the operations and functions. The prefix imsl_c_ is used for f_complex data. The prefix imsl_z_ is used with d_complex data.
|
Operation |
Function Name |
Function Result |
Function Argument(s) |
|
z = –x |
z = imsl_c_neg(x) |
f_complex |
f_complex |
|
z = x + y |
z = imsl_c_add(x,y) |
f_complex |
f_complex (both) |
|
z = x – y |
z = imsl_c_sub(x,y) |
f_complex |
f_complex (both) |
|
z = x * y |
z = imsl_c_mul(x,y) |
f_complex |
f_complex (both) |
|
z = x / y |
z = imsl_c_div(x,y) |
f_complex |
f_complex (both) |
|
x= =ya |
z = imsl_c_eq(x,y) |
Int |
f_complex (both) |
|
z = x Drop Precision |
z = imsl_cz_convert(x) |
f_complex |
d_complex |
a Result has the value 1 if x and y are valid numbers with real and imaginary parts identical; otherwise, result has the value 0.
|
Operation |
Function Name |
Function Result |
Function Argument(s) |
|
z = a + ib Ascend Data |
z = imsl_cf_convert(a,b) |
f_complex |
float (both) |
|
z = |
z = imsl_c_conjg(x) |
f_complex |
f_complex |
|
a = |z| |
a = imsl_c_abs(z) |
float |
f_complex |
|
a = arg (z) –π < a ≤ π |
a = imsl_c_arg(z) |
float |
f_complex |
|
z = |
z = imsl_c_sqrt(z) |
f_complex |
f_complex |
|
z = cos (x) |
z = imsl_c_cos(z) |
f_complex |
f_complex |
|
z = sin (x) |
z = imsl_c_sin(z) |
f_complex |
f_complex |
|
z = exp (x) |
z = imsl_c_exp(z) |
f_complex |
f_complex |
|
z = log (x) |
z = imsl_c_log(z) |
f_complex |
f_complex |
|
z = xa |
z = imsl_cf_power(x,a) |
f_complex |
f_complex, float |
|
z = xy |
z = imsl_cc_power(x,y) |
f_complex |
f_complex (both) |
|
c = ak |
c = imsl_fi_power(a,k) |
float |
float, int |
|
c = ab |
c = imsl_ff_power(a,b) |
float |
float (both) |
|
m = jk |
m = imsl_ii_power(j,k) |
Int |
int (both) |
|
Operation |
Function Name |
Function Result |
Function Argument(s) |
|
z = –x |
z = imsl_z_neg(x) |
d_complex |
d_complex |
|
z = x + y |
z = imsl_z_add(x,y) |
d_complex |
d_complex (both) |
|
z = x – y |
z = imsl_z_sub(x,y) |
d_complex |
d_complex (both) |
|
z = x * y |
z = imsl_z_mul(x,y) |
d_complex |
d_complex (both) |
|
z = x / y |
z = imsl_z_div(x,y) |
d_complex |
d_complex (both) |
|
x==yb |
z = imsl_z_eq(x,y) |
Int |
d_complex (both) |
|
z = x Drop Precision |
z = imsl_zc_convert(x) |
d_complex |
f_complex |
|
z = a + ib Ascend Data |
z = imsl_zd_convert(a,b) |
d_complex |
double (both) |
b Result has the value 1 if x and y are valid numbers with real and imaginary parts identical; otherwise, result has the value 0.
|
Operation |
Function Name |
Function Result |
Function Argument(s) |
|
z = x |
z = imsl_z_conjg(x) |
d_complex |
d_complex |
|
a = |z| |
a = imsl_z_abs(z) |
Double |
d_complex |
|
a = arg (z) –π < a ≤ π |
a = imsl_z_arg(z) |
Double |
d_complex |
|
z = |
z = imsl_z_sqrt(z) |
d_complex |
d_complex |
|
z = cos (x) |
z = imsl_z_cos(z) |
d_complex |
d_complex |
|
z = sin (x) |
z = imsl_z_sin(z) |
d_complex |
d_complex |
|
z = exp (x) |
z = imsl_z_exp(z) |
d_complex |
d_complex |
|
z = log (x) |
z = imsl_z_log(z) |
d_complex |
d_complex |
|
z = xa |
z = imsl_zd_power(x,a) |
d_complex |
d_complex, double |
|
z = xy |
z = imsl_zz_power(x,y) |
d_complex |
d_complex (both) |
|
c = ak |
c = imsl_di_power(a,k) |
Double |
double, int |
|
c = ab |
c = imsl_dd_power(a,b) |
Double |
double (both) |
|
m = jk |
m = imsl_ii_power(j,k) |
Int |
int (both) |
The following sample code computes and prints several quantities associated with complex numbers. Note that the quantity

has a rounding error associated with it. Also the quotient z = (1 + 2i) / (3 + 4i) has a rounding error. The result is acceptable in both cases because the relative errors |w – (2 + 2i)|/ |w| and |z * (3 + 4i) – (1 + 2i)|/ |(1 + 2i)| are approximately the size of machine precision.
#include
<imsl.h>
main()
{
f_complex x
=
{1,2};
f_complex y
=
{3,4};
f_complex z;
f_complex w;
int isame;
float eps
=
imsl_f_machine(4);
/*
Echo inputs x and y */
printf("Data: x =
(%g, %g)\n y = (%g,
%g)\n\n",
x.re,
x.im, y.re,
y.im);
/*
Add inputs */
z =
imsl_c_add(x,y);
printf("Sum: z = x + y =
(%g, %g)\n\n", z.re,
z.im);
/*
Compute square root of y */
w =
imsl_c_sqrt(y);
printf("Square Root: w = sqrt(y) =
(%g, %g)\n", w.re,
w.im);
/*
Check results */
z =
imsl_c_mul(w,w);
printf("Check: w*w
= (%g, %g)\n", z.re, z.im);
isame =
imsl_c_eq(y,z);
printf(" y
== w*w = %d\n", isame);
z =
imsl_c_sub(z,y);
printf("Difference: w*w -
y = (%g, %g) = (%g, %g) *
eps\n\n",
z.re,
z.im, z.re/eps,
z.im/eps);
/*
Divide inputs */
z =
imsl_c_div(x,y);
printf("Quotient: z
= x/y = (%g, %g)\n", z.re,
z.im);
/*
Check results */
w = imsl_c_sub(x, imsl_c_mul(z,
y));
printf("Check: w
= x - z*y = (%g, %g) = (%g, %g) *
eps\n",
w.re,
w.im, w.re/eps, w.im/eps);
}
Data: x = (1,
2)
y = (3,
4)
Sum: z = x + y = (4, 6)
Square Root: w =
sqrt(y) = (2, 1)
Check: w*w = (3,
4)
y
== w*w = 0
Difference: w*w - y = (-2.38419e-07, 4.76837e-07)
= (-2, 4) * eps
Quotient: z = x/y = (0.44,
0.08)
Check: w = x - z*y =
(5.96046e-08, 0) = (0.5, 0) * eps
|
Visual Numerics, Inc. PHONE: 713.784.3131 FAX:713.781.9260 |