or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-operations.mdcuda-integration.mdcustom-kernels.mdfft.mdindex.mdio-operations.mdjit-compilation.mdlinear-algebra.mdmathematical-functions.mdperformance-profiling.mdpolynomial-operations.mdrandom.mdscipy-extensions.md

polynomial-operations.mddocs/

0

# Polynomial Operations

1

2

CuPy provides comprehensive polynomial operations through the `cupy.polynomial` module and legacy polynomial functions, enabling mathematical computation with polynomials including arithmetic, evaluation, fitting, root finding, and advanced polynomial manipulations optimized for GPU acceleration.

3

4

## Capabilities

5

6

### Legacy Polynomial Functions

7

8

Legacy polynomial functions providing basic polynomial operations and manipulations.

9

10

```python { .api }

11

class poly1d:

12

"""

13

One-dimensional polynomial class.

14

15

A convenience class for dealing with polynomials, providing

16

methods for polynomial arithmetic, evaluation, and analysis.

17

"""

18

def __init__(self, c_or_r, r=False, variable=None):

19

"""

20

Parameters:

21

c_or_r: array_like - Polynomial coefficients or roots

22

r: bool, optional - If True, c_or_r contains roots instead of coefficients

23

variable: str, optional - Variable name for string representation

24

"""

25

26

def __call__(self, val):

27

"""Evaluate polynomial at given values."""

28

29

def __add__(self, other):

30

"""Add polynomials."""

31

32

def __sub__(self, other):

33

"""Subtract polynomials."""

34

35

def __mul__(self, other):

36

"""Multiply polynomials."""

37

38

def __div__(self, other):

39

"""Divide polynomials."""

40

41

def __pow__(self, val):

42

"""Raise polynomial to a power."""

43

44

def deriv(self, m=1):

45

"""Return derivative of polynomial."""

46

47

def integ(self, m=1, k=None):

48

"""Return integral of polynomial."""

49

50

@property

51

def coeffs(self):

52

"""Polynomial coefficients."""

53

54

@property

55

def order(self):

56

"""Order (degree) of polynomial."""

57

58

@property

59

def roots(self):

60

"""Roots of polynomial."""

61

62

def poly(seq_of_zeros):

63

"""

64

Find the coefficients of a polynomial with the given sequence of roots.

65

66

Parameters:

67

seq_of_zeros: array_like - Sequence of polynomial roots

68

69

Returns:

70

ndarray: Polynomial coefficients

71

"""

72

73

def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):

74

"""

75

Least squares polynomial fit.

76

77

Parameters:

78

x: array_like - x-coordinates of data points

79

y: array_like - y-coordinates of data points

80

deg: int - Degree of fitting polynomial

81

rcond: float, optional - Relative condition number for fit

82

full: bool, optional - Switch determining nature of return value

83

w: array_like, optional - Weights to apply to y-coordinates

84

cov: bool or str, optional - Return covariance matrix

85

86

Returns:

87

ndarray or tuple: Polynomial coefficients (and additional info if requested)

88

"""

89

90

def polyval(p, x):

91

"""

92

Evaluate a polynomial at specific values.

93

94

Parameters:

95

p: array_like - Polynomial coefficients in decreasing powers

96

x: array_like - Values at which to evaluate polynomial

97

98

Returns:

99

ndarray: Polynomial evaluated at x

100

"""

101

102

def polyadd(a1, a2):

103

"""

104

Add two polynomials.

105

106

Parameters:

107

a1, a2: array_like - Polynomial coefficients

108

109

Returns:

110

ndarray: Coefficients of sum polynomial

111

"""

112

113

def polysub(a1, a2):

114

"""

115

Subtract second polynomial from first.

116

117

Parameters:

118

a1, a2: array_like - Polynomial coefficients

119

120

Returns:

121

ndarray: Coefficients of difference polynomial

122

"""

123

124

def polymul(a1, a2):

125

"""

126

Multiply two polynomials.

127

128

Parameters:

129

a1, a2: array_like - Polynomial coefficients

130

131

Returns:

132

ndarray: Coefficients of product polynomial

133

"""

134

135

def polydiv(u, v):

136

"""

137

Divide first polynomial by second.

138

139

Parameters:

140

u, v: array_like - Polynomial coefficients (dividend and divisor)

141

142

Returns:

143

tuple: (quotient, remainder) polynomial coefficients

144

"""

145

146

def roots(p):

147

"""

148

Return the roots of a polynomial with coefficients given in p.

149

150

Parameters:

151

p: array_like - Polynomial coefficients

152

153

Returns:

154

ndarray: Roots of the polynomial

155

"""

156

```

