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
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: