Почему моя самодельная полиномиальная функция Тейлора не работает так же хорошо, как функция SciPy? - PullRequest
0 голосов
/ 09 мая 2019

В качестве упражнения я написал скрипт, который производит коэффициенты для полинома Тейлора степени n (здесь 8) о x0 (здесь 1) для функции f(x) (здесь sqrt (x) ^ sqrt(x)).

Я использовал цикл for, чтобы превратить это приближение в автономную функцию T(x).Затем я определил Ts(x), используя scipy.interpolate.approximate_taylor_polynomial.Я определил (не показано ниже), что оптимальное значение для параметра scale функции SciPy было около 0,3, проверяя значения в диапазоне от 0 до 1 (вы не можете перейти выше 1, поскольку функция не определена для отрицательного x).

Как я и ожидал, моя функция T(x) работает значительно хуже, чем Ts(x), как вы можете видеть на следующем графике от x = 0 до 3:

Graph of f, T, and Ts

Что делает SciPy, а я нет?

Интересно, может ли ответ быть связан с аргументом dx в функции SciPy derivative.Я остановился на е1-2, потому что более высокие значения порождали наны, а более низкие - явную бессмыслицу.Я также приблизил аргумент order: в сообщениях об ошибках говорилось, что это должно быть нечетное значение больше n, поэтому я выбрал 2*i+1 в цикле for.

Вот мой полный код.

# Imports
import numpy as np
from scipy.interpolate import approximate_taylor_polynomial
from scipy.misc import derivative
import matplotlib.pyplot as plt
import pandas as pd
%matplotlib inline


# Function I'm trying to approximate
def f(x):
    return np.sqrt(x) ** np.sqrt(x)


degree=8      # I am making an 8th degree polynomial
x0=1          # Centered about x=1

dvs=[f(x0)]   # This will hold the values of the nth degree derivative 
coef=[f(x0)]  # And this will hold the polynomial coefs (dvs divided by the corresponding factorials)

for i in range(1,degree+1):
    # I'm not entirely sure what the dx parameter does here, but 1e-2 produced the most accurate results.
    a = derivative(f,x0=x0,dx=1e-2,n=i,order=2*i+1)  # Compute the derivative
    dvs.append(a)                                    # Append to dvs
    coef.append(a/np.math.factorial(i))              # Compute the coefficient and append to coef

# Pretty pandas dataframe
out=pd.DataFrame({"degree":range(0,degree+1),"value":dvs,"coef":coef})


# Define Taylor polynomial using my coefs
def T(x):
    r = 0
    for i in range(0,degree+1):
        r = r + out['coef'][i] * ((x - x0) ** i)
    return r

# Use the scipy function for comparison. It is a poly1d object which can behave like a function.
# Not shown: I tried scale values on np.linspace(0,1,101) and 0.3 was about the best.
Ts = approximate_taylor_polynomial(f,x=x0,degree=8,scale=0.3)


# Test x values to display our functions
x = np.linspace(0,3,301)


fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
# Actual function
ax.plot(x,f(x),c="black",label="f(x)")
# My approximation
ax.plot(x,T(x),c="deepskyblue",label="T(x)")
# Scipy approximation
# Note that scipy doesn't account for the horizontal translation
ax.plot(x,Ts(x-x0),c="forestgreen",label="Ts(x) (scale 0.3)") 
ax.legend()

Выводит график, показанный выше.

Как я могу улучшить свое приближение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...