157

158

### Modern Polynomial Package

159

160

The `cupy.polynomial` package provides a comprehensive set of polynomial classes and functions.

161

162

```python { .api }

163

# Polynomial base classes and utilities

164

class Polynomial:

165

"""

166

Base class for all polynomial classes.

167

168

Provides common interface and functionality for polynomial

169

operations across different polynomial bases.

170

"""

171

def __init__(self, coef, domain=None, window=None): ...

172

173

def __call__(self, x): ...

174

def __add__(self, other): ...

175

def __sub__(self, other): ...

176

def __mul__(self, other): ...

177

def __truediv__(self, other): ...

178

def __pow__(self, other): ...

179

180

def deriv(self, m=1): ...

181

def integ(self, m=1, k=[]): ...

182

def roots(self): ...

183

184

@classmethod

185

def fit(cls, x, y, deg, domain=None, rcond=None, full=False, w=None, window=None): ...

186

187

@classmethod

188

def fromroots(cls, roots, domain=[], window=None): ...

189

190

# Power series polynomials (standard polynomials)

191

class Polynomial:

192

"""Power series polynomial in standard form."""

193

194

def polyval(x, c):

195

"""Evaluate polynomial at x."""

196

197

def polyval2d(x, y, c):

198

"""Evaluate 2-D polynomial at x, y."""

199

200

def polyval3d(x, y, z, c):

201

"""Evaluate 3-D polynomial at x, y, z."""

202

203

def polyvander(x, deg):

204

"""Generate Vandermonde matrix."""

205

206

def polyvander2d(x, y, deg):

207

"""Generate 2-D Vandermonde matrix."""

208

209

def polyvander3d(x, y, z, deg):

210

"""Generate 3-D Vandermonde matrix."""

211

212

def polyfit(x, y, deg, rcond=None, full=False, w=None):

213

"""Least squares fit of polynomial to data."""

214

215

def polycompanion(c):

216

"""Return companion matrix."""

217

218

def polyroots(c):

219

"""Return roots of polynomial."""

220

221

def polyfromroots(roots):

222

"""Generate polynomial from roots."""

223

224

# Chebyshev polynomials

225

class Chebyshev:

226

"""Chebyshev polynomial class."""

227

228

def chebval(x, c):

229

"""Evaluate Chebyshev series at x."""

230

231

def chebval2d(x, y, c):

232

"""Evaluate 2-D Chebyshev series."""

233

234

def chebval3d(x, y, z, c):

235

"""Evaluate 3-D Chebyshev series."""

236

237

def chebvander(x, deg):

238

"""Generate Chebyshev Vandermonde matrix."""

239

240

def chebfit(x, y, deg, rcond=None, full=False, w=None):

241

"""Fit Chebyshev series to data."""

242

243

def chebroots(c):

244

"""Return roots of Chebyshev polynomial."""

245

246

def chebfromroots(roots):

247

"""Generate Chebyshev polynomial from roots."""

248

249

# Legendre polynomials

250

class Legendre:

251

"""Legendre polynomial class."""

252

253

def legval(x, c):

254

"""Evaluate Legendre series at x."""

255

256

def legval2d(x, y, c):

257

"""Evaluate 2-D Legendre series."""

258

259

def legval3d(x, y, z, c):

260

"""Evaluate 3-D Legendre series."""

261

262

def legvander(x, deg):

263

"""Generate Legendre Vandermonde matrix."""

264

265

def legfit(x, y, deg, rcond=None, full=False, w=None):

266

"""Fit Legendre series to data."""

267

268

def legroots(c):

269

"""Return roots of Legendre polynomial."""

270

271

def legfromroots(roots):

272

"""Generate Legendre polynomial from roots."""

273

274

# Laguerre polynomials

275

class Laguerre:

276

"""Laguerre polynomial class."""

277

278

def lagval(x, c):

279

"""Evaluate Laguerre series at x."""

280

281

def lagval2d(x, y, c):

282

"""Evaluate 2-D Laguerre series."""

283

284

def lagval3d(x, y, z, c):

285

"""Evaluate 3-D Laguerre series."""

286

287

def lagvander(x, deg):

288

"""Generate Laguerre Vandermonde matrix."""

289

290

def lagfit(x, y, deg, rcond=None, full=False, w=None):

291

"""Fit Laguerre series to data."""

292

293

def lagroots(c):

294

"""Return roots of Laguerre polynomial."""

295

296

def lagfromroots(roots):

297

"""Generate Laguerre polynomial from roots."""

298

299

# Hermite polynomials (physicist's)

300

class HermiteE:

301

"""Hermite polynomial class (probabilist's)."""

302

303

def hermeval(x, c):

304

"""Evaluate Hermite series at x."""

305

306

def hermeval2d(x, y, c):

307

"""Evaluate 2-D Hermite series."""

308

309

def hermeval3d(x, y, z, c):

310

"""Evaluate 3-D Hermite series."""

311

312

def hermevander(x, deg):

313

"""Generate Hermite Vandermonde matrix."""

314

315

def hermefit(x, y, deg, rcond=None, full=False, w=None):

316

"""Fit Hermite series to data."""

317

318

def hermeroots(c):

319

"""Return roots of Hermite polynomial."""

320

321

def hermefromroots(roots):

322

"""Generate Hermite polynomial from roots."""

323

324

# Hermite polynomials (probabilist's)

325

class Hermite:

326

"""Hermite polynomial class (physicist's)."""

327

328

def hermval(x, c):

329

"""Evaluate Hermite series at x."""

330

331

def hermval2d(x, y, c):

332

"""Evaluate 2-D Hermite series."""

333

334

def hermval3d(x, y, z, c):

335

"""Evaluate 3-D Hermite series."""

336

337

def hermvander(x, deg):

338

"""Generate Hermite Vandermonde matrix."""

339

340

def hermfit(x, y, deg, rcond=None, full=False, w=None):

341

"""Fit Hermite series to data."""

342

343

def hermroots(c):

344

"""Return roots of Hermite polynomial."""

345

346

def hermfromroots(roots):

347

"""Generate Hermite polynomial from roots."""

348

```

