CNLMath : Reference Material : Complex Data Types and Functions
Complex Data Types and Functions
Users can perform computations with complex arithmetic by using predefined data types. These types are available in two floating-point precisions:
1. f_complex z for single-precision complex values
2. 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.
Single-Precision Complex Operations and Functions
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 (z)
z = imsl_c_cos(z)
f_complex
f_complex
z = sin (z)
z = imsl_c_sin(z)
f_complex
f_complex
z = exp (z)
z = imsl_c_exp(z)
f_complex
f_complex
z = log (z)
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)
Double-Precision Complex Operations and Functions
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 (z)
z = imsl_z_cos(z)
d_complex
d_complex
z = sin (z)
z = imsl_z_sin(z)
d_complex
d_complex
z = exp (z)
z = imsl_z_exp(z)
d_complex
d_complex
z = log (z)
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)
Example
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);
}
Output
 
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