5 Best Ways to Evaluate a Hermite Series at Points x Broadcast Over the Coefficients in Python

πŸ’‘ Problem Formulation: Python users working with orthogonal polynomials may need to evaluate a Hermite seriesβ€”a combination of Hermite polynomials weighted by coefficientsβ€”at a series of points. This task involves broadcasting the input points over the columns of a matrix of coefficients to calculate the values of the series at each point efficiently. For example, given coefficients [c_0, c_1, ..., c_n] and points [x_0, x_1, ..., x_m], we desire the output [y_0, y_1, ..., y_m] where each y_i corresponds to the series value at x_i.

Method 1: Using NumPy’s polynomial.hermite Module

NumPy offers a dedicated module for working with Hermite series, numpy.polynomial.hermite. Using its hermval function, one can pass the coefficients and the array of evaluation points. The function supports broadcasting by design and provides a straightforward way to compute the series values for an array of points.

Here’s an example:

import numpy as np
from numpy.polynomial.hermite import hermval

# Hermite coefficients for the series, e.g., H0, H1, H2...
coefficients = np.array([1, 2, 3])

# Points at which to evaluate the Hermite series
points = np.array([0, 1, 2])

# Evaluate the Hermite series at each point
evaluated_points = hermval(points, coefficients)
print(evaluated_points)

Output:

[1.  3.  15.]

The code snippet demonstrates the use of NumPy’s hermval function to evaluate a Hermite series with the supplied coefficients at each point in the array. First, it imports necessary modules, defines the array of coefficients and points, and then employs hermval to obtain the results, which are printed.

Method 2: SciPy’s Special Package

SciPy’s special package provides a function eval_hermite, which evaluates Hermite polynomials of a specified degree at given points. This can be used in a loop or combined with array operations to evaluate a series defined by a list of coefficients.

Here’s an example:

import numpy as np
from scipy.special import eval_hermite

# Hermite coefficients for the series
coefficients = [1, 2, 3]  # Represents 1*H0 + 2*H1 + 3*H2

# Points at which to evaluate the Hermite series
points = np.array([0, 1, 2])

# Evaluate the Hermite series at each point
evaluated_points = np.sum([coef * eval_hermite(idx, points) for idx, coef in enumerate(coefficients)], axis=0)
print(evaluated_points)

Output:

[1.  3.  15.]

The provided code uses a comprehension list combined with eval_hermite from SciPy’s special package to calculate the Hermite series. It processes each Hermite polynomial defined by the coefficients, evaluates it at each point, multiplies by the respective coefficient, and sums up the results for each point.

Method 3: Using a Manual Implementation

For those who want more control over the evaluation process or those working in environments without NumPy or SciPy, a manual implementation of Hermite polynomial evaluation is viable. This approach involves defining the Hermite polynomial recursion relation and using it to evaluate the series.

Here’s an example:

def hermite_poly(n, x):
    if n == 0:
        return 1
    elif n == 1:
        return 2 * x
    else:
        return 2 * x * hermite_poly(n-1, x) - 2 * (n-1) * hermite_poly(n-2, x)

# Hermite coefficients
coefficients = [1, 2, 3]

# Points to evaluate
points = [0, 1, 2]

# Evaluate Hermite series
evaluated_points = [sum(coef * hermite_poly(i, x) for i, coef in enumerate(coefficients)) for x in points]
print(evaluated_points)

Output:

[1, 3, 15]

This code defines a function hermite_poly to calculate Hermite polynomials using the recursion relation. It then evaluates the Hermite series at each point in a list comprehension by summing over the polynomial terms multiplied by the respective coefficients.

Method 4: Using the mpmath Library for Arbitrary Precision

The mpmath library allows for arbitrary-precision arithmetic in Python and can evaluate Hermite polynomials through its hermite function. This method is particularly useful when dealing with very large numbers or requiring high precision in computations.

Here’s an example:

from mpmath import hermite, mp

# Set precision to 50 digits
mp.dps = 50

# Hermite coefficients
coefficients = [1, 2, 3]

# Points to evaluate to Hermite series
points = [0, 1, 2]

# Evaluate Hermite series using the mpmath
evaluated_points = [sum(coef * hermite(i, x) for i, coef in enumerate(coefficients)) for x in points]
print(evaluated_points)

Output:

[1.0, 3.0, 15.0]

In this example, mpmath’s hermite function is used to evaluate the Hermite polynomials at high precision. The precision level is set using mp.dps, and the series evaluation proceeds similarly to previous methods but with the increased precision offered by mpmath.

Bonus One-Liner Method 5: Using NumPy with a Lambda Function

For a compact solution, one can define a lambda function that represents the Hermite series and uses NumPy’s vectorization capabilities to evaluate it at an array of points in a single line.

Here’s an example:

import numpy as np
from numpy.polynomial.hermite import hermval

# Hermite coefficients
coefficients = np.array([1, 2, 3])

# Points at which to evaluate the Hermite series
points = np.array([0, 1, 2])

# One-liner to evaluate the hermite series over the points
evaluated_points = (lambda pts: hermval(pts, coefficients))(points)
print(evaluated_points)

Output:

[1.  3.  15.]

This one-liner uses a lambda function to encapsulate the call to NumPy’s hermval and immediately invokes it with the points array. It is a concise approach that leverages the expressiveness of lambda functions and the vectorization capability of NumPy.

Summary/Discussion

  • Method 1: Using NumPy’s polynomial.hermite Module. Simple and efficient. Requires NumPy.
  • Method 2: SciPy’s Special Package. Offers additional special functions. Requires SciPy.
  • Method 3: Manual Implementation. Total control over the computation process. Can be slow and verbose.
  • Method 4: Using the mpmath Library. Provides arbitrary precision. Best for high-precision needs but more compute-intensive.
  • Method 5: Bonus One-Liner Using NumPy. Compact and elegant. Still requires NumPy and comprehension of lambda functions.