Интеграл многочлена в Python

#python #polynomials #polynomial-math #calculus

#python #многочлены #многочлен-математика #исчисление

Вопрос:

Как бы мы написали функцию на python, которая возвращает определенный интеграл от многочлена между двумя точками ( X_1 и X_2 )?

Функция принимает 3 аргумента:

  • список A коэффициентов полинома (т. Е. Для полинома f(x)=5x^4−2x 1 этот список становится A=[5,0,0,−2,1] )
  • действительное число X_1
  • действительное число X_2

Нам дана формула для определенного интеграла многочлена, такого как Нам дана формула для определенного интеграла многочлена, такого как

Моя попытка выполнить эту функцию приведена ниже, однако вывод возвращает 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))
  

Ожидаемый результат от функции должен быть:

 
    print(take_integral([1, 2, 1], 0, 3))
    21.0
    print(take_integral([5, 0, 0, -2, 1], 0, 1))
    1.0
  

Ответ №1:

Здесь несколько моментов:

  • Существует серьезная проблема с последующим умножением A на целую кучу вещей. A это список, в котором остальные значения имеют значение с плавающей запятой. Компьютер не обязательно знает, что с этим делать. Представьте, если бы я сказал вам умножить набор карандашей на 4. Вы можете догадаться, чего я хочу, но, в конечном счете, это действительно не имеет смысла. Вы хотите умножить содержимое списка вместо самого списка.

  • С вашей приведенной формулой для вычисления определенного интеграла от многочлена я почти уверен, что должна быть сумма, в которую вы складываете все члены вместе. Это и есть определение многочлена, верно? В настоящее время вы вычисляете каждый член и удаляете предыдущий член. Итак, вам нужно вместо этого сложить их.

  • Ваша попытка также как бы … «переворачивает» показатели. Поскольку список коэффициентов A сортируется в порядке убывания степени ( A[0] являясь коэффициентом наибольшей степени), выполнение X_1**(i 1) when i=0 в вашем примере ввода where A=[1,2,1] будет умножать наивысшую степень на наименьший показатель степени вместо желаемого 3 . Итак, вы хотите выполнить итерацию по списку слева направо, но ваш i , когда вы повышаете свой X , должен уменьшаться. К счастью, len(A) пригодится для решения этой проблемы.

    • Если вы это сделаете len(A)-i , вы получите точно в i 1 соответствии с формулой. Это верно, поскольку len(A) даст единицу больше, чем наивысшая степень в вашем многочлене, и i начинается с 0 единицы меньше длины A , и в результате дает вам i 1 в соответствии с формулой.

Вот код, который даст вам правильные ответы:

 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
  

Комментарии:

1. вау, спасибо за подробный ответ! это многое проясняет.

2. Нет проблем! Рад, что смог помочь.

Ответ №2:

В вашей функции вы игнорируете X_1 и X_2 и устанавливаете для них обоих значение 0. Следовательно, результат всегда равен 0

Комментарии:

1. спасибо за это. Я убрал X_1 = 0 и X_2 = 0 , и теперь функция выводит 0.2 для всего?

Ответ №3:

Это также можно сделать более эффективно, используя библиотеки numpy.

 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))