Cached Parameterization Concept#

This concept provides the interface expected by the MonotoneComponent class for the definition of the generally non-monotone function \(f(x) : \mathbb{R}^d \rightarrow \mathbb{R}\). This concept defines the ExpansionType template argument in the MonotoneComponent definition.

The MonotoneComponent class will evaluate \(f(x)\) at many points \(x^{(k)}\) that differ only in the \(d^{th}\) component. That is, for any \(k_1\) and \(k_2\), \(x_j^{(k_1)} = x_j^{(k_2)}\) for \(j<d\). In many cases, it is possible to take advantage of this fact to precompute some quantities related to \(x_{1:d-1}\) that we know will not change as the MonotoneComponent class varies \(x_d\).

To enable this, ExpansionType needs to be able to interact with a preallocated block of memory called the cache below. The cache will be allocated outside the ExpansionType class, and then passed to ExpansionType::FillCache1 to do any necessary precomputations.

When the value of the last component \(x_d\) is altered, the ExpansionType::FillCache2 function will then be called, before calling ExpansionType::Evaluate to actually evaluate \(f(x)\). The ExpansionType::Evaluate function only has access to the memory in the cache, so its important to perform all necessary computations in either the ExpansionType::FillCache1 or ExpansionType::FillCache2 functions.

The details of these functions, as well as all the functions that MonotoneComponent expects ExpansionType to have, are provided in the Specific Requirements section below.

Potential Usage#

Below is an example of how a class implementing the cached parameterization concept could be used to evaluate \(f(x;c)\) at a randomly chosen point \(x\) and randomly chosen coefficients \(c\).

ExpansionType expansion;
// ... Define the expansion

// Evaluate the
std::vector<double> cache( expansion.CacheSize() );

Eigen::VectorXd coeffs = Eigen::VectorXd::Random( expansion.NumCoeffs() );

unsigned int dim = expansion.InputSize();
Eigen::VectorXd evalPt = Eigen::VectorXd::Random( dim );

expansion.FillCache1(&cache[0], evalPt, DerivativeFlags::None);
expansion.FillCache2(&cache[0], evalPt, evalPt(dim-1), DerivativeFlags::None);

double f = expansion.Evaluate(&cache[0], coeffs);

// Now perturb x_d and re-evaluate
double xd = evalPt(dim-1) + 1e-2;
expansion.FillCache2(&cache[0], evalPt, xd, DerivativeFlags::None);

double f2 = expansion.Evaluate(&cache[0], coeffs);

Specific Requirements#

Implementations#

The following classes currently implement this concept.