349

350

## Usage Examples

351

352

### Basic Polynomial Operations

353

354

```python

355

import cupy as cp

356

import cupy.polynomial as poly

357

358

# Create and manipulate polynomials using poly1d

359

p1 = cp.poly1d([1, 2, 3]) # x^2 + 2x + 3

360

p2 = cp.poly1d([2, 1]) # 2x + 1

361

362

print("p1:", p1)

363

print("p2:", p2)

364

365

# Polynomial arithmetic

366

sum_poly = p1 + p2

367

diff_poly = p1 - p2

368

prod_poly = p1 * p2

369

print("Sum:", sum_poly)

370

print("Product:", prod_poly)

371

372

# Evaluate polynomials

373

x_values = cp.linspace(-5, 5, 100)

374

y1 = p1(x_values)

375

y2 = p2(x_values)

376

print("p1 evaluated at x=2:", p1(2))

377

print("p2 evaluated at x=2:", p2(2))

378

379

# Find roots

380

roots_p1 = p1.roots

381

print("Roots of p1:", roots_p1)

382

383

# Derivatives and integrals

384

p1_deriv = p1.deriv()

385

p1_integ = p1.integ()

386

print("Derivative of p1:", p1_deriv)

387

print("Integral of p1:", p1_integ)

388

```

389

390

### Polynomial Fitting

391

392

