# 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.