CuPy: NumPy & SciPy for GPU - A NumPy/SciPy-compatible array library for GPU-accelerated computing with Python, specifically built for CUDA 11.1
—
Comprehensive polynomial operations including fitting, evaluation, arithmetic, root finding, and advanced polynomial manipulation. CuPy provides both traditional polynomial functions and object-oriented polynomial classes for mathematical analysis, curve fitting, and signal processing applications.
Fundamental polynomial operations for construction, evaluation, and manipulation of polynomial expressions.
def poly(seq_of_zeros):
"""
Find polynomial coefficients with given roots.
Parameters:
- seq_of_zeros: array_like, sequence of polynomial roots
Returns:
- ndarray: Polynomial coefficients from highest to lowest degree
Notes:
- Returns coefficients of monic polynomial
- Opposite of roots() function
"""
def roots(p):
"""
Return roots of polynomial with given coefficients.
Parameters:
- p: array_like, polynomial coefficients from highest to lowest degree
Returns:
- ndarray: Roots of polynomial
Notes:
- Uses eigenvalue method for numerical stability
- Complex roots returned for higher-degree polynomials
"""
def polyval(p, x):
"""
Evaluate polynomial at specific values.
Parameters:
- p: array_like, polynomial coefficients from highest to lowest degree
- x: array_like, values at which to evaluate polynomial
Returns:
- ndarray: Polynomial values at x
Notes:
- Uses Horner's method for numerical stability
- Broadcasts over x values
"""
def polyder(p, m=1):
"""
Return derivative of polynomial.
Parameters:
- p: array_like, polynomial coefficients
- m: int, order of derivative (default: 1)
Returns:
- ndarray: Coefficients of derivative polynomial
"""
def polyint(p, m=1, k=None):
"""
Return antiderivative (integral) of polynomial.
Parameters:
- p: array_like, polynomial coefficients
- m: int, order of integration (default: 1)
- k: array_like, integration constants
Returns:
- ndarray: Coefficients of integrated polynomial
"""Mathematical operations between polynomials including addition, subtraction, multiplication, and division.
def polyadd(a1, a2):
"""
Find sum of two polynomials.
Parameters:
- a1: array_like, coefficients of first polynomial
- a2: array_like, coefficients of second polynomial
Returns:
- ndarray: Coefficients of sum polynomial
Notes:
- Handles polynomials of different degrees
- Removes leading zeros from result
"""
def polysub(a1, a2):
"""
Difference (subtraction) of two polynomials.
Parameters:
- a1: array_like, coefficients of first polynomial
- a2: array_like, coefficients of second polynomial
Returns:
- ndarray: Coefficients of difference polynomial
"""
def polymul(a1, a2):
"""
Find product of two polynomials.
Parameters:
- a1: array_like, coefficients of first polynomial
- a2: array_like, coefficients of second polynomial
Returns:
- ndarray: Coefficients of product polynomial
Notes:
- Degree of product is sum of input degrees
- Uses convolution for efficient computation
"""
def polydiv(u, v):
"""
Return polynomial division quotient and remainder.
Parameters:
- u: array_like, dividend polynomial coefficients
- v: array_like, divisor polynomial coefficients
Returns:
- tuple: (quotient, remainder) polynomial coefficients
Notes:
- Performs polynomial long division
- Remainder degree is less than divisor degree
"""Polynomial fitting functions for data analysis, trend analysis, and function approximation from experimental data.
def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
"""
Least squares polynomial fit.
Parameters:
- x: array_like, x-coordinates of data points
- y: array_like, y-coordinates of data points
- deg: int, degree of fitting polynomial
- rcond: float, relative condition number cutoff
- full: bool, return additional fit information
- w: array_like, weights for data points
- cov: bool or str, return covariance matrix
Returns:
- ndarray or tuple: Polynomial coefficients, optionally with fit info
Notes:
- Uses least squares method for optimal fit
- Higher degrees may lead to overfitting
- Returns coefficients from highest to lowest degree
"""
def polyvander(x, deg):
"""
Generate Vandermonde matrix.
Parameters:
- x: array_like, points at which to evaluate polynomials
- deg: int, degree of polynomial basis
Returns:
- ndarray: Vandermonde matrix of shape (..., deg + 1)
Notes:
- Each column is x**i for i from 0 to deg
- Used internally by polyfit
- Useful for custom fitting algorithms
"""Advanced polynomial class providing convenient methods for polynomial manipulation and analysis.
class poly1d:
"""
One-dimensional polynomial class.
Parameters:
- c_or_r: array_like, polynomial coefficients or roots
- r: bool, if True, c_or_r contains roots instead of coefficients
- variable: str, variable name for string representation
"""
def __init__(self, c_or_r, r=False, variable=None): ...
@property
def coeffs(self):
"""Polynomial coefficients from highest to lowest degree"""
@property
def order(self):
"""Order (degree) of polynomial"""
@property
def roots(self):
"""Roots of polynomial"""
def __call__(self, val):
"""Evaluate polynomial at given values"""
def __add__(self, other):
"""Add polynomials or polynomial and scalar"""
def __sub__(self, other):
"""Subtract polynomials or polynomial and scalar"""
def __mul__(self, other):
"""Multiply polynomials or polynomial and scalar"""
def __truediv__(self, other):
"""Divide polynomial by scalar"""
def __pow__(self, val):
"""Raise polynomial to integer power"""
def deriv(self, m=1):
"""
Return mth derivative of polynomial.
Parameters:
- m: int, order of derivative
Returns:
- poly1d: Derivative polynomial
"""
def integ(self, m=1, k=0):
"""
Return antiderivative of polynomial.
Parameters:
- m: int, order of integration
- k: scalar or array, integration constant(s)
Returns:
- poly1d: Integrated polynomial
"""Specialized polynomial classes for different mathematical domains and applications.
# Chebyshev Polynomials (cupy.polynomial.chebyshev)
class Chebyshev:
"""Chebyshev polynomial series"""
def __init__(self, coef, domain=None, window=None): ...
def __call__(self, arg): ...
def degree(self): ...
def roots(self): ...
def convert(self, domain=None, kind=None, window=None): ...
def chebval(x, c):
"""Evaluate Chebyshev series at points x"""
def chebfit(x, y, deg, rcond=None, full=False, w=None):
"""Least squares fit of Chebyshev polynomial to data"""
def chebroots(c):
"""Compute roots of Chebyshev polynomial"""
def chebder(c, m=1, scl=1, axis=0):
"""Differentiate Chebyshev polynomial"""
def chebint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
"""Integrate Chebyshev polynomial"""
# Legendre Polynomials (cupy.polynomial.legendre)
class Legendre:
"""Legendre polynomial series"""
def __init__(self, coef, domain=None, window=None): ...
def legval(x, c):
"""Evaluate Legendre series at points x"""
def legfit(x, y, deg, rcond=None, full=False, w=None):
"""Least squares fit of Legendre polynomial to data"""
def legroots(c):
"""Compute roots of Legendre polynomial"""
# Hermite Polynomials (cupy.polynomial.hermite)
class Hermite:
"""Hermite polynomial series"""
def __init__(self, coef, domain=None, window=None): ...
def hermval(x, c):
"""Evaluate Hermite series at points x"""
def hermfit(x, y, deg, rcond=None, full=False, w=None):
"""Least squares fit of Hermite polynomial to data"""
# Laguerre Polynomials (cupy.polynomial.laguerre)
class Laguerre:
"""Laguerre polynomial series"""
def __init__(self, coef, domain=None, window=None): ...
def lagval(x, c):
"""Evaluate Laguerre series at points x"""
def lagfit(x, y, deg, rcond=None, full=False, w=None):
"""Least squares fit of Laguerre polynomial to data"""import cupy as cp
# Create polynomial from roots
roots = cp.array([1, -2, 3]) # Roots at x = 1, -2, 3
coeffs = cp.poly(roots)
print(f"Polynomial coefficients: {coeffs}")
# Find roots from coefficients
original_roots = cp.roots(coeffs)
print(f"Recovered roots: {original_roots}")
# Evaluate polynomial at specific points
x_vals = cp.linspace(-5, 5, 100)
y_vals = cp.polyval(coeffs, x_vals)
# Polynomial derivatives and integrals
first_deriv = cp.polyder(coeffs, 1)
second_deriv = cp.polyder(coeffs, 2)
integral = cp.polyint(coeffs)
print(f"First derivative coefficients: {first_deriv}")
print(f"Integral coefficients: {integral}")import cupy as cp
# Define two polynomials: p1(x) = x^2 + 2x + 1, p2(x) = x - 1
p1 = cp.array([1, 2, 1]) # x^2 + 2x + 1
p2 = cp.array([1, -1]) # x - 1
# Polynomial arithmetic
sum_poly = cp.polyadd(p1, p2) # Addition
diff_poly = cp.polysub(p1, p2) # Subtraction
prod_poly = cp.polymul(p1, p2) # Multiplication
quot_poly, rem_poly = cp.polydiv(p1, p2) # Division
print(f"Sum: {sum_poly}")
print(f"Product: {prod_poly}")
print(f"Quotient: {quot_poly}, Remainder: {rem_poly}")
# Verify division: p1 = p2 * quotient + remainder
verification = cp.polyadd(cp.polymul(p2, quot_poly), rem_poly)
print(f"Division verification: {cp.allclose(p1, verification)}")import cupy as cp
# Generate noisy data from known polynomial
true_coeffs = cp.array([0.5, -2, 1, 3]) # 0.5x^3 - 2x^2 + x + 3
x_data = cp.linspace(-2, 2, 50)
y_true = cp.polyval(true_coeffs, x_data)
noise = 0.1 * cp.random.randn(len(x_data))
y_data = y_true + noise
# Fit polynomial of various degrees
degrees = [2, 3, 4, 5]
fits = {}
for deg in degrees:
coeffs = cp.polyfit(x_data, y_data, deg)
y_fit = cp.polyval(coeffs, x_data)
mse = cp.mean((y_data - y_fit)**2)
fits[deg] = {'coeffs': coeffs, 'mse': mse}
# Find best fit
best_deg = min(fits.keys(), key=lambda k: fits[k]['mse'])
print(f"Best degree: {best_deg}, MSE: {fits[best_deg]['mse']:.6f}")
print(f"True coefficients: {true_coeffs}")
print(f"Fitted coefficients: {fits[best_deg]['coeffs']}")
# Get fit statistics
coeffs, residuals, rank, s = cp.polyfit(x_data, y_data, 3, full=True)
print(f"Residuals: {residuals}, Rank: {rank}")import cupy as cp
# Create polynomial objects
p1 = cp.poly1d([1, -2, 1]) # x^2 - 2x + 1 = (x-1)^2
p2 = cp.poly1d([1, -1]) # x - 1
print(f"p1: {p1}")
print(f"p1 order: {p1.order}")
print(f"p1 roots: {p1.roots}")
# Polynomial evaluation
x_vals = cp.array([0, 1, 2, 3])
print(f"p1({x_vals}) = {p1(x_vals)}")
# Polynomial arithmetic with objects
p_sum = p1 + p2
p_prod = p1 * p2
p_deriv = p1.deriv()
p_integ = p1.integ()
print(f"Sum: {p_sum}")
print(f"Product: {p_prod}")
print(f"Derivative: {p_deriv}")
print(f"Integral: {p_integ}")
# Create polynomial from roots
roots = cp.array([1, 2, -1])
p_from_roots = cp.poly1d(roots, True) # r=True indicates roots
print(f"Polynomial from roots {roots}: {p_from_roots}")import cupy as cp
from cupy.polynomial import Chebyshev, Legendre
# Chebyshev polynomial approximation
x_data = cp.linspace(-1, 1, 100)
y_data = cp.sin(cp.pi * x_data) # Approximate sine function
# Fit with Chebyshev polynomials
cheb_coeffs = cp.polynomial.chebyshev.chebfit(x_data, y_data, 10)
cheb_approx = cp.polynomial.chebyshev.chebval(x_data, cheb_coeffs)
# Create Chebyshev polynomial object
cheb_poly = Chebyshev(cheb_coeffs)
print(f"Chebyshev approximation error: {cp.max(cp.abs(y_data - cheb_approx)):.6f}")
# Legendre polynomial approximation
leg_coeffs = cp.polynomial.legendre.legfit(x_data, y_data, 10)
leg_approx = cp.polynomial.legendre.legval(x_data, leg_coeffs)
leg_poly = Legendre(leg_coeffs)
print(f"Legendre approximation error: {cp.max(cp.abs(y_data - leg_approx)):.6f}")
# Compare approximation quality
cheb_error = cp.mean((y_data - cheb_approx)**2)
leg_error = cp.mean((y_data - leg_approx)**2)
print(f"Chebyshev MSE: {cheb_error:.8f}")
print(f"Legendre MSE: {leg_error:.8f}")import cupy as cp
# Polynomial detrending of signal
t = cp.linspace(0, 10, 1000)
signal = cp.sin(2 * cp.pi * t) + 0.1 * t**2 + 0.02 * t**3 # Signal with polynomial trend
noise = 0.1 * cp.random.randn(len(t))
noisy_signal = signal + noise
# Fit and remove polynomial trend
trend_degree = 3
trend_coeffs = cp.polyfit(t, noisy_signal, trend_degree)
trend = cp.polyval(trend_coeffs, t)
detrended = noisy_signal - trend
print(f"Original signal std: {cp.std(noisy_signal):.4f}")
print(f"Detrended signal std: {cp.std(detrended):.4f}")
# Polynomial interpolation
sparse_indices = cp.arange(0, len(t), 50) # Every 50th point
sparse_t = t[sparse_indices]
sparse_signal = noisy_signal[sparse_indices]
# Fit high-degree polynomial for interpolation
interp_coeffs = cp.polyfit(sparse_t, sparse_signal, 15)
interpolated = cp.polyval(interp_coeffs, t)
interp_error = cp.mean((noisy_signal - interpolated)**2)
print(f"Interpolation MSE: {interp_error:.6f}")poly1d class provides convenient operator overloading for polynomial arithmeticw parameterInstall with Tessl CLI
npx tessl i tessl/pypi-cupy-cuda111