```python

393

# Generate noisy data

394

x_data = cp.linspace(0, 10, 100)

395

true_coeffs = [0.5, -2, 1, 3] # 0.5x^3 - 2x^2 + x + 3

396

y_true = cp.polyval(true_coeffs, x_data)

397

noise = cp.random.normal(0, 0.5, x_data.shape)

398

y_noisy = y_true + noise

399

400

# Fit polynomial of different degrees

401

degrees = [2, 3, 4, 5]

402

fitted_polys = {}

403

404

for degree in degrees:

405

coeffs = cp.polyfit(x_data, y_noisy, degree)

406

fitted_polys[degree] = coeffs

407

408

# Evaluate fitted polynomial

409

y_fitted = cp.polyval(coeffs, x_data)

410

mse = cp.mean((y_noisy - y_fitted) ** 2)

411

print(f"Degree {degree}: MSE = {mse:.4f}")

412

print(f" Coefficients: {coeffs}")

413

414

# Best fit analysis

415

best_degree = min(fitted_polys.keys(),

416

key=lambda d: cp.mean((y_noisy - cp.polyval(fitted_polys[d], x_data)) ** 2))

417

print(f"Best degree: {best_degree}")

418

419

# Weighted fitting for heteroscedastic noise

420

weights = 1.0 / (1.0 + cp.abs(x_data)) # Less weight for larger x

421

weighted_coeffs = cp.polyfit(x_data, y_noisy, 3, w=weights)

422

print("Weighted fit coefficients:", weighted_coeffs)

423

424

# Robust fitting with full output

425

coeffs, residuals, rank, singular_vals, rcond = cp.polyfit(

426

x_data, y_noisy, 3, full=True

427

)

428

print("Fit diagnostics:")

429

print(f" Residuals: {residuals}")

430

print(f" Rank: {rank}")

431

print(f" Condition number: {1/rcond:.2e}")

432

```

433

434

### Advanced Polynomial Types

435

436

```python

437

# Chebyshev polynomials for better numerical properties

438

x_cheb = cp.linspace(-1, 1, 100)

439

y_data = cp.exp(x_cheb) + 0.1 * cp.random.normal(size=x_cheb.shape)

440

441

# Fit using Chebyshev polynomials

442

cheb_coeffs = poly.chebyshev.chebfit(x_cheb, y_data, 5)

443

y_cheb_fitted = poly.chebyshev.chebval(x_cheb, cheb_coeffs)

444

445

print("Chebyshev coefficients:", cheb_coeffs)

446

print("Chebyshev fit MSE:", cp.mean((y_data - y_cheb_fitted) ** 2))

447

448

# Compare with standard polynomial fit

449

std_coeffs = cp.polyfit(x_cheb, y_data, 5)

450

y_std_fitted = cp.polyval(std_coeffs, x_cheb)

451

print("Standard polynomial MSE:", cp.mean((y_data - y_std_fitted) ** 2))

452

453

# Legendre polynomial approximation

454

leg_coeffs = poly.legendre.legfit(x_cheb, y_data, 5)

455

y_leg_fitted = poly.legendre.legval(x_cheb, leg_coeffs)

456

print("Legendre fit MSE:", cp.mean((y_data - y_leg_fitted) ** 2))

457

458

# Hermite polynomials for Gaussian-weighted data

459

x_herm = cp.linspace(-3, 3, 100)

460

gaussian_weight = cp.exp(-x_herm**2 / 2)

461

y_weighted = cp.sin(x_herm) * gaussian_weight + 0.05 * cp.random.normal(size=x_herm.shape)

462

463

herm_coeffs = poly.hermite_e.hermefit(x_herm, y_weighted, 6)

464

y_herm_fitted = poly.hermite_e.hermeval(x_herm, herm_coeffs)

465

print("Hermite fit MSE:", cp.mean((y_weighted - y_herm_fitted) ** 2))

466

```

467

468

### Multi-dimensional Polynomial Operations

469

470

