Previous: 15.2.1 Complex Numbers and Vectors
Up: 15.2 Complex Numbers
Next: 15.2.3 Impedance of Electrical Circuits
Previous Page: 15.2.1 Complex Numbers and Vectors
Next Page: 15.2.3 Impedance of Electrical Circuits

15.2.2 Roots of Algebraic Equations

One such application where complex numbers occur is in finding roots of algebraic equations. A linear algebraic equation of the form: in one unknown variable, , can be easy to solve depending on the values of the coefficients, and . If and , the equation is homogeneous and has no unique solution; any value for will make the equation true. If but is non-zero, the equation has no solution; no value of will make it true. Otherwise, if is non-zero, the solution for is easily determined:

A quadratic equation is a polynomial of second degree in of the form: If is zero, the equation reduces to a linear equation that is easy to solve. If is non-zero, there are two solutions:

The form of the solutions depends on the discriminant: If the discriminant is positive, the square root is a real number and the roots, and are both real numbers. If the discriminant is zero, the two roots are real and equal. Otherwise, if the discriminant is negative, the square root is an imaginary number and the roots are complex numbers:

In fact, the two roots are complex conjugates: the real parts are the same, the imaginary parts are negatives of each other. Complex roots of polynomials with real coefficients always occur in complex conjugate pairs.

We will now implement a program that finds the roots of a quadratic equation, and then tests each root by evaluating the quadratic polynomial for that value of the variable. If the value is a root, the polynomial must evaluate to zero. When testing roots, we must be able to evaluate the polynomial for all possible values of roots, including complex values. For consistency in testing, we will represent all roots as complex numbers with real roots having a zero imaginary part. Therefore, we will need a function to force a real number into a complex number, as well as a function to make a complex number given its real and imaginary parts. These functions are shown in Figure 15.13, and are added to the file computil.c with their prototypes in computils.h.

Finally, since complex numbers are not a native data type in C, we will also need a function to print complex numbers in the accepted form. If the number is real, it must print only the real part. If the number is imaginary, it must print only times the imaginary part. Otherwise, it must print a complex number as or , depending on the sign of the imaginary part. The function is also shown in Figure 15.13.

With all of these utility functions completed, the program logic is now simple to implement. It reads in the coefficients , , of the quadratic equation and uses the function findroots() to find the roots of the quadratic. The function forces the roots to complex form and returns them indirectly. The arguments of findroots() are the coefficients of the quadratic, and pointers to the two roots. The program then uses the function eval_quad() to verify each root by evaluating the quadratic polynomial at that value. The arguments of eval_quad() are the coefficients of the quadratic, and the value at which the quadratic is to be evaluated. The code for the driver is shown in Figure 15.14.

For each set of coefficients, main() checks if is zero and is non-zero, in which case it prints that the equation is linear with root -c/b. Otherwise, if both and are zero, it prints an invalid equation message, and in either case continues to read the next set of coefficients. On the other hand, if is non-zero, the driver calls findroots() to find the roots as complex numbers and returns them by indirectly to z1 and z2. Each root is printed and verified using eval_quad(). The process continues until end of file.

We next implement the function findroots() shown in Figure 15.15. It computes the roots, forces them to complex numbers and returns the values through the pointer parameters.

Finally, we write eval_quad() to evaluate a quadratic polynomial at a given complex value of the unknown variable. Since the value of the unknown, is complex, we force all coefficients to complex numbers before using our utility functions addc() and multc(). To reduce the number of multiplications required to evaluate the polynomial we perform the expression

The function is shown in Figure 15.16

The complex variable, w, is initialized to zero and then used for the cumulative complex sum of the polynomial. As we saw in Chapter , due to errors in rounding and floating point number representation, our result may not be precisely zero. Therefore, eval_quad() checks that w.real and w.imag are sufficiently close to zero using the library function fabs() to verify the solution and print an appropriate message. A sample run of the program is shown below:



Previous: 15.2.1 Complex Numbers and Vectors
Up: 15.2 Complex Numbers
Next: 15.2.3 Impedance of Electrical Circuits
Previous Page: 15.2.1 Complex Numbers and Vectors
Next Page: 15.2.3 Impedance of Electrical Circuits

tep@wiliki.eng.hawaii.edu
Sat Sep 3 07:27:41 HST 1994