Ошибка в коэффициентах для полинома с использованием Numpy

Я использую класс numpy.polynomial.polynomial.Polynomial (библиотека Numpy), чтобы согласовать с методом fit() определенные данные для полиномиальной функции. Полученный многочлен в порядке, я могу построить его и подставить точки, чтобы получить значение «y», и я получаю правильные ответы. Проблема в том, что атрибут .coef класса Polynomial возвращает набор коэффициентов, которые каким-то образом нормализованы или изменены, и я не могу понять, как это сделать. Что я имею в виду? Код следующий:

x_vid = array([0.0, 50.0, 75.0, 100.0])
y_vid = array([0.0, 30.0, 55.0, 100.0])
pol = Polynomial.fit(x_vid, y_vid, 5) # The polynomial is OK!!
print  pol.coef

Атрибут .coef возвращает следующий массив:

30   38.16   17.93   9.98    2.06   1.85

Коэффициенты расположены в порядке возрастания, поэтому эти коэффициенты представляют следующую полиномиальную функцию:

30 + 38.16x + 17.93x^2 + 9.98x^3 + 2.06x^4 + 1.85x^5

Однако и здесь возникает проблема: если я заменю любое значение из моего диапазона значений [0-100] там, оно не вернет правильное значение, несмотря на это, если я это сделаю, например:

pol(0) → Я получу 0, что нормально, но сразу видно, что в написанном мною многочлене он не вернет 0 при x = 0.

Я думаю, что полиномиальная функция может быть нормализована или смещена. Здесь я могу столкнуться с математической проблемой, а не с программированием, но любая помощь действительно приветствуется, потому что мне нужно записать многочлен, и я не уверен в его правильной форме. Спасибо.

Дополнительная информация: http://docs.scipy.org/doc/numpy/reference/generated/numpy.polynomial.polynomial.Polynomial.html#numpy.polynomial.polynomial.Polynomial


person Ruips    schedule 05.09.2014    source источник
comment
Вы пробовали использовать numpy.polyfit? Кроме того, у меня нет таких же коэффициентов, как у вас, у меня на два порядка больше.   -  person darthbith    schedule 05.09.2014
comment
спасибо @darthbith, эти два метода должны быть очень похожи, в любом случае многочлен хорошо подходит, проблема заключается в коэффициентах для записи полиномиальной функции. Я исправил два порядка величины, которые я разделил на 100, по разным причинам в то время.   -  person Ruips    schedule 05.09.2014
comment
Я обнаружил, что коэффициенты, возвращаемые polyfit, были разумными, а точка пересечения по оси Y соответствовала значению polyval(pol, 0). Я понятия не имею, какие коэффициенты возвращаются из метода Polynomial.fit().   -  person darthbith    schedule 05.09.2014


Ответы (2)


Коэффициенты полинома предназначены для масштабированных полиномов и полиномов смещения для повышения числовой стабильности. Вы можете либо преобразовать в «нормальный» многочлен, либо использовать ряд напрямую, если вы замените off + scl*x на x, где off и scl возвращаются pol.mapparms. Чтобы преобразовать в стандартную форму (не рекомендуется), выполните pol.convert(domain=[-1, 1]).

person Charles Harris    schedule 07.09.2014
comment
Точно! Большое спасибо, Чарльз Харрис - person Ruips; 08.09.2014

Руипы.

В вашем примере есть три проблемы:

  1. Вы подбираете полином пятого порядка только с четырьмя точками данных. Это случай недоопределенности, и он, вероятно, приведет к ранжированию. Однако это случайность, а не основная часть вашей проблемы.

  2. Вы ожидаете, что pol(0) будет работать как numpy.polyval, но это не так. Я вообще-то не уверен, что он делает. Класс предоставляет __call__, который заставляет pol(0) работать, но, насколько я могу судить, документации для вызываемого объекта нет (см. Polynomial docs). numpy.polynomial.polynomial содержит собственную версию polyval. Я протестирую его np.polyval и самодельную версию test_polyval вместе.

  3. Наиболее важно то, что коэффициенты порядка Polynomial класса отличаются от numpy.polyfit и numpy.polyval. В Polynomial, как вы описали, коэффициент наивысшего порядка стоит последним в списке / массиве. Однако в функциях numpy коэффициент наивысшего порядка идет первым (см. polyval docs).

В приведенном ниже фрагменте кода показано, как оценить полином, представленный вашим объектом Polynomial, при произвольном наборе значений x, а также показано, что для получения такого же поведения из numpy.polyval вы должны изменить порядок коэффициентов с помощью coef[::-1] . Я мог бы эквивалентным образом использовать numpy.fliplr, чтобы изменить порядок коэффициентов.

import numpy as np
from numpy.polynomial.polynomial import Polynomial,polyval
from numpy import array
import sys


x_vid = array([0.0, 50.0, 75.0, 100.0])
y_vid = array([0.0, 30.0, 55.0, 100.0])
pol = Polynomial.fit(x_vid, y_vid, 5) # The polynomial is OK!!

# I've written this, which should do what numpy.polynomial.polynomial.polyval 
# does, as a sanity check:
def test_polyval(polynomialInstance,xArray):
    # check that xArray is a numpy.ndarray, using ndarray.shape
    try:
        y = np.zeros(xArray.shape)
    except Exception as e:
        sys.exit('polyval error: %s'%e)

    # manually sum the polynomial terms on xArray
    for exp,c in enumerate(polynomialInstance.coef):
        y = y + c*x**exp

    return y

# Define some random x values for testing, in the range of points used
# for fitting:
x = np.random.rand(100)*100

# Compute, using our own polyval function, then Polynomial.polyval,
# and finally using numpy.polyval, making sure to reverse the
# coefficient order for the last:
y_test_polyval = test_polyval(pol,x)
y_Polynomial_polyval = polyval(x,pol.coef)
y_numpy_polyval = np.polyval(pol.coef[::-1],x)

# Make sure the two results are within machine epsilon:
if np.allclose(y_test_polyval,y_numpy_polyval) and \
        np.allclose(y_test_polyval,y_Polynomial_polyval):
    print 'Hurray!'
person rjonnal    schedule 05.09.2014
comment
Я должен был также сказать, что я тестировал равенство двух реализаций polyval во многих других интервалах (меньших и больших, чем [0,100]), и это работает и в других местах. Я думаю, что есть разница между классом Polynomial и _3 _ / _ 4_ с точки зрения подгонки, поскольку первый позволяет указать диапазоны, в которых вычисляются остаточные ошибки. - person rjonnal; 06.09.2014
comment
Кроме того, я нашел Polynomial.polyval. Это было прямо у меня под носом: [docs.scipy.org/doc/numpy/reference/generated/. - person rjonnal; 06.09.2014
comment
Спасибо за полный ответ, но Чарльз Харрис ответил именно на то, что я спрашивал. - person Ruips; 08.09.2014