```python

471

# 2D polynomial fitting

472

x2d = cp.random.rand(200) * 4 - 2

473

y2d = cp.random.rand(200) * 4 - 2

474

z_true = 2*x2d**2 + 3*y2d**2 - x2d*y2d + x2d + 2*y2d + 1

475

z_noisy = z_true + 0.1 * cp.random.normal(size=z_true.shape)

476

477

# Fit 2D polynomial surface

478

degree_2d = [2, 2] # Degree in x and y directions

479

coeffs_2d = poly.polynomial.polyfit2d(x2d, y2d, z_noisy, degree_2d)

480

481

# Evaluate on regular grid

482

x_grid = cp.linspace(-2, 2, 50)

483

y_grid = cp.linspace(-2, 2, 50)

484

X_grid, Y_grid = cp.meshgrid(x_grid, y_grid)

485

Z_fitted = poly.polynomial.polyval2d(X_grid, Y_grid, coeffs_2d)

486

487

print("2D polynomial coefficients shape:", coeffs_2d.shape)

488

print("Fitted surface shape:", Z_fitted.shape)

489

490

# 3D polynomial evaluation

491

x3d = cp.linspace(-1, 1, 20)

492

y3d = cp.linspace(-1, 1, 20)

493

z3d = cp.linspace(-1, 1, 20)

494

X3d, Y3d, Z3d = cp.meshgrid(x3d, y3d, z3d, indexing='ij')

495

496

# Simple 3D polynomial coefficients

497

coeffs_3d = cp.zeros((3, 3, 3))

498

coeffs_3d[1, 0, 0] = 1 # x term

499

coeffs_3d[0, 1, 0] = 1 # y term

500

coeffs_3d[0, 0, 1] = 1 # z term

501

coeffs_3d[2, 0, 0] = 0.5 # x^2 term

502

503

# Evaluate 3D polynomial

504

result_3d = poly.polynomial.polyval3d(X3d, Y3d, Z3d, coeffs_3d)

505

print("3D polynomial result shape:", result_3d.shape)

506

```

507

508

### Root Finding and Analysis

509

510

```python

511

# Complex polynomial root finding

512

# Polynomial: x^4 - 2x^3 + 3x^2 - 2x + 1

513

coeffs = [1, -2, 3, -2, 1]

514

roots = cp.roots(coeffs)

515

516

print("Polynomial coefficients:", coeffs)

517

print("Roots:", roots)

518

print("Root types:", [type(r).__name__ for r in roots])

519

520

# Verify roots by evaluation

521

for i, root in enumerate(roots):

522

value = cp.polyval(coeffs, root)

523

print(f"Root {i}: {root}, P(root) = {value}")

524

525

# Create polynomial from roots

526

reconstructed_coeffs = cp.poly(roots)

527

print("Reconstructed coefficients:", reconstructed_coeffs)

528

print("Original coefficients (normalized):", cp.array(coeffs) / coeffs[0])

529

530

# Companion matrix approach for root finding

531

companion = poly.polynomial.polycompanion([1, -2, 3, -2, 1])

532

eigenvals = cp.linalg.eigvals(companion)

533

print("Roots from companion matrix:", eigenvals)

534

535

# Analysis of polynomial behavior

536

def analyze_polynomial(coeffs, x_range=(-5, 5), n_points=1000):

537

"""Analyze polynomial behavior over a range."""

538

x = cp.linspace(x_range[0], x_range[1], n_points)

539

y = cp.polyval(coeffs, x)

540

541

# Find extrema (approximate)

542

dy = cp.gradient(y, x[1] - x[0])

543

extrema_indices = cp.where(cp.abs(dy) < cp.std(dy) * 0.1)[0]

544

545

analysis = {

546

'min_value': cp.min(y),

547

'max_value': cp.max(y),

548

'range': cp.max(y) - cp.min(y),

549

'approximate_extrema': len(extrema_indices),

550

'zeros_in_range': cp.sum(cp.abs(y) < cp.std(y) * 0.01)

551

}

552

553

return analysis

554

555

# Analyze different polynomials

556

test_polynomials = [

557

[1, 0, -1], # x^2 - 1

558

[1, -3, 3, -1], # (x-1)^3

559

[1, 0, 0, 0, -1], # x^4 - 1

560

[1, -2, 1] # (x-1)^2

561

]

562

563

for i, coeffs in enumerate(test_polynomials):

564

analysis = analyze_polynomial(coeffs)

565

print(f"\nPolynomial {i+1}: {coeffs}")

566

for key, value in analysis.items():

567

print(f" {key}: {value}")

568

```

