Dynamic Integration of Interpolating Functions and Some Concrete Optimal Stopping Problems

Andrew Lyasoff

This article describes a streamlined method for simultaneous integration of an entire family of interpolating functions that uses one and the same interpolation grid in one or more dimensions. A method for creating customized quadrature/cubature rules that takes advantage of certain special features of Mathematica’s InterpolatingFunction objects is presented. The use of such rules leads to a new and more efficient implementation of the method for optimal stopping of stochastic systems that was developed in []. In particular, this new implementation allows one to extend the scope of the method to free boundary optimal stopping problems in higher dimensions. Concrete applications to finance—mainly to American-style financial derivatives—are presented. In particular, the price of an American put option that can be exercised with any one of two uncorrelated underlying assets is calculated as a function of the observed prices. This method is similar in nature to the well-known Longstaff–Schwartz algorithm, but does not involve Monte–Carlo simulation of any kind.

Preliminaries

The most common encounter with the concept of dynamic programming—and here we will be concerned only with continuous time dynamic programming (CTDP)—occurs in the context of the optimal stopping of an observable stochastic process with given termination payoff. This is a special case of stochastic optimal control where the control consists of a simple on-off switch, which, once turned off, cannot be turned on again. A generic example of an optimal stopping problem can be described as this: the investor observes a continuous Markov process (Subscript[((Subscript[X, t])), t ≥ 0]) with state-space 𝔖⊆(ℝ^N) and with known stochastic dynamics and, having observed at time t≥0 the value (Subscript[(OverHat[X]), t])∈𝔖, where (Subscript[(OverHat[X]), t]) denotes the observed realization of the random variable (Subscript[X, t]), the investor must decide whether to terminate the process immediately and collect the payoff Λ((Subscript[(OverHat[X]), t])), where Λ:𝔖↦ℝ is some a priori determined (deterministic) payoff function, or to wait until time t+Δ > t for the next opportunity to terminate the process (in the context of CTDP, the time step Δ should be understood as an infinitesimally small quantity). In addition, having observed the quantity (Subscript[(OverHat[X]), t])∈𝔖, the investor must determine the value of the observable system (associated with that state) at time t≥0. In many situations, the stopping of the process cannot occur after some finite deterministic time T>0.

There is a vast literature that deals with both the theoretical and the computational aspects of modeling, analysis, and optimal control of stochastic systems. The works of Bensoussan and Lions [] and Davis [] are good examples of classical treatments of this subject.

Many important problems from the realm of finance can be formulated—and solved—as optimal stopping problems. For example, a particular business can be established at the fixed cost of ℐ dollars, but the actual market price of that business follows some continuous stochastic process (Subscript[((Subscript[X, t])), t ≥ 0]), which is observable. Having observed at time t the value (Subscript[(OverHat[X]), t]), an investor who owns the right to incorporate such a business must decide whether to exercise that right immediately, in which case the investor would collect the payoff of (Subscript[(OverHat[X]), t])-ℐ dollars, or to postpone the investment decision until time t+Δ, with the hope that the business will become more valuable. In addition, having observed the value (Subscript[(OverHat[X]), t]), the investor may need to determine the market price of the guaranteed right (say, a patent) to eventually incorporate this business—now, or at any time in the future.

Another classical problem from the realm of finance is the optimal exercise of a stock option of American type, that is, an option that can be exercised at any time prior to the expiration date. A stock option is a contract that guarantees the right to buy (a call option) or to sell (a put option) a particular stock (the underlying) at some fixed price (the strike price, stated explicitly in the option contract) at any time prior to the expiration date T (the maturity date, also stated in the option contract). Consider, for example, an American style put option which expires at some future date T>0. On date t<T, the holder of the option observes the underlying price (Subscript[(OverHat[X]), t]) and decides whether to exercise the option, that is, to sell the stock at the guaranteed price K (and, consequently, collect an immediate payoff of K-(Subscript[(OverHat[X]), t]) dollars) or to wait, hoping that at some future moment, but no later than the expiration date T, the price will fall below the current level (Subscript[(OverHat[X]), t]). If the option is not exercised before the expiration date, the option is lost if (Subscript[X, T])≥K or, ignoring any transaction costs, is always exercised if (Subscript[X, T])<K; that is, if the option is not exercised prior to the expiration date T, on that date the owner of the option collects the amount Max[K-(Subscript[X, T]),0]. In general, stock options are traded in the same way that stocks are traded and, therefore, have a market value determined by the laws of supply and demand. At the same time, the price of such contracts, treated as a function of the observed stock price (Subscript[(OverHat[X]), t]), can be calculated from general economic principles in conjunction with the principles of dynamic programming.

In general, the solution to any optimal stopping problem has two components: (1) for every moment in time, t, one must obtain a termination rule in the form of a termination set (Subscript[ℰ, t])⊆𝔖 so that the process is terminated at the first moment t at which the event {(Subscript[X, t])∈(Subscript[ℰ, t])} occurs; and (2) for every moment t, one must determine the value function (Subscript[f, t]):𝔖↦ℝ, which measures how “valuable” different possible observations are at time t. Clearly, if Λ(·) denotes the termination payoff function (e.g., in the case of an American style put option that would be Λ(x) = Max[K-x,0], x∈(SubPlus[ℝ])), then for every x∈(Subscript[ℰ, t]) one must have (Subscript[f, t])(x)=Λ(x), while for every x∉(Subscript[ℰ, t]) one must have (Subscript[f, t])(x)>Λ(x); that is, one would choose to continue only when continuation is more valuable than immediate termination. Consequently, the termination sets (Subscript[ℰ, t]), t≥0, can be identified with the sets {x∈(ℝ^N);(Subscript[f, t])(x)=Λ(x)}, and the associated optimal stopping time can be described as

τ=inf{t∈[0,T]; (Subscript[f, t])((Subscript[X, t]))=Λ((Subscript[X, t]))}.

Thus, the entire solution to the optimal stopping problem can be expressed in terms of the family of value functions {(Subscript[f, t])(·); t∈[0,T]}, which may be treated as a single function of the form

[0,T]×𝔖∋(t,x)⟶(Subscript[f, t])(x)∈ℝ.

It is important to recognize that the solution to the optimal stopping problem, that is, the value function (t,x) ⟶ (Subscript[f, t])(x), must be computed before the observation process has begun.

In most practical situations, an approximate solution to the optimal stopping problem associated with some observable process (Subscript[((Subscript[X, t])), t ≥ 0]) and some fixed termination payoff Λ:𝔖↦ℝ may be obtained as a finite sequence of approximate value functions

(Subscript[⟨f⟩ , t]^ν):𝔖↦ℝ, t=T,T-(T/ν), T-2(T/ν),… , 0,

where T>0 is the termination date and ν is some sufficiently large integer number. This approximate solution can be calculated from the following recursive rule, which is nothing but a special discrete version of what is known as the dynamic programming equation: for t=T, we set (Subscript[⟨f⟩, t]^ν)(·)≡Λ(·), that is, at time t=T, the value function coincides with the termination payoff on the entire state-space 𝔖, and for t=T- (T/ν), T- 2(T/ν), … , we set

(Subscript[⟨f⟩, t]^ν)(x):=Max[Λ(x),(e^(-(Subscript[r, t])T/ν))(Subscript[Ε, Q])[(Subscript[⟨f⟩, t+T/ν]^ν)((Subscript[X, t+T/ν])) | (Subscript[X, t])=x]], x∈𝔖,

where (Subscript[r, t]) is the instantaneous discount rate at time t, and the probability measure Q, with respect to which the conditional expectation is calculated, is the so-called pricing measure (in general, the instantaneous discount rate (Subscript[r, t])≡(Subscript[r, t])(x) may depend on the observed position x=(Subscript[(OverHat[X]), t]) and the pricing measure may be different from the probability measure that governs the actual stochastic dynamics of the process (Subscript[((Subscript[X, t])), t ≥ 0])). Furthermore, for every t=T-(T/ν), T-2(T/ν), … , the approximate termination set is given by

(Subscript[⟨ℰ⟩, t])≡{x∈(ℝ^N);(Subscript[⟨f⟩, t]^ν)(x)=Λ(x)}.

If, given any t∈[0,T], the limit

(Subscript[f, t])(·)≡(lim_(ν ↗ ∞))(Subscript[⟨f⟩, (T/ν) ⌊ν t/T⌋]^ν)(·)

(⌊·⌋ denotes the integer part of a real number) exists, in some appropriate topology on the space of functions defined on the state-space 𝔖, then one can declare that the function

[0,T]×(ℝ^N)∋(t,x)⟶(Subscript[f, t])(x)∈ℝ

gives the solution to the optimal stopping problem with observable process (Subscript[((Subscript[X, t])), t ≥ 0]), payoff function Λ(·), and pricing measure Q.

It is common to assume that under the pricing probability measure Q the stochastic dynamics of the observable process (Subscript[((Subscript[X, t])), t ≥ 0]) are given by some diffusion equation of the form

d(Subscript[X, t])=σ((Subscript[X, t]))d(Subscript[W, t])+b((Subscript[X, t]))dt

for some (sufficiently nice) matrix-valued function (ℝ^N)∋x⟶σ(x)∈(ℝ^(N⊗N)), vector field (ℝ^N)∋x⟶b(x)∈(ℝ^N), and some (ℝ^N)-valued Brownian motion process (Subscript[((Subscript[W, t])), t ≥ 0]), which is independent from the starting position (Subscript[X, 0]) (note that (Subscript[((Subscript[W, t])), t ≥ 0]) is Brownian motion with respect to the law Q). Given any x∈(ℝ^N), let A(x) denote the matrix σ(x)((σ(x))^T) and let ℒ denote the second-order field in (ℝ^N) given by

(ℝ^N)∋x⟶(Subscript[ℒ, x])≡(1/2)(∑_(i,j=1)^N)(Subscript[A(x), i,j])((∂^2)/((∂_(Subscript[x, i]))(∂_(Subscript[x, j]))))+(∑_(i=1)^N)(Subscript[b(x), i])(∂/(∂_(Subscript[x, i]))).

As is well known, under certain fairly general conditions for the coefficients σ(·) and b(·), and the termination payoff Λ:𝔖↦ℝ, the value function

[0,T]×𝔖∋(t,x)⟶(Subscript[f, t])(x)∈ℝ,

that is, the solution to the associated optimal stopping problem, is known to satisfy the following equation, which is nothing but a special case of the Hamilton–Jacobi–Bellman (HJB) equation

(Subscript[r, t])(x)(Subscript[f, t])(x)=Max[(Subscript[r, t])(x) Λ(x), (∂_t)(Subscript[f, t])(x)+(Subscript[ℒ, ξ])(Subscript[f, t])(x)], x∈(ℝ^N),

