Реализация ряда Тейлора на Python

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Ряд Тейлора для функции представляет собой бесконечную сумму членов, которая использует информацию о производных этой функции для создания полинома, аппроксимирующего эту функцию. Более точные аппроксимации можно вывести, взяв производные более высокого порядка и используя полиномы более высокой степени. В интернете уже есть много статей (и видео на YouTube) о рядах Тейлора, которые помогут вам сформировать хорошее понимание процесса построения бесконечного ряда с упоминанием того, как члены более высоких порядков дают вам более близкие аппроксимации базовой функции (при условии, что ряд сходится). Тем не менее, таких, которые наглядно демонстрируют, почему это может быть так важно для нас, не очень много.

Когда я впервые столкнулся с рядами Тейлора в рамках своего бакалаврского курса, особого впечатления они на меня не произвели — я отнесся к ним как к вполне себе рядовой теме. Но недавно, готовясь к GRE Mathematics Subject Test, я наконец проникся и решил реализовать их на Python. Эта реализация требует от нас только определить аппроксимируемую функцию, все остальное обрабатывается численно. В этой статье мы рассмотрим реализацию ряда Тейлора на Python и обсудим некоторые потенциальные варианты его использования.

Реализация

Членам ряда Тейлора функции f(x) требуются производные последовательно более высоких порядков f^(n)(x) — для определения коэффициентов полинома. Следовательно, ряд Тейлора может быть определен для f(x), только если она бесконечно дифференцируема. Члены ряда определяются выражением

Где а является центром ряда Тейлора (прим. ред.: этот термин используется англоязычным сообществом, а русскоязычное в основном оперирует окрестностью точки а). Если центр ряда равен 0, т. е. a=0, то ряд называют рядом Маклорена.

Чтобы программно сформировать ряд Тейлора для функции, все, что от нас требуется, это вычислить коэффициенты

для достаточного количества членов. Опять же напомню, что чем больше членов ряда Тейлора мы будем использовать, тем точнее будет аппроксимация. К счастью, в пакете Python scipy уже есть встроенная функция для вычисления производной функции в заданной точке. Именно ее мы и будем использовать для определения коэффициентов искомого полинома.

from scipy.misc import derivative
import math

class TaylorSeries():
    def __init__(self, function, order, center=0):
        self.center = center
        self.f = function 
        self.order = order
        self.d_pts = order*2
        self.coefficients = []

        # количество точек (order) для scipy.misc.derivative
        if self.d_pts % 2 == 0: # must be odd and greater than derivative order
            self.d_pts += 1

        self.__find_coefficients()

    def __find_coefficients(self):
        for i in range(0, self.order+1):
            self.coefficients.append(round(derivative(self.f, self.center, n=i, order=self.d_pts)/math.factorial(i), 5))

Приведенная выше логика начинается с определения класса для хранения информации о ряде Тейлора. Конструктор принимает указатель на функцию (function) для которой мы формируем ряд Тейлора, порядок (order) ряда Тейлора (то есть количество членов) и центр (center) ряда, который по умолчанию соответствует ряду Маклорена (т.е. равен нулю). Некоторые переменные, которые используются в функции scipy.misc.derivative, вычисляются на лету из уже предоставленных нами данных. А затем сразу же вызывается приватный метод __find_coefficients(…) для определения значений коэффициентов для каждого члена нашего ряда Тейлора. Это делается программно, путем определения производных для каждого члена ряда Тейлора и деления на соответствующий факториал, как было показано выше.

По сути, это практически все, что нам нужно сделать для получения ряда Тейлора в Python. Остальные взаимодействия с рядом Тейлора будут просто использовать эти коэффициенты. Прежде чем углубиться в них, давайте проверим, что этот код работает, определив коэффициенты некоторых полиномов (рядов Тейлора для конкретных функций). Чтобы можно было проверить результаты, мы определим две функции для просмотра коэффициентов и результирующего уравнения, представляющего ряд Тейлора.

def print_equation(self):
    eqn_string = ""
    for i in range(self.order + 1):
        if self.coefficients[i] != 0:
            eqn_string += str(self.coefficients[i]) + ("(x-{})^{}".format(self.center, i) if i > 0 else "") + " + "
    eqn_string = eqn_string[:-3] if eqn_string.endswith(" + ") else eqn_string
    print(eqn_string)

def print_coefficients(self):
    print(self.coefficients)

def get_coefficients(self):
    """
        Возвращает коэффициенты ряда Тейлора
    """
    return self.coefficients

Первая функция, print_equation(…), выводит ряд Тейлора как уравнение с центром в центре ряда. print_coefficients(…) просто выведет список с коэффициентами, а get_coefficients(…) вернет его.

