How can I create functions that handle polynomials? - python

I have these problems about polynomials and I've spent about 4 hours on this, but I just can't get it. I'm new to Python and programming and I've tried working it out on paper, but I just don't know.
Write and test a Python function negate(p) that negates the polynomial represented by the list of its coeffeicients p and returns a new polynomial (represented as a list). In other words, write a function that makes the list of numbers negative.
Write a Python function eval_polynomial(p, x) that returns the value of P(x), where P is the polynomial represented by the list of its coefficients p. For example, eval_polynomial([1, 0, 3], 2) should return 1*2^2 + 0*2 + 3 = 7. Use a single while loop.
Write and test a function multiply_by_one_term(p, a, k) that multiplies a given polynomial p, represented by a list of coefficients, by ax^k and returns the product as a new list.
I would really appreciate it if someone could help me.

I'd recommend using numpy.poly1d and numpy.polymul, where the coefficients are a0*x2 + a1*x + a2.
For example, to represent 3*x**2 + 2*x + 1:
p1 = numpy.poly1d([3,2,1])
And with the resulting poly1d object you can operate using *, / and so on...:
print(p1*p1)
# 4 3 2
#9 x + 12 x + 10 x + 4 x + 1
If you want to build your own functions, assuming that p contains the coefficients in order: a0 + a1*x + a2*x**2 + ...:
def eval_polynomial(p,x):
return sum((a*x**i for i,a in enumerate(p)))
def multiply_by_one_term(p, a, k):
return [0]*k + [a*i for i in p]
Note
My evaluate function uses exponentials, which can be avoided with Horner's rule, as posted in another answer, which is available in Numpy's polyval function

Please use Horner's Method instead!
For polynomials, you should consider Horner's Method. Its main feature is that computing a polynomial of order N requires only N multiplies and N additions -- no exponentials:
def eval_polynomial(P, x):
'''
Compute polynomial P(x) where P is a vector of coefficients, highest
order coefficient at P[0]. Uses Horner's Method.
'''
result = 0
for coeff in P:
result = x * result + coeff
return result
>>> eval_poly([1, 0, 3], 2)
7
You can work through it by hand, or follow the link to see how it works.

Related

How to evaluate a polynomial at a specific x-value?

Use map to evaluate a given polynomial at a specific x-value.
Input:
p: A list of coefficients for increasing powers of x
x: The value of x to evaluate
Output: Number representing the value of the evaluated polynomial
Example: poly_eval([1, 2, 3], 2) = 1(2)^0 + 2(2)^1 + 3(2)^2 = 17
def poly_eval(coeff_list, x):
total = 0
for i, coeff in enumerate(coeff_list):
total += coeff * x**i
return total
or if you really want to use map :
def poly_eval(coeff_list, x):
n = len(coeff_list)
return sum(map(lambda coeff, x, y: coeff*x**y, coeff_list, [x]*n, range(n)))
This is actually an interesting question. Since the answer is relatively simple and the pen and paper solution is known by everybody the real thing is kind of overlooked.
As mentioned, normally most people would approach like how it's done by pen and paper. However there is a better way which is more suitable for coding purposes, known as the Ruffini Horner method. This is a perfect case for reducing.
Write your polynomial in an array. So y = x^3-7x+7 would be var y = [1,0,-7,7].
Then a simple function;
var calcP = (y,x) => y.reduce((p,c) => p*x+c);
That's it.

Computing Riemann-Liouville Integral using Sympy

New to calculus and not sure where this goes...
I'm trying to compute the Riemann-Liouville interpretation of the integral in Python using sympy. However the resulting integral when running my code between 0 and T contains T as a variable, which I do not want. What should I do to fix this?
Code:
def integral(f, order):
gamma_recip = 1/gamma(order)
T = sympy.Symbol('T')
r = sympy.Symbol('r')
eq = (T-r) ** order - 1
function_eq = eq * f(r)
integral = sympy.integrate(function_eq, (r, 0, T))
return integral
Equation:
Sample call as requested:
-0.333333333333333*T**3 + 0.0833333333333333*T**4.0
Function and order used:
def f(x):
return x**2
print(integral(f, 1.0))
Expected result:
r**3/3
Two issues:
you are using "T" as the integral limit so you will end up with that in the result; if you want "r" in the result, swap the use of T and r in your function
you didn't put parentheses around the order - 1 in your definition of eq; if you do you will (with your current code) get the expected T**3/3

Finding roots of a non linear expression when multiplied with a linear expression