with boundary condition (Subscript[f, T])(x)=Λ(x), x∈(ℝ^N). This equation is a more or less trivial consequence of equations () and (), in conjunction with the Itô formula. It is important to recognize that the dynamic programming equation () is primary for the optimal stopping problem, while the HJB equation () is only secondary, in that it is nothing more than a computational tool. Unfortunately, equation () admits a closed form solution only for some rather special choices of the payoff function Λ(·), the diffusion coefficients b(·) and σ(·), and the discount rate (Subscript[r, t])(·). Thus, in most practical situations, the HJB equation () happens to be useful only to the extent to which this equation gives rise to some numerical procedure that may allow one to compute the solution (t,x)⟶(Subscript[f, t])(x) approximately. Essentially, all known numerical methods for solving equation () are some variations of the finite difference method. The most common approach is to reformulate equation () as a free boundary value problem: one must find a closed domain 𝒟⊆[0,T[×𝔖 with a piecewise differentiable boundary ∂𝒟 and nonempty interior (𝒟^∘) ≡ 𝒟\∂𝒟, plus a continuous function u:𝒟↦ℝ, which is continuously differentiable with respect to the variable t∈ ] 0,T [ and is twice continuously differentiable with respect to the variables x∈(𝒟^∘), that satisfies the following two relations everywhere inside (𝒟^∘)

(Subscript[r, t])(x)u(t,x)=(∂_t)u(t,x)+(Subscript[ℒ, x])u(t,x)    and    u(t,x)>Λ(x), (t,x)∈(𝒟^∘),

and, finally, satisfies the following boundary conditions along the free (i.e., unknown) boundary ∂𝒟

u(t,x)=Λ(x)    and    (∂/(∂_(Subscript[x, i])))u(t,x)=(∂/(∂_(Subscript[x, i])))Λ(x), 1≤i≤n, (t,x)∈∂𝒟.

The last two conditions are known, respectively, as the value matching and the smooth pasting conditions. It can be shown that under some rather general—but still quite technical—assumptions, the free boundary value problem that was just described has a unique solution (consisting of a function u(·,·) and domain 𝒟) which then allows one to write the solution to the optimal stopping problem as follows: for any t∈[0,T] and any x∈𝔖, one has

(Subscript[f, t])(x)={({{u(t,x) ,  for (t,x)∈𝒟;}, {Λ(x),  for (t,x)∈(𝒟^c)≡([0,T]×𝔖)\𝒟.}})

The drawbacks from formulating an optimal stopping problem as a free boundary value problem for some parabolic partial differential equation (PDE), which—in principle, at least—can be solved numerically by way of finite differencing, are well known. First, the value matching and the smooth pasting conditions are difficult to justify and this makes the very formulation of the problem rather problematic in many situations. Second, just in general, for purely technical reasons, it is virtually impossible to use finite differencing when the dimension of the state-space is higher than 3 and, in fact, in the case of free boundary value problems, even a state-space of dimension 2 is rather challenging. Third, with the exception of the explicit finite difference scheme, which is guaranteed to be stable only under some rather restrictive conditions, the implementation of most finite differencing procedures on parallel processors is anything but trivial.

At the time of this writing, it is safe to say that finite differencing is no longer at the center of attention in computational finance, where most problems are inherently complex and multidimensional. Indeed, most of the research in computational finance in the last five years or so appears to be focused on developing new simulation-based tools—see [–], for example (even a cursory review of the existing literature from the last few years is certain to be very long and is beyond the scope of this article). Among these methods, the Longstaff–Schwartz algorithm [] seems to be the most popular among practitioners.

The attempts to avoid the use of finite differencing are nothing new (there is a section in the book Numerical Recipes in C entitled There Is More to Life than Finite Differencing—see [], p. 833). Indeed, Monte Carlo, finite element, and several other computational tools have been in use for solving fixed boundary value problems for PDEs for quite some time. Apparently, from the point of view of stochastic optimal control, it is more efficient—and in some ways more natural—to develop numerical procedures directly from the dynamic programming equation () and skip the formulation of the HJB equation altogether—at least this is the approach that most recent studies in computational finance are taking.

Since the solution to an optimal stopping problem is given by an infinite family of functions of the form (Subscript[f, t]):𝔖↦ℝ, t∈[0,T], for some set 𝔖⊆(ℝ^N), from a computational point of view the actual representation of any such object involves two levels of discretization. First, one must discretize the state-space 𝔖, that is, functions defined on 𝔖 must be replaced with finite lists of values attached to some fixed set of distinct abscissas

{(Subscript[x, k])∈𝔖; 1≤k≤n},

for some fixed n∈(SubPlus[ℤ]). This means that for every list of values ℓ∈(ℝ^n), one must be able to construct a function (S^ℓ):𝔖↦ℝ which “extends” the discrete assignment (Subscript[x, k])⟶(Subscript[ℓ, k]), 1≤k≤n, to some function defined on the entire state-space 𝔖. Second, one must discretize time, that is, replace the infinite family of functions {(Subscript[f, t])(·);t∈[0,T]} not just with the finite sequence of functions

(Subscript[⟨f⟩, t]^ν):𝔖↦ℝ, t=T, T- (T/ν), T- 2(T/ν), … , 0,

determined by the discrete dynamic programming equation (), but, rather, with a finite sequence of lists

ℓ(t)∈(ℝ^n), t=T- (T/ν), T- 2(T/ν), … , 0,

computed from the following space-discretized analog of the time-discrete dynamic programming equation (): for t=T-(T/v), we set

(Subscript[ℓ(t), k])≡Max[Λ((Subscript[x, k])), (e^(-(Subscript[r, t]) (T/ν)))(Subscript[Ε, Q])[Λ((Subscript[X, T])) | (Subscript[X, t])=(Subscript[x, k])]], 1≤k≤n,

and then define

(Subscript[ℓ(t), k])≡Max[Λ((Subscript[x, k])), (e^(-(Subscript[r, t])(T/ν)))(Subscript[Ε, Q])[(S^(ℓ(t+T/ν)))((Subscript[X, t+T/ν])) | (Subscript[X, t])=(Subscript[x, k])]], 1≤k≤n,

consecutively, for t=T-2 (T/v), t=T-3(T/v), … , where (S^(ℓ(t+T/ν))):𝔖↦ℝ is simply the map that “extends” the discrete assignment (Subscript[x, k])⟶(Subscript[ℓ(t+(T/v)), k]).

Of course, in order to compute the conditional expectation in equation (), the distribution law of the random variable (Subscript[X, t+T/ν]) relative to the pricing measure Q and conditioned to the event {(Subscript[X, t])=(Subscript[x, k])} must be expressed in computable form. Unfortunately, this is possible only for some rather special choices for the diffusion coefficients σ(·) and b(·) that govern the stochastic dynamics of the process (Subscript[((Subscript[X, t])), t ≥ 0]) under the pricing measure Q. This imposes yet another—third—level of approximation. The simplest such approximation is to replace (Subscript[X, t+T/ν]) in equation () with the random quantity

(Subscript[ψ, T/ν])((Subscript[x, k]),Γ)=(Subscript[x, k])+σ((Subscript[x, k]))(Sqrt[(T/v)])Γ+b((Subscript[x, k])) ((T/v)),

where Γ is some standard normal (ℝ^N)-valued random variable. As a result of this approximation, expression () becomes

(Subscript[ℓ(t), k])≡Max[Λ((Subscript[x, k])), (e^(-(Subscript[r, t]) (T/ν)))(∫_(ℝ^N)) (S^(ℓ(t+T/ν)))((Subscript[ψ, T/ν])((Subscript[x, k]),x))(Subscript[p, N])(x)dx],   1≤k≤n,

where (Subscript[p, N])(·) stands for the standard normal probability density function in (ℝ^N). Another (somewhat more sophisticated) approximation scheme for the diffusion process (Subscript[((Subscript[X, t])), t ≥ 0]) in the case N=1 is discussed in []. Fortunately, in the most widely used diffusion models in finance, the conditional law of (Subscript[X, t+T/ν]), given the event {(Subscript[X, t])=(Subscript[x, k])}, coincides with the law of a random variable of the form ψ((Subscript[x, k]),Γ) for some function ψ((Subscript[x, k]),·) that can be expressed in computable form, so that in this special case the right side of equation () is exactly identical to the right side of equation () and the approximation given in equation () is no longer necessary.

One must be aware that, in general, the distribution law of the random variable ψ((Subscript[x, k]),Γ) is spread on both sides of the point (Subscript[x, k]) and, even though for a reasonably small time step (T/v) this law is concentrated almost exclusively in some small neighborhood of the node (Subscript[x, k]), when this node happens to be very close to the border of the interpolation region, the computation of the integral on the right side of equation () inevitably requires information about the function (S^(ℓ(t+T/ν)))(·) outside the interpolation domain. However, strictly speaking, interpolating functions are well defined only inside the convex hull of the abscissas used in the interpolation. One way around this problem is to choose the interpolation domain in such a way that along its border the solution to the optimal stopping problem takes values that are very close to certain asymptotic values. For example, if one is pricing an American put option with strike price of $1, one may assume that the value of the option is practically 0 when the price of the underlying asset is above $100, regardless of the time left to maturity (of course, this assumption may be grossly inaccurate when the volatility is very large and/or when the option matures in the very distant future). Consequently, for those nodes (Subscript[x, k]) that are close to the border of the interpolation domain, the respective values (Subscript[ℓ(t), k]) will not depend on t and will not be updated according to the prescription (). At the same time, the remaining nodes (Subscript[x, k]) must be chosen in such a way that the probability mass of the random variable ψ((Subscript[x, k]),Γ) is concentrated almost exclusively inside the interpolation region.

In general, numerical procedures for optimal stopping of stochastic systems differ in the following: First, they differ in the space-discretization method, that is, the method for choosing the abscissas (Subscript[x, k]) and for “reconstructing” the function (S^ℓ)(·) from the (finite) list of values ℓ assigned to the abscissas (Subscript[x, k]). Second, numerical procedures differ in the concrete quadrature rule used in the calculation of the conditional expectation in the discretized dynamic programming equation (). The method described in this article is essentially a refinement of the method of dynamic interpolation and integration described in []. The essence of this method is that the functions (S^ℓ)(·) are defined by way of spline interpolation—or some other type of interpolation—from the list of values ℓ, while the integral in equation () is calculated by using some standard procedures for numerical integration. As was illustrated in [], the implementation of this procedure in Mathematica is particularly straightforward, since NIntegrate accepts as an input InterpolatingFunction objects, and, in fact, can handle such objects rather efficiently.

The key point in the method developed in this article is a procedure for computing a universal list of vectors (Subscript[Ω, k])∈(ℝ^n), 1≤k≤n, associated with the abscissas (Subscript[x, k]), 1≤k≤n, that depend only on the stochastic dynamics of (Subscript[((Subscript[X, t])), t ≥ 0]) and the time step (T/v), so that one can write

(∫_ℛ) (S^(ℓ(t+T/ν)))(ψ((Subscript[x, k]),x))(Subscript[p, N])(x)dx=(Subscript[Ω, k])·ℓ(t+(T/v))

for any t and for any k, where ℛ stands for the convex hull of the interpolation grid (Subscript[x, k]), that is, the domain of interpolation. Essentially, equation () is a variation of the well-known cubic spline quadrature rule—see §4.0 in [] and §5.2, p. 89, in []. It is also analogous to the “cubature formula,” which was developed in [] with the help of a completely different computational tool (following [] and [], we use the term cubature as a reference to some integration rule for multiple integrals and the term quadrature as a reference to some integration rule for single integrals). One of the principal differences between the interpolation quadrature/cubature rules and the cubature formula obtained in [] is that the former allows for a greater freedom in the choice of the abscissas (Subscript[x, k]). This means that, in practice, one can choose the evaluation points in a way that takes into account the geometry of the payoff function Λ(·) and not just the geometry of the diffusion (Subscript[((Subscript[X, t])), t ≥ 0]). From a practical point of view, this feature is quite important and, in fact, was the main reason for developing what is now known as Gaussian quadratures.

An entirely different method for computing conditional averages of the form

(Subscript[Ε, Q])[φ((Subscript[X, t+T/ν])) | (Subscript[X, t])=(Subscript[x, k])]

was developed in [] and []. In this method, quantities of this form are approximated by finite products of linear operators acting on the function φ(·). One must be aware that the methods described in [–] require a certain degree of smoothness for the integrand φ(·), which, generally, InterpolatingFunction objects may not have.

The method developed in this article bears some similarity also with the quantization algorithm described in [, ]. The key feature in both methods is that one can separate and compute—once and for all—certain quantities that depend on the observable process but not on the payoff function. Essentially, this means that one must solve, simultaneously, an entire family of boundary value problems corresponding to different payoff functions. The two methods differ in the way in which functions on the state-space are encoded in terms of finite lists of values. The advantages in using interpolating functions in general, or splines in particular, are well known: one can “restore” the pricing maps from fewer evaluation points and this feature is crucial for optimal stopping problems in higher dimensions.

Making Quadrature/Cubature Rules with Mathematica

In this section we show how to make quadrature/cubature rules for a fixed set of abscissas that are similar to the well-known Gaussian rules or the cubic spline rules. We consider quadrature rules on the real line ℝ first. To begin with, suppose that one must integrate some cubic spline x⟶S(x) that is defined from the abscissas {(Subscript[x, 1]),… ,(Subscript[x, n])}∈(ℝ^n), (Subscript[x, 1])<⋯<(Subscript[x, n]), and from some list of tabulated values {(Subscript[v, 1]),… ,(Subscript[v, n])}∈(ℝ^n). Since S(·) is a cubic spline, for any fixed 1≤k≤(n-1) there are real numbers (Subscript[a, k,0]), (Subscript[a, k,1]), (Subscript[a, k,2]), and (Subscript[a, k,3]) for which we have

S(x)=(Subscript[a, k,0])+(Subscript[a, k,1])x+(Subscript[a, k,2])(x^2)+(Subscript[a, k,3])(x^3)    for any    x∈[(Subscript[x, k]),(Subscript[x, k+1])].

As a result, one can write

(∫_(Subscript[x, 1])^(Subscript[x, n]))S(x)dx=(∑_(k=1)^(n-1))(∑_(i=0)^3)((Subscript[a, k,i])/(i+1))((Subscript[x, k+1]^(i+1))-(Subscript[x, k]^(i+1))),

which reduces the computation of the integral (∫_(Subscript[x, 1])^(Subscript[x, n]))S(ξ)dξ to the computation of the coefficients (Subscript[a, k,i]) from the tabulated values (Subscript[v, k]) and the abscissas (Subscript[x, k]).

Though not immediately obvious, it so happens that when all abscissas (Subscript[x, 1])<⋯<(Subscript[x, n]) are fixed, each coefficient (Subscript[a, k,i])—and, consequently, the entire expression on the right side of equation ()—can be treated as a linear function of the list {(Subscript[v, 1]),… ,(Subscript[v, n])} ∈ (ℝ^n) (in fact, each (Subscript[a, k,i]) is a linear function only of a small portion of that list). This property is instrumental for the quadrature/cubature rules that will be developed in the next section. To see why one can make this claim, recall that (e.g., see §3.3 in []) the cubic spline created from the discrete assignment (Subscript[x, k])⟶(Subscript[v, k]), 1≤k≤n, is given by

({{S(x), ≡, (Subscript[a, k,0])+(Subscript[a, k,1])x+(Subscript[a, k,2])(x^2)+(Subscript[a, k,3])(x^3)}, { , =, (Subscript[A, k])(x) (Subscript[v, k])+(Subscript[B, k])(x) (Subscript[v, k+1])+(Subscript[C, k])(x) (Subscript[v, k]^″)+(Subscript[D, k])(x) (Subscript[v, k+1]^″),}, { ,  ,                                                               (Subscript[x, k])≤x≤(Subscript[x, k+1]), 1≤k≤n-1,}})

where

({{(Subscript[A, k])(x), ≡, (((Subscript[x, k+1])-x)/((Subscript[x, k+1])-(Subscript[x, k]))),}, {(Subscript[B, k])(x), ≡, 1-(Subscript[A, k])(x),}, {(Subscript[C, k])(x), ≡, (((((Subscript[A, k])(x))^3)-(Subscript[A, k])(x))/6)((((Subscript[x, k+1])-(Subscript[x, k])))^2),}, {(Subscript[D, k])(x), ≡, (((((Subscript[B, k])(x))^3)-(Subscript[B, k])(x))/6)((((Subscript[x, k+1])-(Subscript[x, k])))^2),}})

and (Subscript[v, k]^″):=S''((Subscript[x, k])), 1≤k≤n (note that the definition implies S((Subscript[x, k]))=(Subscript[v, k]), 1≤k≤n). Usually, one sets (Subscript[v, 1]^″)=(Subscript[v, n]^″)=0 (which gives the so-called natural splines) and determines the remaining values {(Subscript[v, 2]^″),… ,(Subscript[v, n-1]^″)} from the requirement that the cubic spline has a continuous first derivative on the entire interval ](Subscript[x, 1]),(Subscript[x, n])[ (it is a trivial matter to check that with this choice the second derivative of the function defined in equation () is automatically continuous on ](Subscript[x, 1]),(Subscript[x, n ])[). Finally, recall that this last requirement leads to a system of n-2 linear equations with unknowns {(Subscript[v, 1]^″),… ,(Subscript[v, n]^″)} and that the right side of each of these equations is a linear function of the list {(Subscript[v, 1]),… ,(Subscript[v, n])}, while the coefficients in the left side are linear functions of the abscissas {(Subscript[x, 1]),… ,(Subscript[x, n])}—see equation (3.3.7) in [], for example. This means that each quantity in the list {(Subscript[v, 2]^″),… ,(Subscript[v, n-1]^″)} can be treated as a linear function of the list {(Subscript[v, 1]),… ,(Subscript[v, n])}. Since the quantities (Subscript[A, k])(x), (Subscript[B, k])(x), (Subscript[C, k])(x), and (Subscript[D, k])(x) are all independent from the choice of {(Subscript[v, 1]),… ,(Subscript[v, n])}, one can claim that the entire expression in the right side of equation () is a linear function of the list {(Subscript[v, 1]),… ,(Subscript[v, n])}. Thus, for every 1≤k≤(n-1) and every x∈[(Subscript[x, i]),(Subscript[x, i+1])], we can write

S(x)≡(Subscript[a, k,0])+(Subscript[a, k,1])x+(Subscript[a, k,2])(x^2)+(Subscript[a, k,3])(x^3)=(∑_(k=1)^n)(Subscript[h, k,i])(x) (Subscript[v, k ]),

where (Subscript[h, k,i])(·) are polynomials of degree at most 3. More importantly, these polynomials are universal in the sense that they depend on the abscissas (Subscript[x, k]) but not on the tabulated values (Subscript[v, k]). In fact, this representation holds for spline interpolation objects of any degree, except that in the general case the degree of the polynomials (Subscript[h, k,i])(·) may be bigger than 3. An analogous representation is valid for other (non-spline) interpolating functions S(·); in particular, such a representation is valid for interpolating functions S(·) defined by way of divided differences interpolation, which is the method used by ListInterpolation. For example, if S(·) denotes the usual interpolating polynomial of degree n-1 defined from the discrete assignment (Subscript[x, k])⟶(Subscript[v, k]), 1≤k≤n, then (Subscript[h, k,i])(·)≡(Subscript[h, k])(·) is simply the (k^th) Lagrange polynomial for the abscissas (Subscript[x, k]). Thus, when S(·) is an interpolating function object (defined by, say, splines, divided differences, or standard polynomial interpolation) from the assignment (Subscript[x, k])⟶(Subscript[v, k]), 1≤k≤n, assuming that ϕ(·) is some (fixed) continuous and strictly monotone function and that p(·) is some (fixed) integrable function and, finally, assuming that the values (Subscript[z, k])∈ℝ, 1≤k≤n, are chosen so that ϕ((Subscript[z, k]))=(Subscript[x, k]), 1≤k≤n, one can write

(∫_(Subscript[z, 1])^(Subscript[z, n]))S(ϕ(x))p(x)dx={(Subscript[ω, 1])… ,(Subscript[ω, n])}·{(Subscript[v, 1]),… ,(Subscript[v, n])}≡(∑_(k=1)^n)(Subscript[ω, k]) (Subscript[v, k]),

where

(Subscript[ω, k])≡(∑_(i=1)^(N-1))(∫_(Subscript[z, i])^(Subscript[z, i+1]))(Subscript[h, k,i])(ϕ(x))p(x)dx, 1≤k≤n.

Since the list {(Subscript[ω, 1]),… ,(Subscript[ω, n])}∈(ℝ^n) can be computed once and for all and independently from the interpolated values (Subscript[v, k]), and since the calculation of the integral (∫_(Subscript[z, 1])^(Subscript[z, n]))S(ϕ(x))p(x)dx comes down to the calculation of the dot product {(Subscript[ω, 1])… ,(Subscript[ω, n])}·{(Subscript[v, 1]),… ,(Subscript[v, n])}, the computation of the list {(Subscript[ω, 1]),… ,(Subscript[ω, n])}∈(ℝ^n) may be viewed as a simultaneous integration of all functions of the form x⟶S(ϕ(x))p(x) for all interpolating functions S(·) (of the same interpolation type) that are based on one and the same (forever fixed) set of abscissas {(Subscript[x, 1]),… ,(Subscript[x, n])}. Indeed, the knowledge of the list {(Subscript[ω, 1]),… ,(Subscript[ω, n])} turns the expression (∫_(Subscript[z, 1])^(Subscript[z, n]))S(ϕ(x))p(x)dx into a trivial function of the list {(Subscript[v, 1]),… ,(Subscript[v, n])}, that is, a trivial function defined on the entire class of interpolating functions S(·). In other words, in equation () we have made a quadrature (or cubature) rule.

The preceding remarks contain nothing new or surprising in any way and we only need to find a practical way for computing the weights (Subscript[ω, k]). Fortunately, Mathematica allows one to define InterpolatingFunction objects even if the interpolated values (Subscript[v, k]) are defined as symbols that do not have actual numerical values assigned to them. Furthermore, such objects can be treated as ordinary functions that can be evaluated, differentiated, and so on—all in symbolic form. We illustrate this powerful feature next (recall that ListInterpolation has default setting InterpolationOrder->3).

V=Array[(Subscript[v, #1])&,{10}]

S=ListInterpolation[V]

(∂_(x,x))S(x)/.{x->3.5}//Simplify

(∂_(x,x))S(x)/.{x->(7/2)}//Simplify

Since, just by definition, the restriction of the function x->S(x) to the interval [3,4] coincides with a polynomial of degree 3, by Taylor’s theorem, for any fixed (Subscript[x, 0])∈ ]3,4[, we have

S(x)=(∑_(i=0)^3)(1/(i!))Derivative[i][S]((Subscript[x, 0])) (((x-(Subscript[x, 0])))^i)    for any    3≤x≤4.

Thus, if we define

te[ff_,x0_]:=Sum[(1/(i!))*Derivative[i][ff](x0)*(((x-x0))^i),{i,0,3}];

then on the interval [3,4] we can identify the function S with the dot product

x0=3.5;S34[x_]=CoefficientList[te[S,x0],x].{1,x,(x^2),(x^3)};Clear[x0]

Mathematica can rearrange this expression as an ordinary polynomial:

Collect[S34(x)//Simplify,x]

We can also do

x0=(7/2);SS34[x_]=CoefficientList[te[S,x0],x].{1,x,(x^2),(x^3)};Clear[x0]

Collect[SS34(x)//Simplify,x]

Essentially, this is some sort of reverse engineering of the InterpolatingFunction object S, that is, a way to “coerce” Mathematica to reveal what polynomials the object S is constructed of between the interpolation points.

There are other tricks that we can use in order to reverse engineer an InterpolatingFunction object. For example, with the definition of S, the entire function [3,4]∋x⟶S(x)∈ℝ can be restored from the values {S(3),S((10/3)),S((11/3)),S(4)}. To do the restoration we must solve a linear system for the four unknown coefficients in some (unknown) cubic polynomial. This can be implemented in Mathematica rather elegantly without the use of CoefficientList. The only drawback in this approach is that one must resort to Solve or LinearSolve, which, generally, are more time-consuming, especially in dimensions 2 or higher. Of course, instead of using reverse engineering, one can simply implement the interpolation algorithm step-by-step, which, of course, involves a certain amount of work.

For example, we have

S34(3.7)-S(3.7)//Simplify

%//Chop

SS34((37/10))-S((37/10))//Simplify

In the definition of S34, the variable x0 can be given any numerical value inside the interval ]3,4[; the choice x0=3.5 was completely arbitrary.

In the same way, one can reverse engineer InterpolatingFunction objects that depend on any number of independent abscissas. Here is an example.

VV=Array[(Subscript[v, #1,#2])&,{10,10}];

H=ListInterpolation[VV]

(∂_(x,y))H(x,y)/.{x->3.2,y->3.7}//Simplify

Te[ff_,x0_,y0_]:=Sum[(1/((i!)*(j!)))*Derivative[i,j][ff](x0,y0)*(((x-x0))^i)*(((y-y0))^j),{i,0,3},{j,0,3}];

x0=3.5;y0=4.5;H3445[x_,y_]=Flatten[CoefficientList[Te[H,x0,y0],{x,y}]//Simplify].Flatten[Table[(x^i)(y^j),{i,0,3},{j,0,3}]];Clear[x0,y0]

H3445(3.2,4.7)-H(3.2,4.7)//Simplify

%//Chop

In this example, for 3≤x≤4 and for 4≤y≤5, the quantity H[x,y] can be expressed as the following polynomial of the independent variables x and y.

H3445[x,y];

If one does not suppress the output from the last line (which would produce a fairly long output), it  becomes clear that all coefficients in the polynomial of the variables x and y are linear functions of the array VV∈(ℝ^(10⊗10)). Consequently, if the variables x and y are integrated out, the expression will turn into a linear combination of all the entries (symbols) in the array VV.

Now we turn to concrete applications of the features described in this section. For the purpose of illustration, all time-consuming operations in this notebook are executed within the Timing function. The CPU times reflect the speed on Dual 2 GHz PowerPC processors with 2.5 GB of RAM. The Mathematica version is 6.0.1. For all inputs with computing time longer than 1 minute, a file that contains the returned value is made available.

Some Examples of Cubic Cubature Rules for Gaussian Integrals in (ℝ^2)

First, define the standard normal density in (ℝ^2).

p[x_,y_]=(1/(2π))(E^(-(((x^2)+(y^2))/2)));

In this section, we develop cubature rules for computing integrals of the form

(∫_(-∞)^∞)dx(∫_(-∞)^∞)f(x,y)p(x,y)dy

for certain functions f(·). We suppose that the last integral can be replaced by

(∫_(-R)^R)dx(∫_(-R)^R)f(x,y)p(x,y)dy

without a significant loss of precision, where the value

R=(84/10);

is chosen so that

(1/(Sqrt[2π]))(∫_R^∞)(E^(-((u^2)/2)))\[DifferentialD]u<$MachineEpsilon

The next step is to choose the abscissas X[[k]], 1≤k≤m, and Y[[l]], 1≤l≤n:

X=Table[x,{x,-R,R,(4/5)}];Y=X;

m=Length[X];n=Length[Y];

For the sake of simplicity, in display equations we will write (Subscript[x, k]) instead of X[[k]] and (Subscript[y, l]) instead of Y[[l]]. Then we define the associated array of symbolic values attached to the interpolation nodes ((Subscript[x, k]),(Subscript[y, l]))

V=Array[(Subscript[v, #1,#2])&,{m,n}];

and produce the actual InterpolatingFunction object:

f=ListInterpolation[Table[{X[[k]],Y[[l]],{V[[k,l]]}},{k,1,m},{l,1,n}]]

Note that V was defined simply as an array of symbols and that, therefore, f can be treated as a symbolic object, too. In any case, we have

({{(∫_(-R)^R)dx(∫_(-R)^R)f(x,y)p(x,y)dy}, { =(∑_(k=1)^(m-1))(∑_(l=1)^(n-1))(∫_(Subscript[x, k])^(Subscript[x, k+1]))dx(∫_(Subscript[y, l])^(Subscript[y, l+1]))f(x,y)p(x,y)dy.}})

Note that each double integral on the right side of the last identity is actually an integral of some polynomial of the variables x and y multiplied by the standard normal density in (ℝ^2). Furthermore, as was pointed out earlier, every coefficient in this polynomial is actually a linear function of the array V. Since the InterpolatingFunction object f was defined with InterpolationOrder->3 (the default setting for ListInterpolation), we can write

({{(∫_(Subscript[x, k])^(Subscript[x, k+1]))dx(∫_(Subscript[y, l])^(Subscript[y, l+1]))f(x,y)p(x,y)dy}, { =(∑_(i=0)^3)(∑_(j=0)^3)(Subscript[ℓ, k,l,i,j])(V)(∫_(Subscript[x, k])^(Subscript[x, k+1]))dx(∫_(Subscript[y, l])^(Subscript[y, l+1]))(x^i)(y^j)p(x,y)dy,}})

where (Subscript[ℓ, k,l,i,j])(·):(ℝ^(m⊗n))↦ℝ are linear functions of the tensor V that can be computed once and for all by using the method described in the previous section. In addition, the integrals in the right side of the last identity also can be computed once and for all by using straightforward integration—this is the only place in the procedure where actual integration takes place. Once these calculations are completed, the integral () can be expressed as an explicit linear function of the array V of the form

Flatten[Ω]·Flatten[V]

for some fixed tensor Ω∈(ℝ^(m⊗n)). Of course, the actual calculation of the tensor Ω is much more involved and time consuming than the direct numerical evaluation of the integral () in those instances where f is not a symbolic object, that is, when the symbols (Subscript[v, k,l]) are given concrete numeric values. The point is that the calculation of the tensor Ω is tantamount to writing the integral () as an explicit function of the symbols that define f; that is, we evaluate simultaneously the entire family of integrals for all possible choices of actual numeric values that can be assigned to the symbols (Subscript[v, k,l]). Once the tensor Ω is calculated, we can write

(∫_(-R)^R)dx(∫_(-R)^R)f(x,y)p(x,y)dy=Flatten[Ω]·Flatten[V].

Note that this identity is exact if the abscissas ((Subscript[x, k]),(Subscript[y, l])) are exact numbers. In other words, by computing the tensor Ω we have made a cubature rule. Furthermore, when F(·) is some function defined in the rectangle [-R,R]×[-R,R] that has already been defined and the symbol V is given the numeric values

Table[F(X[[k]],Y[[l]]),{k,1,m},{l,1,n}],

then the right side of equation () differs from the left side by no more than 4(R^2) times the uniform distance between the function F(·) and the interpolating function created from the assignment

((Subscript[x, k]),(Subscript[y, l]))⟶F((Subscript[x, k]),(Subscript[y, l])).

First, we compute—once and for all—all integrals of the form

(∫_(Subscript[x, k])^(Subscript[x, k+1]))dx(∫_(Subscript[y, l])^(Subscript[y, l+1]))(x^i)(y^j)p(x,y)dy

for all choices of 1≤k≤m, 1≤l≤n, 0≤i≤3, and 0≤j≤3, and we represent these integrals as explicit functions of the symbols {(Subscript[x, k]),(Subscript[x, k+1]),(Subscript[y, l]),(Subscript[y, l+1])}.

Instead of calculating the tensor integrals, one may load its (precomputed) value from the files integrals.mx or integrals.txt (if available):

<<"C:/LocalHDlocation/integrals.mx"

or

<<"C:/LocalHDlocation/integrals.txt"

Timing[integrals=Table[Integrate[(x^i)*(y^j)*p[x,y],{x,Xk,Xk1},{y,Yl,Yl1}],{i,0,3},{j,0,3}];]

Next, we replace the symbols {(Subscript[x, k]),(Subscript[x, k+1]),(Subscript[y, l]),(Subscript[y, l+1])} with the actual numeric values of the associated abscissas on the grid:

Timing[WM=Table[integrals/.{Xk->X[[k]],Xk1->X[[k+1]],Yl->Y[[l]],Yl1->Y[[l+1]]},{k,m-1},{l,n-1}];]

Dimensions[WM]

The next step is to create the lists of the midpoints between all neighboring abscissas

Xm=Table[(1/2)*(X[[i]]+X[[i+1]]),{i,1, m-1}];Ym=Table[(1/2)*(Y[[i]]+Y[[i+1]]),{i,1, n-1}];

which would allow us to produce the Taylor expansion of the InterpolatingFunction object f at the points (Xm[[k]],Ym[[l]])∈(ℝ^2), for any 1≤k≤m-1 and any 1≤l≤n-1. As noted earlier, for every choice of k and l, the associated expansion coincides with the object f everywhere in the rectangle

[X[[k]],X[[k+1]]]×[Y[[l]],Y[[l+1]]]⊂(ℝ^2).

Now we will compute the entire expression

(∑_(k=1)^(m-1))(∑_(l=1)^(n-1))((∑_(i,j=0)^3)(Subscript[ℓ, k,l,i,j])(V)(∫_(Subscript[x, k])^(Subscript[x, k+1]))dx(∫_(Subscript[y, l])^(Subscript[y, l+1]))(x^i)(y^j)p(x,y)dy)

as a linear function of the symbols (Subscript[v, k,l]), 1≤k≤m, 1≤l≤n. Note that for every fixed k and l, the third summation simply gives the dot product between the vectors.

Flatten[CoefficientList[Te[f,Xm[[k]],Ym[[l]]],{x,y}]]   and  Flatten[WM[[k,l]]]

It is important to recognize that the sum of these dot products gives the exact value of the integral

(∫_(-R)^R)dx(∫_(-R)^R)f(x,y)p(x,y)dy.

Unfortunately, the exact values of the integrals stored in the list WM are quite cumbersome:

WM[[5,7,3,1]]

Since working with such expressions becomes prohibitively slow, we convert them to floating-point numbers (we can, of course, use any precision that we wish).

Timing[WMN=N[WM,20];]

Note that this last operation is the only source of errors in the integration of the interpolating function f.

Finally, we compute the integral

(∫_(-R)^R)dx(∫_(-R)^R)f(x,y)p(x,y)dy

in symbolic form, that is, as an explicit function of the symbols (Subscript[v, k,l]) that define the interpolating function f—what we are going to compute are the actual numerical values of the coefficients for the symbols (Subscript[v, k,l]) in the linear combination that represents this integral. Consequently, an expression in symbolic form for the integral is nothing but a tensor of actual numeric values. We again stress that the only loss of precision comes from the conversion of the exact numeric values for the integrals stored in WM into the floating-point numbers stored in WMN.

Instead of calculating the object CoeffList in the following, which contains the actual linear combination of the symbols (Subscript[v, i,j]), one may load its (precomputed) value from the files CoeffList.mx or CoeffList.txt (if available):

<<"C:/LocalHDlocation/CoeffList.mx"

or

<<"C:/LocalHDlocation/CoeffList.txt"

Timing[CoeffList=Total[Table[Total[Expand[CoefficientList[Te(f,Xm[[i]],Ym[[j]]),{x,y}] WMN[[i,j]]],2],{i,m-1},{j,n-1}],2];]

Now we extract the numeric values for the coefficients (Subscript[v, k,l]) and store those values in the tensor Ω:

Timing[Ω=Table[Coefficient[CoeffList,(Subscript[v, k,l])],{k,m},{l,n}];]

Note that in order to produce the actual cubature rule we need to compute the tensor Ω only once, so that several minutes of computing time is quite acceptable. Note also that Ω (i.e., the cubature rule) can be calculated with any precision. This means that if we approximate an integral of the form

(∫_(-R)^R)dx(∫_(-R)^R)u(x,y)p(x,y)dy

with the dot product

Flatten[Table[u(X[[i]],Y[[j]]),{i,m},{j,n}]]·Flatten[Ω],

then the upper estimate for the error in this approximation can be made arbitrarily close to the uniform distance between the function u(·,·) and the interpolating function created from the values that u takes on the grid multiplied by the area of the integration domain, which is 4(R^2).

Now we turn to some examples. First, consider the function

u[x_,y_]=(x^2)+(y^2);

and set

V=Table[u[X[[k]],Y[[l]]],{k,m},{l,n}];

Now we have

Flatten[V].Flatten[Ω]

NIntegrate[u[x,y]*(1/(2π))*(E^(-(((x^2)+(y^2))/2))),{x,-R,R},{y,-R,R}]

Abs[%-%%]

For the function

u[x_,y_]=ArcTan[(x^2)*(E^y)];V=Table[u[X[[k]],Y[[l]]],{k,m},{l,n}];

we get

Abs[Flatten[V].Flatten[Ω]-NIntegrate[u[x,y]*(1/(2π))*(E^(-(((x^2)+(y^2))/2))),{x,-R,R},{y,-R,R}]]

One must be aware that NIntegrate is a very efficient procedure and, generally, replacing NIntegrate with a “hand made” cubature rule of the type described in this section may be justified only when the integrand cannot be defined in terms of standard functions, or when a better control of the error is needed, provided that one can control the uniform distance between the integrand and the respective interpolating function created from the grid. In general, such “hand made” cubatures become useful mostly in situations where one has to compute a very large number of integrals for similarly defined integrands—assuming, of course, that the uniform error from the interpolation in all integrands can be controlled (this would be the case, for example, if one has a global bound on a sufficient number of derivatives).

Interpolation quadrature rules for single integrals can be obtained in much the same way. It must be noted that, in general, spline quadrature rules are considerably more straightforward than spline cubature rules. This is because smooth interpolation in (ℝ^1) can be obtained without any additional information about the derivatives at the grid points and this is not the case in spaces of dimension greater than or equal to 2. For example, cubic splines in (ℝ^1) are uniquely determined by the values at the grid points and by the requirement that the second derivative vanishes at the first and last grid points (the so-called natural splines). In contrast, smooth interpolation in two or more dimensions depends on the choice of the gradient and at least one mixed derivative at every grid point, and when information about these quantities is not available—as is often the case—one usually resorts to divided difference interpolation. In general, the efficiency of the interpolation may be increased by using a nonuniform grid and by placing more grid points in the regions where the functions that are being interpolated are more “warped.” We will illustrate this approach in the last section. The use of nonsmooth interpolation, such as bilinear interpolation in (ℝ^2), for example, reduces considerably the computational complexity of the problem. In any case, the error from the interpolation must be controlled in one way or another. While the discussion of this issue is beyond the scope of this article, it should be noted that rather powerful estimates for the interpolation error are well known.

Some Examples of Bilinear Cubature Rules for Gaussian Integrals in (ℝ^2)

In general, just as one would expect, cubature rules based on bilinear interpolation are less accurate than the cubature rules described in the previous section (assuming, of course, one uses the same grid and keeping in mind that this claim is made just in general). However, from a computational point of view, bilinear cubature rules are considerably simpler and easier to implement, especially for more general integrals of the form

∫f(ϕ(x))p(x)dx

for some fixed functions x⟶ϕ(x)Math and x⟶p(x). The greater computational simplicity actually allows one to use a denser grid, which, in many cases, is a reasonable compensation for the loss in smoothness. The dynamic integration procedures in (ℝ^2) that are discussed in the next section are all based on bilinear cubature rules (in the case of (ℝ^1) we will use cubic quadratures).

Here we will be working with the same interpolation grid X[[k]], 1≤k≤m, Y[[l]], 1≤l≤n, that was defined in the previous section and, just as before, in all display formulas will write (Subscript[x, k]) instead of X[[k]] and (Subscript[y, l]) instead of Y[[l]]. Instead of working with the interpolation objects of the form

ListInterpolation[Table[{{X[[k]],Y[[l]]},{(Subscript[v, k,l])}},{k,1,m},{l,1,n}]],

we will work with bilinear interpolation objects that we are going to “construct from scratch” as explicit functions of the variables x and y that depend on the respective grid points and tabulated values. This means that for

(Subscript[x, k])≤x≤(Subscript[x, k+1])and (Subscript[y, l])≤y≤(Subscript[y, l+1]),

the bilinear interpolation object can be expressed as

bi(x,y,X[[k]],X[[k+1]],Y[[l]],Y[[l+1]],(Subscript[v, k,l]),(Subscript[v, k,l+1]),(Subscript[v, k+1,l]),(Subscript[v, k+1,l+1])),

where the function bi is defined as

bi[x_,y_,x1_,x2_,y1_,y2_,V11_,V12_,V21_,V22_]=(1-((x-x1)/(x2-x1)))*(1-((y-y1)/(y2-y1)))*V11+((x-x1)/(x2-x1))*(1-((y-y1)/(y2-y1)))*V21+(1-((x-x1)/(x2-x1)))*((y-y1)/(y2-y1))*V12+((x-x1)/(x2-x1))*((y-y1)/(y2-y1))*V22;

It is clear from this definition that, treated as a function of the variables x and y, the expression bi can be written as

A+B x+C y+D x y,

where the entire list {A,B,C,D} can be treated as a function of the grid points ((Subscript[x, k]),(Subscript[x, k+1]),(Subscript[y, l]),(Subscript[y, l+1])) and the tabulated values ((Subscript[v, k,l]),(Subscript[v, k,l+1]),(Subscript[v, k+1,l]),(Subscript[v, k+1,l+1])). In fact, this function (that is, a list of functions) can be written as

cfbi[x1_,x2_,y1_,y2_,V11_,V12_,V21_,V22_]=CoefficientList[bi[x,y,x1,x2,y1,y2,V11,V12,V21,V22],{x,y}];

For every fixed k and l, the integral of the bilinear interpolating object taken over the rectangle

(Subscript[x, k])≤x≤(Subscript[x, k+1]) and (Subscript[y, l])≤y≤(Subscript[y, l+1])

is simply the dot product between the list {A,B,C,D} and the list of integrals (over the same rectangle) of the functions

(x,y) ⟶ p(x,y), (x,y) ⟶ x p(x,y), 
(x,y) ⟶ y p(x,y), and (x,y) ⟶ x y p(x,y).

Now we will calculate—and store—all these lists (of integrals) of dimension 4 for all choices for 1≤k≤m and for 1≤l≤n:

ip00[a_,b_,c_,d_]=Assuming[a∈ℝ&&b∈ℝ&&c∈ℝ&&d∈ℝ&&a<b&&c<d,Integrate[p[x,y],{x,a,b},{y,c,d}]]

ip10[a_,b_,c_,d_]=Assuming[a∈ℝ&&b∈ℝ&&c∈ℝ&&d∈ℝ&&a<b&&c<d,Integrate[x*p[x,y],{x,a,b},{y,c,d}]]

ip01[a_,b_,c_,d_]=Assuming[a∈ℝ&&b∈ℝ&&c∈ℝ&&d∈ℝ&&a<b&&c<d,Integrate[y*p[x,y],{x,a,b},{y,c,d}]]

ip11[a_,b_,c_,d_]=Assuming[a∈ℝ&&b∈ℝ&&c∈ℝ&&d∈ℝ&&a<b&&c<d,Integrate[x*y*p[x,y],{x,a,b},{y,c,d}]]

Timing[WM2=Table[{ip00[X[[k]],X[[k+1]],Y[[l]],Y[[l+1]]],ip01[X[[k]],X[[k+1]],Y[[l]],Y[[l+1]]],ip10[X[[k]],X[[k+1]],Y[[l]],Y[[l+1]]],ip11[X[[k]],X[[k+1]],Y[[l]],Y[[l+1]]]},{k,m-1},{l,n-1}];]

Timing[WM2N=N[WM2,20];]

and then compute the sum of all dot products:

Timing[loc=Total[Table[(Flatten[cfbi[X[[k]],X[[k+1]],Y[[l]],Y[[l+1]],(Subscript[v, k,l]),(Subscript[v, k,l+1]),(Subscript[v, l+1,k]),(Subscript[v, k+1,l+1])]].WM2N[[k,l]])//Simplify,{k,m-1},{l,n-1}],2];]

This sum is a linear function of the symbols (Subscript[v, k,l]), and this linear function represents the integral of the interpolating function f(·) over the entire interpolation region (each dot product gives the integral of f(·) in the respective sub-region). Finally, we must extract the coefficients for the symbols (Subscript[ν, k,l]) from the linear combination (of those symbols) that we just obtained.

Timing[Θ=Table[(∂_(Subscript[v, k,l]))(loc),{k,m},{l,n}];]

Now we can use the tensor Θ in the same way in which we used the tensor Ω in the previous section: although Θ contains concrete numeric values, this tensor still has the meaning of “integral of f(·) in symbolic form.” For example, if we set

u[x_,y_]=(E^(0.1x y));

then we obtain

Timing[V=Table[u[X[[k]],Y[[l]]],{k,m},{l,n}];Flatten[V].Flatten[Θ]]

which is reasonably close to

NIntegrate[u[x,y]*(1/(2π))*(E^(-(((x^2)+(y^2))/2))),{x,-R,R},{y,-R,R}]//Timing

In this case, the cubic cubature rule is considerably more accurate:

Timing[V=Table[u[X[[k]],Y[[l]]],{k,m},{l,m}];Flatten[V].Flatten[Ω]]

Here is another example.

u[x_,y_]=Max[R-Min[x+R,y+R],0];

This function is nonsmooth, as the following 3D plot shows.

Plot3D[u[x,y],{x,-R,R},{y,-R,R},PlotPoints->150,Mesh->False,PlotRange->All]

Timing[V=Table[u[X[[k]],Y[[l]]],{k,m},{l,n}];Flatten[V].Flatten[Θ]]

Timing[V=Table[u[X[[k]],Y[[l]]],{k,m},{l,n}];Flatten[V].Flatten[Ω]]

NIntegrate[u[x,y]*(1/(2π))*(E^(-(((x^2)+(y^2))/2))),{x,-R,R},{y,-R,R}]//Timing

Abs[{%[[2]]-%%[[2]],%[[2]]-%%%[[2]]}]

Finally, we remark that—at least in principle—the procedures developed in this and in the previous sections may be used with any other, that is, nonGaussian, probability density p(·), including nonsmooth densities.

Application to Optimal Stopping Problems and Option Pricing

The main objective in this section is to revisit the method of dynamic interpolation and integration described in [] and to present a considerably more efficient implementation of this method, which takes advantage of the fact that the objects that are being integrated sequentially are actually interpolating functions. More importantly, we will show how to implement this method in the case of optimal stopping problems for certain diffusions in (ℝ^2). Essentially, this section is about the actual implementation in Mathematica of the method encoded in the space-discretized version of the time-discrete dynamic programming equation (). The solution is approximated in terms of dynamic cubature rules of the form () by using the procedure encoded in equation (). For the sake of simplicity, the examples presented in this section will be confined to the case where the (diffusion type) observation process (Subscript[((Subscript[X, t])), t ≥ 0]) is computable, in the sense that for any fixed T≥ t≥0, the random variable (Subscript[X, T]) can be expressed as

(Subscript[X, T])=(Subscript[ψ, T-t])((Subscript[X, t]),(Subscript[W, T])-(Subscript[W, t]))

for some computable function (Subscript[ψ, T-t]):(ℝ^N)×(ℝ^N)↦(ℝ^N) (note that the position of the diffusion process at time t, (Subscript[X, t]), is independent of the future increment of the Brownian motion (Subscript[W, T])-(Subscript[W, t])). In other words, the conditional law of (Subscript[X, T]) given the event {(Subscript[X, T])=x} can be identified with the distribution law of a random variable of the form

(Subscript[ψ, T-t])(x,(Sqrt[T-t]) Γ),

where Γ is a standard normal (ℝ^N)-valued random variable. Of course, when (Subscript[((Subscript[X, t])), t ≥ 0]) is computable in the sense that we just described, then there is no need to use the approximation (), and, if (Subscript[((Subscript[X, t])), t ≥ 0]) is not computable, in principle at least, the procedures described in this section can still be used, provided that the definition of the function (Subscript[ψ, T-t])(·,·) is changed according to the recipe ().

We note that the Mathematica code included in this section is independent of the code included in all previous sections.

To begin with, define the following symmetric probability density function in (ℝ^2).

p(x_,y_)=(1/(2π))*(E^(-(((x^2)+(y^2))/2)));

This is nothing but the probability density of a bivariate normal random variable (X,Y)∈(ℝ^2), with standard normal marginals X and Y and with correlation Ε[X Y]=0. Let (Subscript[W, t]), t≥0, and (Subscript[B, t]), t≥0, be two standard Brownian motions that are independent, so that Ε[(Subscript[W, t])(Subscript[B, t])]=0 for any t≥0. Next, for some fixed σ>0 and for (x,y)∈(ℝ^2), set (Subscript[a, t]^x)=x (e^(σ (Subscript[W, t]))) and (Subscript[b, t]^y)=y (e^(σ (Subscript[B, t]))) for any t≥0. Note that the joint distribution law of ((Subscript[a, t]^x),(Subscript[b, t]^y)) is the same as the joint distribution law of (x (e^(σ (Sqrt[t]) X)),y (e^(σ (Sqrt[t]) Y))). It is a trivial matter to check that

(SubPlus[ℝ])∋t⟶((Subscript[a, t]^x),(Subscript[b, t]^y))∈(ℝ^2)

is a diffusion process in (ℝ^2) with generator

ℒ=((σ^2)/2)((x^2)(∂_(x,x))+(y^2)(∂_(y,y))).

In what follows, we study the problem for optimal stopping of the process (Subscript[((Subscript[a, t]^x),(Subscript[b, t]^y)), t ≥ 0]) no later than time T>0, for a given termination payoff Λ:(Subscript[ℝ, +]^2)↦ℝ. For the sake of simplicity, we will suppose that the discount rate for future payoffs is 0. In the special case where Λ(x,y)=λ(x), x≥0, for some “sufficiently nice” function of one variable λ:(SubPlus[ℝ])↦ℝ, the problem comes down to the optimal stopping of the one-dimensional diffusion (Subscript[((Subscript[a, t]^x)), t ≥ 0]). We analyze this one-dimensional case first.

𝒩(ξ_)=(1/(Sqrt[2 π]))(E^(-((ξ^2)/2)));

σ=0.3;

The time step in the procedure, that is, the quantity (T/v), is set to

t=.05;

Next, define the interpolation grid:

X=Join[Table[x//N,{x,2,32,2}],Table[x//N,{x,34,42,2}],Table[x//N,{x,44,80,4}],{90,100},Table[x//N,{x,120,200,20}]];m=Length[X]; XX=Join[{$MachineEpsilon},X,{300,400}];Xm=Table[(1/2)*( XX[[k]]+ XX[[k+1]]),{k,1, m+2}];

Just as before, in all display equations we will write (Subscript[x, k]) instead of X[[k]] and (Subscript[(OverBar[x]), k]) instead of XX[[k]]. The boundary conditions will be prescribed at the first and last two abscissas on the extended grid XX. This means that the recursive procedure will update only the values on the grid X. Thus, the procedure that we develop can be applied only to situations where the value function does not change at those points in the state-space that are either close to 0 or happen to be very large.

The next step is to define the list of tabulated symbols

vrsb=Array[(Subscript[b, #1])&,{m+3}];

and the associated (symbolic) InterpolatingFunction object

g=ListInterpolation[Table[{ XX[[k]],{vrsb[[k]]}},{k,1,m+3}]];

Next, extract the coefficients of the cubic polynomials that represent the object g between the interpolation nodes.

te[ff_,x0_]:=Sum[(1/((i!)))*Derivative[i][ff](x0)*(((x-x0))^i),{i,0,3}];

m0loc=Table[CoefficientList[te[g,Xm[[k]]],{x}]//Simplify,{k,m+2}];

For example,

m0loc[[1,1]]//Chop

which means that for (Subscript[(OverBar[x]), 1])≤x≤(Subscript[(OverBar[x]), 2]), the expression g[x] can be identified with the polynomial

{1,x,(x^2),(x^3)}.m0loc[[1,1]]

Next, note that the relation

(Subscript[(OverBar[x]), k])≤(Subscript[x, ξ]) (e^(σ(Sqrt[t])x))≤(Subscript[(OverBar[x]), k+1])

is equivalent to

L(ξ,k)≡(1/(σ(Sqrt[t])))log(((Subscript[(OverBar[x]), k])/(Subscript[x, ξ])))≤x≤(1/(σ(Sqrt[t])))log((( (Subscript[(OverBar[x]), k+1]))/(Subscript[x, ξ])))≡L(ξ,k+1).

For every fixed ξ=1,… ,m, we will compute all integrals

(∫_(L(ξ,k))^(L(ξ,k+1)))(e^( (i-1) σ(Sqrt[t]) x)) 𝒩(x)dx, 1≤i≤4, 1≤k≤m+2,

and will store these integrals in the matrix (initially filled with zeros):

wl=Table[(Table[0,{i,0,3}]),{k,1,m+2}];

In particular, the integral

(∫_(L(ξ,k))^(L(ξ,k+1)))g((Subscript[x, ξ])(e^(σ (Sqrt[t])x))) 𝒩(x)dx

can be replaced by

({1,(Subscript[x, ξ]),(Subscript[x, ξ]^2),(Subscript[x, ξ]^3)}·(m0loc[[k,1]] wl[[k]])),

and we remark that

m0loc[[k,1]] wl[[k]]≡(∑_(i=1)^4)m0loc[[k,i]] wl[[k,i]].

The entire expression

(∫_(L[ξ,1])^(L[ξ,m+3]))g[(Subscript[x, ξ]) (e^(σ (Sqrt[t]) x))] 𝒩[x]dx=(∑_(k=1)^(m+2)){1,(Subscript[x, ξ]),(Subscript[x, ξ]^2),(Subscript[x, ξ]^3)}.(m0loc[[k,1]] wl[[k]])

then becomes a linear function of the symbols {(Subscript[b, 1]),… ,(Subscript[b, m+3])}. This linear function (i.e., vector of dimension m+3) depends on the index ξ and represents a quadrature rule for the integral in the left side in the last identity. We stress that we need one such rule for every abscissa (Subscript[x, ξ]), 1≤ξ≤m. We will store all these rules (i.e., vectors of dimension m+3) in the tensor (initially filled with zeroes):

ω=Table[Table[0,{k,1,m+3}],{ξ,1,m}];

Clear[ll,ul];locInt=Table[Integrate[(E^((i-1)*σ*(Sqrt[t])*x))* 𝒩(x),{x,ll,ul}]//Simplify,{i,1,4}];

Do[(Do[Do[(wl[[k,i]]=N[(locInt[[i]]/.{ll->(1/(σ*(Sqrt[t])))*Log[(( XX[[k]])/(X[[ξ]]))],ul->(1/(σ*(Sqrt[t])))*Log[(( XX[[k+1]])/(X[[ξ]]))]})]),{i,1,4}],{k,m+2}];lcls=Sum[({1,X[[ξ]],((X[[ξ]])^2),((X[[ξ]])^3)}.(m0loc[[k,1]]*wl[[k]])//Simplify),{k,m+2}];ω[[ξ]]=Table[(∂_(Subscript[b, k]))(lcls),{k,m+3}];),{ξ,m}]//Timing

As a first application, we compute the price of an American put option with payoff:

Λ[x_]=Max[40- x,0]

The first iteration will be done by using a direct numerical integration—not interpolation quadrature rules.

Timing[V1=Table[{Max[Λ[XX[[k]]],NIntegrate[Λ[XX[[k]]*(E^(σ*(Sqrt[t])*x))]* 𝒩(x),{x,-∞,(1/(σ*(Sqrt[t])))Log[(40/(XX[[k]]))]},MaxRecursion->10,AccuracyGoal->16,SingularityDepth->10]]},{k,1,m+3}];]

Now we will do 19 additional iterations by using interpolation quadratures. The time step is t=0.05 years. This will give us the approximate price of an American put with strike price 40 and one year left to expiry. Note that the list ω[[k]] gives the integral associated with the abscissa (Subscript[x, k]), which is the same as (Subscript[(OverBar[x]), k+1]) for 1≤k≤m. The idea is to keep the value at the abscissa (Subscript[(OverBar[x]), 1]) fixed, throughout the iterations, equal to the initial value 40 and, similarly, keep the values at the abscissas (Subscript[(OverBar[x]), m+2]) and (Subscript[(OverBar[x]), m+3]) forever fixed at the initial values 0 and 0.

K=V1;VL=K;

Timing[Do[(Do[VL[[k+1]]={Max[Λ[ XX[[k+1]]],Flatten[K].ω[[k]]]},{k,m}];K=VL),{19}];]

Note that the first iteration took about 20 times longer to compute than the remaining 19. Now we define the value function after 20 iterations—this is nothing but the option price with one year left to maturity treated as a function defined on the entire range of observable stock prices.

f=ListInterpolation[Table[{ XX[[k]],K[[k]]},{k,1,m+3}]];

We plot the value function f(·) together with the termination payoff Λ(·).

Plot[{f[x],Λ[x]},{x,0,120},PlotRange->All,PlotPoints->150,PlotStyle->{Hue[0.],Hue[0.7]}]

The range of abscissas at which the value function and the termination payoff coincide is precisely the price range where immediate exercise of the option is optimal, assuming that there is exactly one year left to expiry.

Now we consider the same optimal stopping problem but with a smooth payoff function, namely

Λ[x_]=(1/100)(x^2)*(1/40)(((Max[40-x,0]))^2);

Essentially, this is an example of some sort of a generalized obstacle problem.

Plot[Λ[x],{x,0,60},PlotRange->All]

In this case, there is no need to perform the first iteration by using direct numerical integration.

Timing[V1=Table[{Λ[ XX[[k]]]},{k,1,m+3}];]

Now we perform 60 iterations, which will give us the value function with three years left to the termination deadline.

K=V1;VL=K;

Timing[Do[(Do[VL[[k+1]]={Max[Λ[ XX[[k+1]]],Flatten[K].ω[[k]]]},{k,1,m}];K=VL),{60}];]

f=ListInterpolation[Table[{ XX[[k]],K[[k]]},{k,1,m+3}]];

Plot[{f[x],Λ[x]},{x,0,120},PlotRange->All,PlotStyle->{Hue[0.],Hue[0.7]}]

The most common approach to dynamic programing problems of this type is to use the free boundary problem formulation, followed by some suitable variation of the finite difference scheme. However, such an approach is much less straightforward and usually takes much longer to compute—a fraction of a second would be very hard to imagine even on a very powerful computer. In fact, we could double the number of the interpolation nodes and cut the time step in half, which would roughly quadruple the timing, and still complete the calculation within one second.

It is important to point out that, in terms of the previous procedure, there is nothing special about the standard normal density. In fact, we could have used just about any other reasonably behaved probability density function 𝒩(·)—as long as the associated integrals are computable. In particular, one can use this procedure in the context of financial models in which the pricing process is driven by some nonwhite noise process, including a noise process with jumps. The only requirement is that we must be able to compute the integrals

(∫_(L(ξ,k))^(L(ξ,k+1)))(e^( (i-1) σ (Sqrt[t]) x)) 𝒩(x)dx, 1≤i≤4, 1≤k≤m+2,

for any ξ=1,… ,m.

Finally, we consider the two-dimensional case. We use the same grid-points on both axes:

Y=X;n=Length[Y]; YY= XX;

Although the lists Y and YY are the same as X and XX, in the notation that we use we will pretend that these lists might be different and will write (Subscript[y, k]) instead of Y[[k]], (Subscript[(OverBar[y]), k]) instead of YY[[k]], and set

M(η,l)≡(1/(σ(Sqrt[t])))log(((Subscript[(OverBar[y]), l])/(Subscript[y, η]))).

We will use bilinear cubature rules, which are easier to implement—we need one such rule for every point ((Subscript[x, ξ]),(Subscript[y, η])), 1≤ξ≤m, 1≤η≤n. Thus, we must compute all integrals

(∫_(L(ξ,k))^(L(ξ,k+1)))dx(∫_(M(η,l))^(M(η,l+1)))(e^( (i-1) σ (Sqrt[t]) x + (j-1) σ (Sqrt[t]) y))p(x,y) dy

for i,j=1,2, for 1≤k≤m+2, for 1≤l≤n+2, for 1≤ξ≤m, and for ξ≤η≤n (because of the symmetry in the density p(·), it is enough to consider only the case η≥ξ). Now we need to operate with substantially larger lists of data and for that reason we need to organize the Mathematica code differently.

Assuming that (x,y)⟶f(x,y) is an interpolating function constructed by way of bilinear interpolation from the tabulated symbols

(Subscript[a, k,l])≡f((Subscript[(OverBar[x]), k]),(Subscript[(OverBar[y]), l])), 1≤k≤m+3, 1≤l≤n+3,

we can express each of the integrals

(∫_(L(ξ,k))^(L(ξ,k+1)))dx(∫_(M(η,l))^(M(η,l+1)))f((Subscript[x, ξ])(e^( σ (Sqrt[t]) x )),(Subscript[y, η])(e^( σ (Sqrt[t]) y)))p(x,y)dy

in the form

{1,(Subscript[x, ξ])}.(Subscript[A, ξ,η,k,l]).{1,(Subscript[y, η])},

where (Subscript[A, ξ,η,k,l]) is the 2×2 matrix given by (here we use the definition of cfbi from the previous section)

(Subscript[A, ξ,η,k,l])=cfbi[(Subscript[(OverBar[x]), k]),(Subscript[(OverBar[x]), k+1]),(Subscript[(OverBar[y]), l]),(Subscript[(OverBar[y]), l+1]),(Subscript[a, k,l]),(Subscript[a, k,l+1]),(Subscript[a, k+1,l]),(Subscript[a, k+1,l+1])]*locIntegrals,

and locIntegrals is the 2×2 matrix of the integrals () indexed by 1≤i,j≤2 (i is the first index and j is the second). In fact, with our special choice for the bi-variate density p(x,y), all these integrals can be calculated in closed form:

Clear[σ,t,x,y,lx,Lx,ly,Ly]

i=1;j=1;Integrate[(E^( (i-1) σ (Sqrt[t]) x + (j-1) σ (Sqrt[t]) y))*p(x,y),{x,lx,Lx},{y,ly,Ly}]

i=2;j=1;Integrate[(E^( (i-1) σ (Sqrt[t]) x + (j-1) σ (Sqrt[t]) y))*p(x,y),{x,lx,Lx},{y,ly,Ly}]

i=1;j=2;Integrate[(E^( (i-1) σ (Sqrt[t]) x + (j-1) σ (Sqrt[t]) y))*p(x,y),{x,lx,Lx},{y,ly,Ly}]

i=2;j=2;Integrate[(E^( (i-1) σ (Sqrt[t]) x + (j-1) σ (Sqrt[t]) y))*p(x,y),{x,lx,Lx},{y,ly,Ly}]

After fixing the values for the volatility σ and the time step t

Clear[i,j];σ=0.3;t=.05;

the integrals can be written as explicit functions of the integration limits:

cip11=Compile[{{lx, _Real},{Lx, _Real},{ly, _Real},{Ly, _Real}},(1/4)* (erf((lx/(Sqrt[2])))-erf((Lx/(Sqrt[2])))) *(erf((ly/(Sqrt[2])))-erf((Ly/(Sqrt[2]))))];

cip21=Compile[{{lx, _Real},{Lx, _Real},{ly, _Real},{Ly, _Real}},(1/4) *(E^((t (σ^2))/2)) *(erf((ly/(Sqrt[2])))-erf((Ly/(Sqrt[2]))))*(erf(((lx-(Sqrt[t]) σ)/(Sqrt[2])))-erf(((Lx-(Sqrt[t]) σ)/(Sqrt[2]))))];

cip12=Compile[{{lx, _Real},{Lx, _Real},{ly, _Real},{Ly, _Real}},(1/4) *(E^((t (σ^2))/2))* (erf((lx/(Sqrt[2])))-erf((Lx/(Sqrt[2]))))*(erf(((ly-(Sqrt[t]) σ)/(Sqrt[2])))-erf(((Ly-(Sqrt[t]) σ)/(Sqrt[2]))))];

cip22=Compile[{{lx, _Real},{Lx, _Real},{ly, _Real},{Ly, _Real}},(1/4) *(E^(t (σ^2))) *(erf(((lx-(Sqrt[t]) σ)/(Sqrt[2])))-erf(((Lx-(Sqrt[t]) σ)/(Sqrt[2])))) *(erf(((ly-(Sqrt[t]) σ)/(Sqrt[2])))-erf(((Ly-(Sqrt[t]) σ)/(Sqrt[2]))))];

Our method depends in a crucial way on the fact that {1,X[[ξ]]}.(Subscript[A, ξ,η,k,l]).{1,Y[[η]]} is actually a linear function of the symbols {(Subscript[a, k,l]),(Subscript[a, k,l+1]),(Subscript[a, k+1,l]),(Subscript[a, k+1,l+1])}. In fact, we can compute the coefficients in this linear combination explicitly, as we now demonstrate.

Clear[x1,x2,y1,y2,xx,yy,a,b,c,d,C11,C12,C21,C22]

locIntegrals={{C11,C12},{C21,C22}}

The next two definitions are taken from the previous section, so that the code included in this section can be self-contained.

bi[x_,y_,x1_,x2_,y1_,y2_,V11_,V12_,V21_,V22_]=(1-((x-x1)/(x2-x1)))*(1-((y-y1)/(y2-y1)))*V11+((x-x1)/(x2-x1))*(1-((y-y1)/(y2-y1)))*V21+(1-((x-x1)/(x2-x1)))*((y-y1)/(y2-y1))*V12+((x-x1)/(x2-x1))*((y-y1)/(y2-y1))*V22;

cfbi[x1_,x2_,y1_,y2_,V11_,V12_,V21_,V22_]=CoefficientList[bi[x,y,x1,x2,y1,y2,V11,V12,V21,V22],{x,y}];

Coefficient[{1,xx}.(cfbi[ x1, x2, y1, y2,a,b,c,d]*locIntegrals).{1,yy},a]//Simplify

Coefficient[{1,xx}.(cfbi[ x1, x2, y1, y2,a,b,c,d]*locIntegrals).{1,yy},b]//Simplify

Coefficient[{1,xx}.(cfbi[ x1, x2, y1, y2,a,b,c,d]*locIntegrals).{1,yy},c]//Simplify

Coefficient[{1,xx}.(cfbi[ x1, x2, y1, y2,a,b,c,d]*locIntegrals).{1,yy},d]//Simplify

Thus, the entire integral

(∫_(L(ξ,1))^(L(ξ,m+3)))dx(∫_(M(η,1))^(M(η,n+3)))f(X[[ξ]](e^( σ (Sqrt[t]) x )),Y[[η]](e^( σ (Sqrt[t]) y)))p(x,y)dy

can be treated as a linear function of the symbols

{(Subscript[a, k,l]); 1≤k≤m+3,1≤l≤n+3}.

This linear function is nothing but a tensor of dimension (m+3)×(n+3) and this tensor is nothing but a cubature rule for the integral (), which, obviously, depends on the indices ξ and η. Consequently, we have one such cubature rule (tensor) for every choice of ξ=1,… ,m and every choice of η=ξ,… ,n, and all such rules will be stored in the tensor (initially filled with zeros):

Ξ=Table[Table[0,{k,m+3},{l,n+3}],{ξ,m},{η,ξ,n}];

The calculation of the tensor Ξ is the key step in the implementation of the method of dynamic interpolation and integration in dimension 2. This is the place where we must face the “curse of the dimension.” It is no longer efficient to express the global integral () as the sum of local integrals of the form () and then extract from the sum the coefficients for the symbols (Subscript[a, k,l]). It turns out to be much faster if one updates the coefficients for the symbols (Subscript[a, k,l]) sequentially, as the local integrals in () are calculated one by one. Just as one would expect, dealing with the boundary conditions in higher dimensions is also trickier. Throughout the dynamic integration procedure we will be updating the values of the value function at the grid points ((Subscript[x, ξ]),(Subscript[y, η])), 1≤ξ≤m, 1≤η≤n, or, which amounts to the same, the grid points ((Subscript[(OverBar[x]), k]),(Subscript[(OverBar[y]), l])), 2≤k≤m+1, 2≤η≤n+1. The values on the remaining grid points ((Subscript[(OverBar[x]), k]),(Subscript[(OverBar[y]), l])) with k=1, or k=m+2, or k=m+3, or l=1, or l=n+2, or l=n+3, will be kept unchanged, or, depending on the nature of the problem, will be updated according to some other—one-dimensional, perhaps—dynamic quadrature rule.

Now we turn to the actual computation of the tensor Ξ. On a single “generic” processor, this task takes about (1/2) hour (if more processors are available the task can be distributed between several different Mathematica kernels in a trivial way). The key point is that this is a calculation that we do once and for all. As will be illustrated shortly, once the tensor Ξ is calculated, a whole slew of optimal stopping problems can be solved within seconds. Of course, the “slew of optimal stopping problems” is limited to the ones where the termination payoff and the value functions obtained throughout the dynamic integration can be approximated reasonably well by way of bilinear interpolation from the same interpolation grid. In general, the set of these “quickly solvable” problems can be increased by choosing a denser grid and/or a grid that covers a larger area. However, doing so may become quite expensive. For example, if we were to double the number of grid points in each coordinate, the computing time for the tensor Ξ would increase roughly 16 times—again, everything is easily parallelizable.

It is important to recognize that the calculation of the list Ξ involves only the evaluation of standard functions and accessing the elements of a fairly large tensor (Ξ has a total of 1,245,621 entries). This is close to the “minimal number of calculations” that one may expect to get away with: if the number of discrete data from which the value function can be restored with a reasonable degree of accuracy is fairly large, then there is a fairly large number of values that will have to be calculated no matter what. Furthermore, the evaluation of standard functions is very close to the fastest numerical procedure that one may hope to get away with in this situation. From an algorithmic point of view, the efficiency of this procedure can be improved in two ways: (1) find a new way to encrypt the value function with fewer discrete values; and/or (2) represent all functions involved in the procedure (i.e., all combinations of standard functions) in a form that allows for an even faster evaluation. In terms of hardware, the speed of the procedure depends not only on the speed of the processor but also on the speed and the organization of the memory.

Instead of calculating the list Ξ, one may load its (precomputed) value from the files Xi.mx or Xi.txt (if available):

<<"C:/LocalHDlocation/Xi.mx"

or

<<"C:/LocalHDlocation/Xi.txt"

Timing[Do[xx=X[[ξ]];yy=Y[[η]];(Do[(lx=(1/(σ*(Sqrt[t])))*Log[(( XX[[k]])/(X[[ξ]]))];Lx=(1/(σ*(Sqrt[t])))*Log[(( XX[[k+1]])/(X[[ξ]]))];x1=XX[[k]];x2=XX[[k+1]];Do[(ly=(1/(σ*(Sqrt[t])))*Log[(( YY[[l]])/(Y[[η]]))];Ly=(1/(σ*(Sqrt[t])))*Log[(( YY[[l+1]])/(Y[[η]]))];y1=YY[[l]];y2=YY[[l+1]];C11=cip11[lx,Lx,ly,Ly];C12=cip12[lx,Lx,ly,Ly];C21=cip21[lx,Lx,ly,Ly];C22=cip22[lx,Lx,ly,Ly];Ξ[[ξ,η-ξ+1,k,l]]=Ξ[[ξ,η-ξ+1,k,l]]+((C11 x2 y2-C21 xx y2-C12 x2 yy+C22 xx yy)/((x1-x2) (y1-y2)));Ξ[[ξ,η-ξ+1,k,l+1]]=Ξ[[ξ,η-ξ+1,k,l+1]]+((-C11 x2 y1+C21 xx y1+C12 x2 yy-C22 xx yy)/((x1-x2) (y1-y2)));Ξ[[ξ,η-ξ+1,k+1,l]]=Ξ[[ξ,η-ξ+1,k+1,l]]+((-C11 x1 y2+C21 xx y2+C12 x1 yy-C22 xx yy)/((x1-x2) (y1-y2)));Ξ[[ξ,η-ξ+1,k+1,l+1]]=Ξ[[ξ,η-ξ+1,k+1,l+1]]+((C11 x1 y1-C21 xx y1-C12 x1 yy+C22 xx yy)/((x1-x2) (y1-y2)));),{l,n+2}]),{k,m+2}];),{ξ,1,m},{η,ξ,n}];]

Now we can turn to some concrete applications. First, we will consider an American put option with strike price 40 on the choice of one of two uncorrelated assets (the owner of the option can choose one of the two assets when the option is exercised). The termination payoff from this option is

Λ[x_,y_]=Max[40-Min[x,y],0];

Plot3D[Λ[x,y],{x,0,120},{y,0,120},PlotPoints->250,Mesh->False,PlotRange->All]

The two underlying assets are uncorrelated and follow the processes (Subscript[x, 0])(e^(σ (Subscript[W, t]))), t≥0, and (Subscript[y, 0])(e^(σ (Subscript[B, t]))), t≥0, where B and W are the Brownian motions described earlier in this section. Let (x,y)⟶(Subscript[f, t])(x,y) be the value function with t years left to expiry, that is, if the time left to expiry is t years and the prices of the two assets are, respectively, x∈(SubPlus[ℝ]) and y∈(SubPlus[ℝ]), then the value of the option is (Subscript[f, t])(x,y)∈(SubPlus[ℝ]) and we remark that what is meant here as “the value of the option” is actually a function defined on the entire range of prices, that is, the range of prices covered by the interpolation grid. Clearly, we must have (Subscript[f, t])(x,0)=(Subscript[f, t])(0,y)=40. Furthermore, when one of the assets has a very large value, then the option is very close to a canonical American put option on the other asset. Consequently, the values at the grid points ((Subscript[(OverBar[x]), k]),(Subscript[(OverBar[y]), l])), where k=1 or l=1, will never be updated and will remain forever fixed at the initial value 40. When k is fixed to either k=m+2 or k=m+3, the values at the grid points ((Subscript[(OverBar[x]), k]),(Subscript[(OverBar[y]), l])), 1≤l≤n+3, will be updated exactly as we did earlier in the case of an American put on a single asset with a strike price 40. Similarly, when l is fixed to either l=n+2 or l=m+3, the values at the grid points ((Subscript[(OverBar[x]), k]),(Subscript[(OverBar[y]), l])), 1≤k≤m+3, will be updated in the same way, that is, as if we were dealing with an American put on a single asset with strike price 40. Of course, since the payoff is symmetric and so is the density p(·,·), we only need to update the values at the grid points ((Subscript[(OverBar[x]), k]),(Subscript[(OverBar[y]), l])) for k=1,… ,m+3 and l=k,… ,n+3.

Now we turn to the actual calculation. By using the method of dynamic integration of interpolating functions, we will compute—approximately—the pricing function (x,y)⟶(Subscript[f, 1])(x,y) that maps the prices of the underlying assets in the range covered by the grid into the price of the option with one year left to maturity. With time step t=0.05, we need to perform 20 iterations in the dynamic integration procedure. Note that if we choose to perform the first iteration by direct numerical integration of the termination payoff, then that would require the calculation of 741 integrals.

We initialize the procedure by tabulating the termination payoff over the interpolation grid.

Timing[V3=Table[Λ[ XX[[k]], YY[[l]]],{k,1,m+3},{l,1,n+3}];]

K=V3;VL=K;

Then we do 20 iterations—at each iteration we update the tensor VL:

Timing[Do[(Do[(VL[[ξ+1,η+1]]={Max[Λ[ XX[[ξ+1]], YY[[η+1]]],Flatten[Ξ[[ξ,η-ξ+1]]].Flatten[K]]}),{ξ,m},{η,ξ,n}];Do[VL[[k+1,n+2]]={Max[Max[40- XX[[k+1]],0],Flatten[K[[All,n+2]]].ω[[k]]]},{k,m}];Do[VL[[k+1,n+3]]={Max[Max[40- XX[[k+1]],0],Flatten[K[[All,n+3]]].ω[[k]]]},{k,m}];Do[(VL[[ξ,η]]=VL[[η,ξ]]),{ξ,2,m+3},{η,ξ-1}];K=VL),{20}];]

Now we can produce the pricing map with one year left to maturity.

floc=ListInterpolation[Table[{ {XX[[k]], YY[[l]]},{VL[[k,l]]}},{k,1,m+3},{l,1,n+3}]];

Plot3D[floc[x,y],{x,0,120},{y,0,120},PlotPoints->250,Mesh->False,PlotRange->All]

Calculating the derivatives of the value function (treated as functions, too) is straightforward as we now illustrate, and before we do we remark that in the realm of finance, information about these derivatives (known as the deltas of the option) is often more important than the pricing function itself.

Plot3D[Derivative[1,0][floc](x,y),{x,0,80},{y,0,80},PlotPoints->250,Mesh->False,PlotRange->All]

In our second example, we consider an American put option on the more expensive of two given underlying assets (in contrast, in our previous example we dealt with an American put option on the less expensive of the two underlying assets). In this case, the termination payoff function is given by

Λ[x_,y_]=Max[40-Max[x,y],0];

Plot3D[Λ[x,y],{x,0,120},{y,0,120},PlotPoints->250,Mesh->False,PlotRange->All]

This time the boundary conditions must take into account the fact that when one of the assets becomes too expensive, the option becomes worthless, and when one of the assets is worthless, the option may be treated as a standard American option on the other asset. For the purpose of illustration we will compute the value of the option with three years left to maturity.

Timing[V4=Table[Λ[ XX[[k]], YY[[l]]],{k,1,m+3},{l,1,n+3}];]

K=V4;VL=K;

Timing[Do[(Do[(VL[[ξ+1,η+1]]={Max[Λ[ XX[[ξ+1]], YY[[η+1]]],Flatten[Ξ[[ξ,η-ξ+1]]].Flatten[K]]}),{ξ,m},{η,ξ,n}];Do[VL[[1,k+1]]={Max[Max[40- YY[[k+1]],0],Flatten[K[[1,All]]].ω[[k]]]},{k,m}];Do[VL[[k+1,n+2]]={0},{k,m}];Do[VL[[k+1,n+3]]={0},{k,m}];Do[(VL[[ξ,η]]=VL[[η,ξ]]),{ξ,2,m+3},{η,ξ-1}];K=VL),{60}];]

floc=ListInterpolation[Table[{{XX[[k]], YY[[l]]},{VL[[k,l]]}},{k,1,m+3},{l,1,n+3}]];

Plot3D[floc[x,y],{x,0,120},{y,0,120},PlotPoints->250,Mesh->False,PlotRange->All]

This is a good example of a value function which is neither everywhere smooth nor convex.

In our final example we consider optimal stopping of the same diffusion in (ℝ^2) but with smooth termination payoff of the form

λ[x_]=(1/100)(x^2)*(1/40)(((Max[40-x,0]))^2);Λ[x_,y_]=(1/40)λ[x]*λ[y];

Plot3D[Λ[x,y],{x,0,120},{y,0,120},PlotPoints->250,Mesh->False,PlotRange->All]

With this termination payoff the boundary conditions must reflect the fact that the option is worthless when one of the assets is worthless or when one of the assets is too expensive. We will execute 60 iterations, which will give us the value function with three years left to expiry.

Timing[V5=Table[Λ[ XX[[k]], YY[[l]]],{k,1,m+3},{l,1,n+3}];]

K=V5;VL=K;

Timing[Do[(Do[(VL[[ξ+1,η+1]]={Max[Λ[ XX[[ξ+1]], YY[[η+1]]],Flatten[Ξ[[ξ,η-ξ+1]]].Flatten[K]]}),{ξ,m},{η,ξ,n}];Do[VL[[1,k+1]]={0},{k,m}];Do[VL[[k+1,n+2]]={0},{k,m}];Do[VL[[k+1,n+3]]={0},{k,m}];Do[(VL[[ξ,η]]=VL[[η,ξ]]),{ξ,2,m+3},{η,ξ-1}];K=VL),{60}];]

floc=ListInterpolation[Table[{{XX[[k]],YY[[l]]},{VL[[k,l]]}},{k,1,m+3},{l,1,n+3}]];

Plot3D[floc[x,y],{x,0,120},{y,0,120},PlotPoints->250,Mesh->False,PlotRange->All]

Conclusions

Most man-made computing devices can operate only with finite lists of numbers or symbols. Any use of such devices for modeling, analysis, and optimal control of stochastic systems inevitably involves the encoding of inherently complex phenomena in terms of finite lists of numbers or symbols. Thus one can think of two general directions that may lead to expanding the realm of computable models. First, one may try to construct computing devices that can handle larger and larger lists, faster and faster. Second, one may try to develop “smarter” procedures with which more complex objects can be encrypted with shorter lists of numbers. With this general direction in mind, the methodology developed in this article is entirely logical and natural. Indeed, the approximation of functions with splines or other types of interpolating functions is a familiar, well developed, and entirely natural computing tool. The use of special quadrature/cubature rules—as opposed to general methods for numerical integration—in the context of dynamic integration of interpolating functions is just as logical and natural. However, only recently have computer languages in which one can implement such procedures in a relatively simple and straightforward fashion become widely available. This article is an attempt to demonstrate how the advent of more sophisticated computing technologies may lead to the development of new and more efficient algorithms. Curiously, new and more efficient algorithms often lead to the design of new and more efficient computing devices. In particular, all procedures described in this article can be implemented on parallel processors or on computing grids in essentially a trivial way. There is a strong incentive to build computing devices that can perform simultaneously several numerical integrations, or can compute dot products between very large lists of numbers very fast.

Finally, we must point out that most of the examples presented in the article are only prototypes. They were meant to be executed on a generic (and slightly out of date) laptop computer with the smallest possible number of complications. Many further improvements in terms of higher accuracy and overall efficiency can certainly be made.

Acknowledgments

The author thanks all three anonymous referees for their extremely helpful comments and suggestions.

References

A. Lyasoff, “Path Integral Methods for Parabolic Partial Differential Equations with Examples from Computational Finance,” The Mathematica Journal, 9(2), 2004 pp. 399–422.

A. Bensoussan and J. L. Lions, Applications of the Variational Inequalities in Stochastic Control, Amsterdam: North Holland, 1982.

M. H. A. Davis, “Markov Models and Optimization,” Monographs on Statistics and Applied Probability, Vol. 49, Chapman & Hall/CRC Press,1993.

V. Bally and G. Pagès, “A Quantization Algorithm for Solving Discrete Time Multidimensional Optimal Stopping Problems,” Bernoulli, 9(6), 2003 pp. 1003–1049.

V. Bally and G. Pagès, “Error Analysis of the Quantization Algorithm for Obstacle Problems,” Stochastic Processes and their Applications, 106(1), 2003 pp. 1–40.

B. Bouchard, I. Ekeland, and N. Touzi, “On the Malliavin Approach to Monte Carlo Approximation of Conditional Expectations,” Finance and Stochastics, 8(1), 2004 pp. 45–71.

M. Broadie and P. Glasserman, “Pricing American-Style Securities Using Simulation,” Journal of Economic Dynamics and Control, 21(8–9),1997 pp.1323–1352.

F. A. Longstaff and R. S. Schwartz, “Valuing American Options By Simulation: A Simple Least-Square Approach,” Review of Financial Studies, 14(1), 2001 pp. 113–147.

W. H. Press, B. Flannery, S. A. Teukolsky, and W. T. Vetterling, Numerical Recipes in C: The Art of Scientific Computing, 2nd ed., Cambridge: Cambridge University Press, 1992.

G. E. Forsythe, M. A. Malcolm, and C. B. Moler, Computer Methods for Mathematical Computations, Englewood Cliffs, NJ: Prentice Hall, 1977.

T. Lyons and N. Victoir, “Cubature on Wiener Space,” in Proceedings of the Royal Society of London, Series A (Mathematical and Physical Sciences), 460(2041), 2004 pp. 169–198.

S. Kusuoka, “Approximation of Expectation of Diffusion Process and Mathematical Finance,” in Advanced Studies in Pure Mathematics, Proceedings of the Taniguchi Conference on Mathematics (Nara 1998), (M. Maruyama and T. Sunada, eds.), 31, 2001 pp. 147–165.

S. Kusuoka, “Approximation of Expectation of Diffusion Processes Based on Lie Algebra and Malliavin Calculus,” Advances in Mathematical Economics, 6, 2004 pp. 69–83.

A. H. Stroud, Approximate Calculation of Multiple Integrals, Englewood Cliffs, NJ: Prentice-Hall, 1971.

Additional Material

Lyasoff.zip contains:
integrals.mx
integrals.txt
CoeffList.mx
CoeffList.txt
Xi.mx
Xi.txt

Available at www.mathematica-journal.com/data/uploads/2011/12/Lyasoff.zip.