569

570

### Specialized Polynomial Applications

571

572

```python

573

# Interpolation using different polynomial bases

574

def compare_interpolation_methods(x_data, y_data, eval_points):

575

"""Compare different polynomial interpolation methods."""

576

n_points = len(x_data)

577

degree = n_points - 1

578

579

methods = {}

580

581

# Standard polynomial interpolation

582

std_coeffs = cp.polyfit(x_data, y_data, degree)

583

methods['Standard'] = cp.polyval(std_coeffs, eval_points)

584

585

# Chebyshev interpolation

586

cheb_coeffs = poly.chebyshev.chebfit(x_data, y_data, degree)

587

methods['Chebyshev'] = poly.chebyshev.chebval(eval_points, cheb_coeffs)

588

589

# Legendre interpolation

590

leg_coeffs = poly.legendre.legfit(x_data, y_data, degree)

591

methods['Legendre'] = poly.legendre.legval(eval_points, leg_coeffs)

592

593

return methods

594

595

# Test interpolation with Runge function (challenging for high-degree polynomials)

596

def runge_function(x):

597

return 1 / (1 + 25 * x**2)

598

599

# Interpolation points

600

n_interp = 10

601

x_interp = cp.linspace(-1, 1, n_interp)

602

y_interp = runge_function(x_interp)

603

604

# Evaluation points

605

x_eval = cp.linspace(-1, 1, 200)

606

y_true = runge_function(x_eval)

607

608

# Compare methods

609

methods = compare_interpolation_methods(x_interp, y_interp, x_eval)

610

611

print("Interpolation comparison (MSE vs true function):")

612

for method_name, y_approx in methods.items():

613

mse = cp.mean((y_true - y_approx) ** 2)

614

print(f" {method_name}: {mse:.6f}")

615

616

# Orthogonal polynomial series expansion

617

def orthogonal_series_approximation(func, x_range, n_terms, poly_type='chebyshev'):

618

"""Approximate a function using orthogonal polynomial series."""

619

x = cp.linspace(x_range[0], x_range[1], 1000)

620

y = func(x)

621

622

if poly_type == 'chebyshev':

623

coeffs = poly.chebyshev.chebfit(x, y, n_terms-1)

624

y_approx = poly.chebyshev.chebval(x, coeffs)

625

elif poly_type == 'legendre':

626

coeffs = poly.legendre.legfit(x, y, n_terms-1)

627

y_approx = poly.legendre.legval(x, coeffs)

628

elif poly_type == 'hermite':

629

coeffs = poly.hermite.hermfit(x, y, n_terms-1)

630

y_approx = poly.hermite.hermval(x, coeffs)

631

632

mse = cp.mean((y - y_approx) ** 2)

633

return coeffs, y_approx, mse

634

635

# Test with exponential function

636

exponential = lambda x: cp.exp(x)

637

x_range = (-2, 2)

638

639

for n_terms in [5, 10, 15, 20]:

640

for poly_type in ['chebyshev', 'legendre']:

641

coeffs, y_approx, mse = orthogonal_series_approximation(

642

exponential, x_range, n_terms, poly_type

643

)

644

print(f"{poly_type.capitalize()} ({n_terms} terms): MSE = {mse:.8f}")

645

646

# Polynomial differentiation and integration

647

p = cp.poly1d([1, -2, 1, 3]) # x^3 - 2x^2 + x + 3

648

print(f"Original polynomial: {p}")

649

650

# Multiple derivatives

651

for k in range(1, 4):

652

p_deriv = p.deriv(k)

653

print(f"Derivative {k}: {p_deriv}")

654

655

# Multiple integrals

656

for k in range(1, 3):

657

p_integ = p.integ(k)

658

print(f"Integral {k}: {p_integ}")

659

660

# Definite integration

661

x_vals = cp.linspace(0, 2, 100)

662

y_vals = p(x_vals)

663

numerical_integral = cp.trapz(y_vals, x_vals)

664

analytical_integral = p.integ()(2) - p.integ()(0)

665

print(f"Numerical integral (0 to 2): {numerical_integral}")

666

print(f"Analytical integral (0 to 2): {analytical_integral}")

667

```

