feynmanKacEvaluate

Computes the value of a Hermite quintic spline or the value of one of its derivatives. In particular, computes solutions to the Feynman-Kac PDE handled by function feynmanKac.

Synopsis

feynmanKacEvaluate (breakpoints, w, coef)

Required Arguments

float breakpoints[] (Input)
Array of length m containing the breakpoints for the Hermite quintic spline interpolation. The breakpoints must be in strictly increasing order. When applied to feynmanKac, breakpoints[] is identical to array xgrid[].
float w[] (Input)
Vector of length nw containing the evaluation points for the spline. It is required that breakpoints[0] w[i] breakpoints[m-1] for i=0,…, nw-1.
float coef[] (Input)

Vector of length 3*m containing the coefficients of the Hermite quintic spline.

When applied to feynmanKac, this vector is one of the rows of output arrays y or yPrime related to the spline coefficients at time points t=tgrid[j], j=1, …, ntgrid.

Return Value

An array of length nw containing the values of the Hermite quintic spline or one of its derivatives at the evaluation points in array w[]. If no values can be computed, then None is returned.

Optional Arguments

deriv, int (Input)

Let d = deriv and let H(w) be the given Hermite quintic spline. Then, this option produces the d-th derivative of H(w) at w, Hd(w). It is required that deriv = 0,1,2 or 3.

Default: deriv = 0.

Description

The Hermite quintic spline interpolation is done over the composite interval [xmin,xmax], where

breakpoints[i-1] = xi are given by (xmin .

The Hermite quintic spline function is constructed using three primary functions, defined by

\begin{split}\begin{aligned} b_0(z) &= -6z^5 + 15z^4 - 10z^3 + 1 = (1-z)^3\left(6z^2 + 3z + 1\right), \\ b_1(z) &= -3z^5 + 8z^4 - 6z^3 + z = (1-z)^3z(3z+1), \\ b_2(z) &= \tfrac{1}{2}\left(-z^5+3z^4-3z^3+z^2\right) = \tfrac{1}{2}(1-z)^3z^2. \end{aligned}\end{split}

For each

x \in \left[x_i,x_{i+1}\right], h_i = x_{i+1} - x_i, z_i = \left(x-x_i\right) / h_i, i = 1, \ldots, m-1,

the spline is locally defined by

\begin{split}\begin{array}{c} H(x) = y_{3i-2}b_0(z) + y_{3i+1}b_0(1-z) + h_iy_{3i-1}b_1(z) \\ -h_iy_{3i+2}b_1(1-z) + h_i^2y_{3i}b_2(z) + h_i^2y_{3i+3}b_2(1-z), \\ \end{array}\end{split}

where

\begin{split}\begin{aligned} y_{3i-2} = f\left(x_i\right), y_{3i-1} = \left({\partial}f / {\partial}x\right)\left(x_i\right) &= f'\left(x_i\right), y_{3i} = \left(\partial^2f / {\partial}x^2\right)\left(x_i\right) \\ &= f''\left(x_i\right), i = 1, \ldots, m - 1 \end{aligned}\end{split}

are the values of a given twice continuously differentiable function f and its first two derivatives at the breakpoints.

The approximating function H(x) is twice continuously differentiable on \left[x_{\text{min}}, x_{\text{max}}\right] , whereas the third derivative is in general only continuous within the interior of the intervals \left[ x_i, x_{i+1} \right] . From the local representation of H(x) it follows that

H\left(x_i\right) = f\left(x_i\right) = y_{3i-2}, H'\left(x_i\right) = f'\left(x_i\right) = y_{3i-1}, H''\left(x_i\right) = y_{3i}, i = 1, \ldots, m

The spline coefficients y_i, i = 1, \ldots, 3m are stored as successive triplets in array coef[]. For a given w \in \left[ x_{\min}, x_{\max} \right], function feynmanKacEvaluate uses the information in coef[] together with the values of b_0, b_1, b_2 and its derivatives at w to compute H^{(d)} (w), d = 0, \ldots, 3 using the local representation on the particular subinterval containing w.

Example

Consider function f(x) = x^5, a polynomial of degree 5, on the interval [-1, 1] with breakpoints \pm 1. Then, the end derivative values are

y_1 = f(-1) = -1, y_2 = f'(-1) = 5, y_3 = f''(-1) = -20

and

y_4 = f(1) = 1, y_5 = f'(1) = 5, y_6 = f''(1) = 20

Since the Hermite quintic interpolates all polynomials up to degree 5 exactly, the spline interpolation on [-1, 1] must agree with the exact function value up to rounding errors.

from __future__ import print_function
from numpy import *
from pyimsl.math.feynmanKacEvaluate import feynmanKacEvaluate

# Define function


def func(x):
    return x ** 5.0


nw = 7
m = 2
breakpoints = [-1.0, 1.0]
w = [-0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75]
coef = [-1.0, 5.0, -20.0, 1.0, 5.0, 20.0]

result = feynmanKacEvaluate(breakpoints, w, coef)

print("     x          F(x)   Interpolant   Error\n")
for i in range(0, 7):
    print("  %6.3f  %10.3f  %10.3f  %10.7f" %
          (w[i], func(w[i]), result[i], fabs(func(w[i]) - result[i])))

Output

     x          F(x)   Interpolant   Error

  -0.750      -0.237      -0.237   0.0000000
  -0.500      -0.031      -0.031   0.0000000
  -0.250      -0.001      -0.001   0.0000000
   0.000       0.000       0.000   0.0000000
   0.250       0.001       0.001   0.0000000
   0.500       0.031       0.031   0.0000000
   0.750       0.237       0.237   0.0000000