X
6811

Finding the Nth Roots of a Real Number

This Help Article demonstrates how the FZ_ROOTS function can be used, and why it is preferable to using power notation, to find the Nth roots of a real number where N is a positive integer. The Help Article also provides a convenient wrapper function.

Discussion
Suppose IDL is being used to find a real root of a number. For example, examine the 5th roots of -1, which include (in complex form) (-1,0), (-0.309017, -0.951056), (-0.309017, 0.951057), (0.809017, -0.587786) and (0.809018, 0.587785). Using power notation:

        IDL> print, (-1)^(1./5)

IDL will return "-NaN" since it is unclear which of the five roots to return. One could argue that since IDL does not typically take a floating point value and return a complex number after an operation (unless it is expected as in the case of FFT), that IDL could assume the user expects a real result of -1. However this is still tricky since IDL doesn't actually "see" -1^(1/5). Instead, it "sees" -1^(0.2000000), and can not know to interpret this as simply (1/5).

The better method is to use the FZ_ROOTS function, which takes a polynomial over the real numbers and finds all of its roots (real and complex). Let's examine how this function can be used to find the Nth roots of a real number x, where N is a positive integer. Generally, this is the set of all complex numbers satisfying the equation

        y = x^(1/N)

which can be rewritten as the polynomial

        y^N - x = 0.

IDL's FZ_ROOTS routine requires the coefficient of each term in the polynomial, so the polynomial can be rewritten as

        1*y^N + 0*y^(N-1) + ... + 0*y - x = 0.

These coefficients can be placed into an (N+1)-element vector to get [1,0,0,...,0,x] which can then be passed to FZ_ROOTS to get back all the Nth roots of x.

So, to find the 5th roots of -1, the following polynomial equation will be used:

        y^5 - (-1) = 1*y^5 + 0*y^4 + 0*y^3 + 0*y^2 + 0*y + 1 = 0

to get the vector [1,0,0,0,0,1] to pass to FZ_ROOTS:

        IDL> print, fz_roots([1,0,0,0,0,1])

        (-1.00000, 0.000000) (-0.309017, -0.951056) (-0.309017, 0.951057)
    (0.809017, -0.587786) (0.809018, 0.587785)


Below is a convenient wrapper function that, given a real number x and an integer N, will construct the polynomial coefficient vector described above and then evaluate the Nth roots of x using FZ_ROOTS. The syntax for calling this function to print the Nth roots of x is:

        IDL> print, nth_roots(x, N)

Revisiting the example above, this gives:

        IDL> print, nth_roots(-1, 5)

        (-1.00000, 0.000000) (-0.309017, -0.951056) (-0.309017, 0.951057)
    (0.809017, -0.587786) (0.809018, 0.587785)