Here is a simple polynomial equation:
b^2 + 2b + 1 = 0
I could easily solve this as:
import numpy as np
from scipy.optimize import fsolve
eq = lambda b : np.power(b,2) + 2*b + 1
fsolve(eq, np.linspace(0,1,2))
Similarly I could solve any equation, that has finite number of terms. But how do I solve an equation with infinite number of terms which is given as :
The above equation could be written as :
5 = (1 - l) * (5.5 + 4.0*l + 4*l^2 + 6*l^3 + 5*l^4 + 5*l^5 + 5*l^6 + 5*l^7 + 5*l^8 + 5*l^9 + 5*l^10 )
when n goes from 1 to 10. But I want to solve this for sufficiently large value of n such that LHS ~= RHS.
I know the values of LHS and G1 -> Ginf but cannot understand how could I compute the value of lambda here.
I tried looking at numpy polynomial functions but could not find a function that is relevant here.
The following glosses over the fact that I do not 100% understand the coefficient notation G_t:t+n (what kind of dependency is that supposed to indicate exactly?)
Obviously, the solution will depend on coefficients. If as your example suggests, the coefficients are all equal above some index n_0 then your r.h.s. expression is a telescoping sum and equal to G_t:1 + sum_1^n_0 [G_t:n - G_t:n+1] l^n`. Be sure to note that this sum is finite, so you know how to proceed from here.
One caveat: you must have |l| < 1 otherwise the series does not converge and the r.h.s. is undefined, although some kind of continuation argument may be possible.

Python program to multiply two polynomial where each term of the polynomial is represented as a pair of integers (coefficient, exponent)?

fuction takes two list(having tuples as values) as input
i got in my mind following algorithm to write code for this, but to write it properly.
-->firstly make required no. of dictionary to store coefficient of each power is multiplied with all coefficient of polynomial p2.
then all dictionary coefficient are added which having same power.
def multpoly(p1,p2):
dp1=dict(map(reversed, p1))
dp2=dict(map(reversed, p2))
kdp1=list(dp1.keys())
kdp2=list(dp2.keys())
rslt={}
if len(kdp1)>=len(kdp2):
kd1=kdp1
kd2=kdp2
elif len(kdp1)<len(kdp2):
kd1=kdp2
kd2=kdp1
for n in kd2:
for m in kd1:
rslt[n]={m:0}
if len(dp1)<=len(dp2):
rslt[n][m+n]=rslt[n][m+n] + dp1[n]*dp2[m]
elif len(dp1)>len(dp2):
rslt[n][m+n]=rslt[n][m+n] + dp2[n]*dp1[m]
return(rslt)
If I understand correctly, you want a function to multiply two polynomials and return the result. In the future, try and post a specific question. Here is code that will work for you:
def multiply_terms(term_1, term_2):
new_c = term_1[0] * term_2[0]
new_e = term_1[1] + term_2[1]
return (new_c, new_e)
def multpoly(p1, p2):
"""
#params p1,p2 are lists of tuples where each tuple represents a pair of term coefficient and exponent
"""
# multiply terms
result_poly = []
for term_1 in p1:
for term_2 in p2:
result_poly.append(multiply_terms(term_1, term_2))
# collect like terms
collected_terms = []
exps = [term[1] for term in result_poly]
for e in exps:
count = 0
for term in result_poly:
if term[1] == e:
count += term[0]
collected_terms.append((count, e))
return collected_terms
Note however, there are definitely much better ways to represent these polynomials such that the multiplication is faster and easier to code. Your idea with the dict is slightly better but still messy. You could use a list where the index represents the exponent and the value represents the coefficient. For ex. you could represent 2x^4 + 3x + 1 as [1, 3, 0, 0, 2].

Evaluating polynomials in modulo arithmetic

I need to repeatedly evaluate a polynomial of the form
f(x)=c(0)+c(1)*x+...+c(k-1)*x^(k-1) mod p
where k is an integer, p is a large prime number and c(0),...,c(p) are between 1 and p.
For my applications, k=10, p should be greater than 1000.
I would prefer to do this in Python and as fast as possible. I don't know enough about modulo arithmetic in Python to implement this efficiently (e.g. how to exploit that we can use Mersenne primes p=2^q-1 in which case about should use that multiplication is a register shift, avoid trouble by adding integers over different orders of magnitude,...).
Motivation: k-independent hashing, see https://en.wikipedia.org/wiki/K-independent_hashing. This seems to a very popular academic subject but I was not able to find any implementations for k>2.
In general, you can compute the value of a polynomial using the following construction:
def value(poly, x):
"""Evaluates a polynomial POLY for a given x.
The polynomial is expressed as a list of coefficients, with
the coefficient for x ** N at poly[N].
This means that x ** 2 + 2*x + 3 is expressed as [3, 2, 1].
"""
v = 0
# Bit messy, but we're basically generating the indexes of
# our polynomial coefficients from highest to lowest
for coeff in reverse(poly):
v = v * x + coeff
return v
To evaluate this modulo a value, we can simply change the inner loop to v = v * x + poly[ix] % p (and pass our modulus as the parameter p).
We can show that the example polynom (x^2 + 2x + 3) is computed correctly by unwinding the loop and see that what we have is (((1) * x + 2) * x + 3) (each parenthesis level is one iteration through the loop), this can be simplified to 1 * x * x + 2 * x + 3, which is clearly the expected polynomial.
By using this, we should never end up with an intermediate value larger than p * x.

Categories