Q:

Solve Polynomial equation of 6th order with Python efficiently

I want to Solve Polynomial equation of 6th order with Python.
I've tried the "basic" version:
avgIrms = 19.61
c_val = (0.000002324*avgIrms**6) - (0.0001527*avgIrms**5) + (0.003961843*avgIrms**4) - (0.052211292*avgIrms**3) + (0.379269091*avgIrms**2) -(0.404399274*avgIrms) + 0.000682896
print(c_val)

After that I've used the numpy with the following code:
import numpy as np
avgIrms = 19.61
ppar = [0.000002324, -0.0001527, 0.003961843, -0.052211292, 0.379269091, -0.404399274, 0.000682896]
p = np.poly1d(ppar)
print(p(avgIrms))   

In the both ways the raspberry tooks more than five seconds to process... It's to much! Any help to solve polynomial equations efficiently? (less than one second...)
Thanks in advance,
Daniel

A:

First, what you want is to evaluate a polynomial for a given x, not to solve it. Second, I still don't see how do you get your speed up..
Find here a couple of timmings:
>>> import numpy as np
>>> x = 19.61
>>> pr = [0.000002324, -0.0001527, 0.003961843, -0.052211292, 0.379269091, -0.404399274, 0.000682896]
>>> p = pr[::-1] # reverse the order

Hardcoded solution:
>>> %timeit p[0] + x * p[1] + p[2] * x**2 + p[3] * x**3 + p[4] * x**4 + p[5] * x**5 + p[6] * x**6
809 ns

Loopy solution:
>>> %%timeit
    val = 0
    for i in range(len(p)):
        val += p[i] * x**i
1.24 µs

Functional programming solution:
>>> %timeit reduce(lambda acc, i: acc + p[i] * x**i, range(len(p)))
1.61 µs

Using numpy's polyval:
>>> %timeit np.polyval(pr, x)
6.12 µs

Using numpy's poly1d
>>> %%timeit
    c = np.poly1d(pr)
    c(x)
9.46 µs

So, clearly numpy is slower, as for a such a small array it adds some overhead in the Python <-> C communication, but still, it is of the order of 6-9 µs, I'm using a desktop computer, but I would be pretty impressed if a Raspberry Pi would really take 5 seconds to do that operation. Are you sure you did the timings properly?
Any way, either the hardcoded or the loopy solution seem faster than the functional programming one (the equivalent to the one that you defined as horner in your comment).

