Полиномы#

Полиномы в NumPy могут быть создан, манипулировать, и даже обученный используя удобные классы из numpy.polynomial пакет, представленный в NumPy 1.4.

До NumPy 1.4, numpy.poly1d был классом выбора и он всё ещё доступен для поддержания обратной совместимости. Однако, более новый polynomial package более полный и его удобные классы предоставляют более последовательный, лучше работающий интерфейс для работы с полиномиальными выражениями. Поэтому numpy.polynomial рекомендуется для нового кодирования.

Примечание

Терминология

Термин модуль polynomial относится к старому API, определённому в numpy.lib.polynomial, который включает numpy.poly1d класс и полиномиальные функции с префиксом poly доступный из numpy пространство имен (например, numpy.polyadd, numpy.polyval, numpy.polyfit, и т.д.).

Термин пакет polynomial относится к новому API, определенному в numpy.polynomial, который включает удобные классы для различных видов полиномов (Polynomial, Chebyshev, и т.д.).

Переход от numpy.poly1d to numpy.polynomial#

Как отмечено выше, poly1d class и связанные функции, определенные в numpy.lib.polynomial, такие как numpy.polyfit и numpy.poly, считаются устаревшими и должны не использоваться в новом коде. Начиная с версии NumPy 1.4, numpy.polynomial пакет предпочтителен для работы с полиномами.

Краткий справочник#

Следующая таблица выделяет некоторые основные различия между устаревшим модулем polynomial и пакетом polynomial для общих задач. Polynomial класс импортирован для краткости:

from numpy.polynomial import Polynomial

Как…

Устаревшее (numpy.poly1d)

numpy.polynomial

Создать объект полинома из коэффициентов [1]

p = np.poly1d([1, 2, 3])

p = Polynomial([3, 2, 1])

Создать полиномиальный объект из корней

r = np.poly([-1, 1]) p = np.poly1d(r)

p = Polynomial.fromroots([-1, 1])

Подобрать полином степени deg к данным

np.polyfit(x, y, deg)

Polynomial.fit(x, y, deg)

Вычислить полином в точке [2]

p(2.0) или np.polyval([1, 2, 3], 2.0)

p(2.0) или polyval(2.0, p.coef) (используйте p.convert().coef после fit)

Руководство по переходу#

Существуют значительные различия между numpy.lib.polynomial и numpy.polynomial. Наиболее значительное различие — это порядок коэффициентов для полиномиальных выражений. Различные процедуры в numpy.polynomial все работают с рядами, коэффициенты которых идут от нулевой степени вверх, что является обратный порядок соглашения poly1d. Простой способ запомнить это — индексы соответствуют степени, т.е., coef[i] является коэффициентом члена степени i.

Хотя разница в соглашениях может сбивать с толку, преобразовать из устаревшего полиномиального API в новый несложно. Например, ниже показано, как преобразовать numpy.poly1d экземпляр, представляющий выражение \(x^{2} + 2x + 3\) в Polynomial экземпляр, представляющий то же выражение:

>>> import numpy as np
>>> p1d = np.poly1d([1, 2, 3])
>>> p = np.polynomial.Polynomial(p1d.coef[::-1])

В дополнение к coef атрибут, полиномы из пакета polynomial также имеют domain и window атрибуты. Эти атрибуты наиболее актуальны при подгонке полиномов к данным, хотя следует отметить, что полиномы с разными domain и window атрибуты не считаются равными и не могут смешиваться в арифметических операциях:

>>> p1 = np.polynomial.Polynomial([1, 2, 3])
>>> p1
Polynomial([1., 2., 3.], domain=[-1.,  1.], window=[-1.,  1.], symbol='x')
>>> p2 = np.polynomial.Polynomial([1, 2, 3], domain=[-2, 2])
>>> p1 == p2
False
>>> p1 + p2
Traceback (most recent call last):
    ...
TypeError: Domains differ

См. документацию для удобные классы для дополнительных деталей о domain и window атрибуты.

Еще одно важное различие между устаревшим модулем полиномов и пакетом polynomial заключается в аппроксимации полиномами. В старом модуле аппроксимация выполнялась через polyfit функция. В пакете polynomial, fit предпочтительнее использовать метод класса. Например, рассмотрим простую линейную подгонку к следующим данным:

In [1]: rng = np.random.default_rng()

In [2]: x = np.arange(10)

In [3]: y = np.arange(10) + rng.standard_normal(10)

С устаревшим модулем полиномов линейная аппроксимация (т.е. полином степени 1) может быть применена к этим данным с помощью polyfit:

In [4]: np.polyfit(x, y, deg=1)
Out[4]: array([0.87055444, 0.22350597])

С новым полиномиальным API, fit предпочтительнее использовать метод класса:

In [5]: p_fitted = np.polynomial.Polynomial.fit(x, y, deg=1)

In [6]: p_fitted
Out[6]: Polynomial([4.14100093, 3.91749496], domain=[0., 9.], window=[-1.,  1.], symbol='x')

Обратите внимание, что коэффициенты приведены в масштабированной области определенное линейным отображением между window и domain. convert можно использовать для получения коэффициентов в области не масштабированных данных.

In [7]: p_fitted.convert()
Out[7]: Polynomial([0.22350597, 0.87055444], domain=[-1.,  1.], window=[-1.,  1.], symbol='x')

Документация для polynomial пакет#

В дополнение к стандартным степенным полиномам, пакет polynomial предоставляет несколько дополнительных видов полиномов, включая полиномы Чебышева, Эрмита (два подтипа), Лагерра и Лежандра. Каждый из них имеет связанный удобный класс доступно из numpy.polynomial пространство имен, предоставляющее единый интерфейс для работы с полиномами независимо от их типа.

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

Документация для устаревших полиномов#