668

669

### Performance Optimization

670

671

```python

672

# Efficient polynomial evaluation using Horner's method

673

def horner_evaluation(coeffs, x):

674

"""Evaluate polynomial using Horner's method for numerical stability."""

675

result = cp.zeros_like(x, dtype=cp.result_type(coeffs.dtype, x.dtype))

676

for coeff in coeffs:

677

result = result * x + coeff

678

return result

679

680

# Compare with standard evaluation

681

coeffs_high_degree = cp.random.rand(50) # High-degree polynomial

682

x_test = cp.linspace(-10, 10, 10000)

683

684

# Time both methods

685

import time

686

687

start_time = time.time()

688

result_standard = cp.polyval(coeffs_high_degree, x_test)

689

standard_time = time.time() - start_time

690

691

start_time = time.time()

692

result_horner = horner_evaluation(coeffs_high_degree, x_test)

693

horner_time = time.time() - start_time

694

695

print(f"Standard evaluation time: {standard_time:.4f}s")

696

print(f"Horner evaluation time: {horner_time:.4f}s")

697

print(f"Results match: {cp.allclose(result_standard, result_horner)}")

698

699

# Vectorized polynomial operations for multiple polynomials

700

def batch_polynomial_evaluation(poly_coeffs_list, x_values):

701

"""Evaluate multiple polynomials efficiently."""

702

results = []

703

for coeffs in poly_coeffs_list:

704

results.append(cp.polyval(coeffs, x_values))

705

return cp.stack(results)

706

707

# Create batch of polynomials

708

n_polynomials = 100

709

poly_list = [cp.random.rand(cp.random.randint(3, 10)) for _ in range(n_polynomials)]

710

x_batch = cp.linspace(-5, 5, 1000)

711

712

# Batch evaluation

713

batch_results = batch_polynomial_evaluation(poly_list, x_batch)

714

print(f"Batch evaluation shape: {batch_results.shape}")

715

print(f"Memory usage: {batch_results.nbytes / 1024**2:.2f} MB")

716

717

# Memory-efficient polynomial fitting for large datasets

718

def streaming_polynomial_fit(data_generator, degree, max_batch_size=10000):

719

"""Fit polynomial to streaming data in batches."""

720

x_accumulator = []

721

y_accumulator = []

722

723

for x_batch, y_batch in data_generator:

724

x_accumulator.extend(x_batch)

725

y_accumulator.extend(y_batch)

726

727

# Process when batch is full

728

if len(x_accumulator) >= max_batch_size:

729

x_array = cp.array(x_accumulator)

730

y_array = cp.array(y_accumulator)

731

732

# Fit polynomial to current batch

733

coeffs = cp.polyfit(x_array, y_array, degree)

734

yield coeffs

735

736

# Clear accumulators

737

x_accumulator = []

738

y_accumulator = []

739

740

# Process remaining data

741

if x_accumulator:

742

x_array = cp.array(x_accumulator)

743

y_array = cp.array(y_accumulator)

744

coeffs = cp.polyfit(x_array, y_array, degree)

745

yield coeffs

746

747

# Example streaming data generator

748

def synthetic_data_generator(n_batches=10, batch_size=5000):

749

for i in range(n_batches):

750

x = cp.random.rand(batch_size) * 10 - 5

751

y = 2*x**3 - 3*x**2 + x + 1 + 0.1*cp.random.randn(batch_size)

752

yield cp.asnumpy(x), cp.asnumpy(y)

753

754

# Process streaming data

755

coeffs_list = list(streaming_polynomial_fit(synthetic_data_generator(), degree=3))

756

print(f"Processed {len(coeffs_list)} batches")

757

print("Average coefficients:", cp.mean(cp.stack(coeffs_list), axis=0))

758

```

759

760

Polynomial operations in CuPy provide comprehensive mathematical tools for polynomial manipulation, fitting, evaluation, and analysis, supporting both legacy interfaces and modern orthogonal polynomial bases with GPU acceleration for high-performance computational mathematics and numerical analysis applications.