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