Weilory
Weilory

Reputation: 3111

numpy roots negative exponential function

I have read numpy.roots, which works out common algebraic function's y axis intersections.

which

y = ax^n + bx^{n - 1} + cx^{n - 2} ...

and exponentials are always natural number.

so by passing in

[1, 2, 3]

I am basically working out

y = x^2 + 2x + 3

but I need to bring in negative exponentials, such as

y = x^2 + 2x + 3 - x^{-1}

I wonder if I can construct a dict, for the instance above

{2: 1, 1: 2, 0: 3, -1: 1}

which keys are exponentials and values are coefficients, and work out the roots.


any suggestions will be appreciated.

Upvotes: 0

Views: 541

Answers (1)

Max Pierini
Max Pierini

Reputation: 2249

If you got a "polynomial" with negative exponents, it is not really a polynomial but a fractional function, so to find the roots you can simply find the roots of the numerator polynomial.

In a function

enter image description here

you can factor out the last term

enter image description here

which is equal to

enter image description here

So we can say

enter image description here

The function g(x) is a polynomial of n+m degree and finding the roots of g(x) you'll get the roots of f(x) because the denominator cannot be zero (x=0 is outside the domain of f(x), when it's zero you get a singularity, in this case a division by zero which is impossible).

EDIT

We can graphically verify. For example, let's take a function with these coefficients

import numpy as np
coeffs = [1, 6, -6, -64, -27, 90]
roots = np.roots(coeffs)
roots

array([-5.,  3., -3., -2.,  1.])

As you can see we got 5 real roots.

Let's now define a polynomial with the given coefficients and a fractional function

import matplotlib.pyplot as plt

def print_func(func, func_name):
    fig, ax = plt.subplots(figsize=(12, .5))
    ax.set_xticks([])
    ax.set_yticks([])
    ax.axis('off')
    ax.text(0, .5, 
            f"{func_name}\n"
            fr"${func}$",
            fontsize=15,
            va='center'
           )
    plt.show()

def polynom(x, coeffs):
    res = 0
    terms = []
    for t, c in enumerate(coeffs[::-1]):
        res += c * x**t
        terms.append(f"{c:+} x^{{{t}}}")
    func = "".join(terms[::-1])
    print_func(func, "polynomial")
    return res

def fract(x, coeffs, min_exp):
    res = 0
    terms = []
    for t, c in enumerate(coeffs[::-1]):
        e = t + min_exp
        res += c * x**e
        terms.append(f"{c:+} x^{{{e}}}")
    func = "".join(terms[::-1])
    print_func(func, "fractional")
    return res

x = np.linspace(-6, 4, 100)

So this is the polynomial

y1 = polynom(x, coeffs)

enter image description here

and this is the fractional function

y2 = fract(x, coeffs, -2)

enter image description here

Let's plot them both and the found roots

plt.plot(x, y1, label='polynomial')
plt.plot(x, y2, label='fractional')
plt.axhline(0, color='k', ls='--', lw=1)
plt.plot(roots, np.repeat(0, roots.size), 'o', label='roots')
plt.ylim(-100, 100)
plt.legend()
plt.show()

enter image description here

You see they've got the same roots.

Please note that, if you had a fractional like

y2 = fract(x, coeffs, -3)

enter image description here

i.e where the denominator has an odd exponent, you could think there is a root in x=0 too, simply looking at the plot

enter image description here

but that's not a root, that's a singularity, a vertical asymptote to ±∞. With an even exponent denominator the singularity will go to +∞.

Upvotes: 3

Related Questions