Приведенный ниже код используется для нахождения коэффициентов ряда Тейлора, представляющего функцию f(x):

from TaylorSeries import TaylorSeries

def f(x):
    return 2 + x**3 + x**7 + x**2

if __name__ == '__main__':
    terms = 15
    center = 0
    precision = 3

    ts = TaylorSeries(f, terms, center)
    ts.print_coefficients()
    ts.print_equation()

Выполнение этой логики сформирует список размером в 15 элементов, который содержит коэффициенты ряда Тейлора, а также выведет полиномиальное уравнение. В этом случае функция “аппроксимируется” рядом Тейлора из 15 параметров

Поскольку это полином, ряд Тейлора должен точно представлять его, имея первый коэффициент (константу) 2.0, коэффициенты 1.0 для индексов 2, 3 и 7 и коэффициенты 0.0 во всех остальных порядков. Т.е. мы получим многочлен, показанный выше. И действительно, запуск скрипта дает нам следующий вывод:

Вывод скрипта Python, приведенного выше, показывает, что коэффициенты определены правильно, и что мы получили исходный многочлен в качестве ряда Тейлора.
Вывод скрипта Python, приведенного выше, показывает, что коэффициенты определены правильно, и что мы получили исходный многочлен в качестве ряда Тейлора.

Изменение функции f(x) на различные полиномы в приведенном выше Python-скрипте дало те же результаты — каждый полином точно представлен рядом Тейлора. Это не очень увлекательно, но это хороший способ убедиться, что логика работает должным образом. Более интересные функции, благодаря аппроксимации которых ряд Тейлора получил широкую известность, например, sin(x), cos(x), e^x и т. д., также дают правильные результаты в этой реализации. Далее, в приведенных ниже применениях, мы будем использовать именно эти функции.

Применения ряда Тейлора

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

Бесполезное

Дифференцирование

Ряд Тейлора функции можно использовать для аппроксимации ее производной в конкретной точке. Члены ряда Тейлора можно дифференцировать по отдельности, тогда они примут форму

которая представляет собой просто производную степенной функции, умноженного на коэффициент ряда Тейлора. Обратите внимание, что в коде это отбросит члены, не представленные в ряде Тейлора, поскольку их коэффициенты будут равны 0.

В нашей Python-логике эти вычисления будут выполняются с помощью функции, приведенной ниже:

def approximate_derivative(self, x):
    """
        Приблизительно вычисляет производную функции f(x) по ее ряду Тейлора.
        Бесполезно, так как нам нужна производная самой функции, чтобы построить ряд Тейлора.
    """
    value = 0
    for i in range(1, len(self.coefficients)): # skip the first value (constant) as the derivative is 0
        value += self.coefficients[i] * i * ((x - self.center)**(i-1)) # differentiate each term: x^n => n*x^(n-1)
    return value

В этой функции аппроксимация производной функции находится путем перебора коэффициентов, вычисления значений производной, как описано выше, и их суммирования. Подстановка значений в эту функцию обеспечивает точную аппроксимацию производной базовой функции. Ниже приведены результаты для cos(x):

x

f(x)

Approx. f'(x)

0

1.0

0.0

pi/6

0.866

-0.5

pi/4

0.707

-0.707

pi/3

0.5

-0.866

pi/2

0.0

-1.0

pi

-1

-0.042

Выше приведены значения аппроксимированной функции cos(x) и ее производной (обратите внимание, что фактическая производная равна -sin(x)) в точках 0,

Источник: https://habr.com/ru/company/otus/blog/651659/


Интересные статьи

Интересные статьи

К старту курса о Fullstack-разработке на Python мы подготовили сокращённый перевод опроса StackOverflow среди почти 83 000 людей, без малого 70 % из них — профессиональные разработчики. Опрос проводил...
В данной статье разобран код на Qt, который позволяет создать панель инструментов с возможностью менять положение виджетов на экране в зависимости от соотношения размеров...
Привет, Хабр! Ваш интерес к новой книге "Секреты Python Pro" убедил нас, что рассказ о необычностях Python заслуживает продолжения. Сегодня предлагаем почитать небольшой тут...
Ace (Ajax.org Cloud9 Editor) — популярный редактор кода для веб-приложений. У него есть как плюсы, так и минусы. Одно из больших преимуществ библиотеки — возможность использования пользовательс...
Многие думают, что точки входа это такие инструкции в setup.py, которые позволяют сделать пакет доступным для запуска из командной строки. Это, в целом, верно, но возможности точек входа не огран...