Integral of a Polynomial in Python
Question:
How would we write a function in python that returns the definite integral of a polynomial between two points (X_1
and X_2
)?
The function takes 3 arguments:
- a list
A
of polynomial coefficients (i.e. for polynomial f(x)=5x^4−2x+1
, this list becomes A=[5,0,0,−2,1]
)
- a real number
X_1
- a real number
X_2
We are given the formula for the definite integral of a polynomial such as
My attempt at this function is below, however the output returns 0.2
def take_integral(A, X_1, X_2):
integral = 0
for i in range(len(A)):
integral = A*(X_2**(i+1) - X_1**(i+1))/(i+1)
return integral
print(take_integral([1, 2, 1], 0, 3))
The expected result from the function should be:
print(take_integral([1, 2, 1], 0, 3))
21.0
print(take_integral([5, 0, 0, -2, 1], 0, 1))
1.0
Answers:
In your function you ignore X_1 and X_2 and set them both to 0. Hence the result is always 0
A few points here:
-
There’s a serious problem with multiplying A
with the whole bunch of stuff afterwards. A
is a list, where the rest gives a float. The computer doesn’t necessarily know what to do with that. Imagine if I told you to multiply a set of crayons by 4. You can guess what I want, but ultimately, it doesn’t really make sense. You want to multiply the contents of the list instead of the list itself.
-
With your given formula for computing a definite integral of a polynomial, I’m pretty sure there should be a sum where you add all the terms together. That’s what the definition of a polynomial is, right? Currently, you’re computing each term and erasing the previous term. So, you need to add them up instead.
-
Your attempt also kind of…"flips" the exponents. Since the list of coefficients A
is sorted in descending order of power (A[0]
being the coefficient of the highest power), doing X_1**(i+1)
when i=0
in your sample input where A=[1,2,1]
would be multiplying the highest power with the lowest exponent instead of the desired 3
. So you want to iterate through the list from left to right, but your i
when you’re raising your X
‘s needs to decrease. Thankfully, len(A)
comes in handy for solving that.
- If you do
len(A)-i
, you’ll get exactly the i+1
according to the formula. This is true since len(A)
will give the one more than the highest power in your polynomial, and i
starts from 0
to one less than the length of A
, and as a result gives you i+1
as per the formula.
Here’s the code that will give you the right answers:
def take_integral(A, X_1, X_2):
integral = 0
for i in range(len(A)):
integral += A[i]*(X_2**((len(A))-i) - X_1**((len(A))-i))/((len(A))-i)
return integral
print(take_integral([1, 2, 1], 0, 3))
21
print(take_integral([5, 0, 0, -2, 1], 0, 1))
1
This can also be done more efficiently using numpy libraries.
import numpy as np
def take_integral(A, X_1, X_2):
powers = np.flipud(np.array(range(len(A)))) + 1 # Create an array
A = A/ powers # adjust coefficients
return np.sum(A * (X_2 ** powers - X_1 ** powers))
How would we write a function in python that returns the definite integral of a polynomial between two points (X_1
and X_2
)?
The function takes 3 arguments:
- a list
A
of polynomial coefficients (i.e. for polynomialf(x)=5x^4−2x+1
, this list becomesA=[5,0,0,−2,1]
) - a real number
X_1
- a real number
X_2
We are given the formula for the definite integral of a polynomial such as
My attempt at this function is below, however the output returns 0.2
def take_integral(A, X_1, X_2):
integral = 0
for i in range(len(A)):
integral = A*(X_2**(i+1) - X_1**(i+1))/(i+1)
return integral
print(take_integral([1, 2, 1], 0, 3))
The expected result from the function should be:
print(take_integral([1, 2, 1], 0, 3))
21.0
print(take_integral([5, 0, 0, -2, 1], 0, 1))
1.0
In your function you ignore X_1 and X_2 and set them both to 0. Hence the result is always 0
A few points here:
-
There’s a serious problem with multiplying
A
with the whole bunch of stuff afterwards.A
is a list, where the rest gives a float. The computer doesn’t necessarily know what to do with that. Imagine if I told you to multiply a set of crayons by 4. You can guess what I want, but ultimately, it doesn’t really make sense. You want to multiply the contents of the list instead of the list itself. -
With your given formula for computing a definite integral of a polynomial, I’m pretty sure there should be a sum where you add all the terms together. That’s what the definition of a polynomial is, right? Currently, you’re computing each term and erasing the previous term. So, you need to add them up instead.
-
Your attempt also kind of…"flips" the exponents. Since the list of coefficients
A
is sorted in descending order of power (A[0]
being the coefficient of the highest power), doingX_1**(i+1)
wheni=0
in your sample input whereA=[1,2,1]
would be multiplying the highest power with the lowest exponent instead of the desired3
. So you want to iterate through the list from left to right, but youri
when you’re raising yourX
‘s needs to decrease. Thankfully,len(A)
comes in handy for solving that.- If you do
len(A)-i
, you’ll get exactly thei+1
according to the formula. This is true sincelen(A)
will give the one more than the highest power in your polynomial, andi
starts from0
to one less than the length ofA
, and as a result gives youi+1
as per the formula.
- If you do
Here’s the code that will give you the right answers:
def take_integral(A, X_1, X_2):
integral = 0
for i in range(len(A)):
integral += A[i]*(X_2**((len(A))-i) - X_1**((len(A))-i))/((len(A))-i)
return integral
print(take_integral([1, 2, 1], 0, 3))
21
print(take_integral([5, 0, 0, -2, 1], 0, 1))
1
This can also be done more efficiently using numpy libraries.
import numpy as np
def take_integral(A, X_1, X_2):
powers = np.flipud(np.array(range(len(A)))) + 1 # Create an array
A = A/ powers # adjust coefficients
return np.sum(A * (X_2 ** powers - X_1 ** powers))