# Utilities Functions

In this section we document commonly used utility structures methods.

## Interpolation Methods

`DiffFusion.interpolation_methods`

— Constantconst interpolation_methods = Dict{String, Function}(...)

Specify names for available interpolation methods.

Dictionary values are constructors with signature `(x,y) -> interpolation`

Available interpolation strings (i.e. keys) are

`LINEAR`

,`CUBIC`

,`AKIMA`

,`FRITSCHCARLSON`

,`STEFFEN`

.

See package Interpolations for details.

## Polynomial Regression Methods

`DiffFusion.PolynomialRegression`

— Type```
struct PolynomialRegression
V::Matrix{Int}
beta::AbstractVector
end
```

A `PolynomialRegression`

holds allows to predict values of a multi-variate function. The polynomial degrees are encoded in the multi-index matrix *V*. The polynomial coefficients are stored in the vector *beta*.

`DiffFusion.polynomial_regression`

— Function```
polynomial_regression(
C::AbstractMatrix,
O::AbstractVector,
max_degree::Int,
)
```

Calibrate a `PolynomialRegression`

object from a matrix of controls C of size (n,p) and a vector of observations O of size (p,). The maximum polynomial degree is given by max_degree.

`DiffFusion.predict`

— Method`predict(reg::PolynomialRegression, C::AbstractMatrix)`

Use a calibrated polynomial regression to predict function values. Input is a matrix of controls C of size (n,p). Result is a vector of size (p,).

`DiffFusion.multi_index`

— Method`multi_index(n::Int, k::Int)`

Calculate an `Int`

matrix as `Vector{Vector{Int}}`

of size (m,n) where each row represents an n-dimensional multi-index α with degree |α| < k.

`DiffFusion.monomials`

— Method`monomials(C::AbstractMatrix, V::AbstractMatrix)`

Calculate monomials M of size (m,p) for a matrix of controls C of size (n,p) and a matrix V of multi-indices α. V is of size (m,n).

## Pice-wise Polynomial Regression Methods

We implement a piece-wise polynomial multivariate regression.

The method represents a combination of a simple decision tree model with polynomial regression on the leaf nodes.

For reference and motivation, see the following blog post.

We consider a data set of controls C of size (n,p). Here, n represents the number of features and p represents the number of observations.

A *partitioning* is represented by a multi-index π = (π*1, ..., π*n) with π*k > 0. Each π*k represents the number of partitions for the k-th feature.

The idea is to sort C by the values of the first feature. Then, we split the data set into π_1 partitions. For each partition the procedure is repeated with the second feature and following features.

As a result, we get a split of the full data set into π*1 * ... * π*n subsets. For each subset of data we calculate a polynomial regression.

For model prediction have a given data point c. We need to identify the subset and regression which is to be used with c. This step is split into the following sub-steps:

Determine a multi-index α that identifies the subset.

Determine a scalar index r via a total ordering of multi- indices.

The elements of α in step 1 are determined successively by means of a *branching matrix* Q. A branching matrix is of size (π*k - 1, m*k). Each column in Q represents quantiles that evenly split the calibration data set for the k-th feature.

In order to determine an element α*k from c*k in step 1 we determine the relevant column from the k-th branching matrix and compare c_k against the quantile values.

`DiffFusion.PiecewiseRegression`

— Type```
struct PiecewiseRegression
π::Vector{Int}
Qs::Vector{AbstractMatrix}
regs::Vector{PolynomialRegression}
end
```

A PiecewiseRegression holds the information on the partitioning of the training data set and a list of regressions. The information on the partitioning is encoded in the partitioning vector π, the list of branching matrices Qs and the list of polynomial regressions.

`DiffFusion.piecewise_regression`

— Function```
piecewise_regression(
C::AbstractMatrix,
O::AbstractVector,
max_degree::Int,
π::Vector{Int},
)
```

Create a PiecewiseRegression from a matrix of features (or controls) C, a vector of labels (or observations) O, a maximum polynomial degree (max_degree), and a partitioning vector π.

C is of size (n,p), O is of length p, max_degree should be 2 (or 3) and π is of length n. The entries of π should be between 2 and 4; depending on the number of observations p and the number of dimensions n.

`DiffFusion.predict`

— Method`predict(reg::PiecewiseRegression, C::AbstractMatrix)`

Use a calibrates piecewise polynomial regression to predict function values. Input is a matrix of controls C of size (n,p). Result is a vector of size (p,).

`DiffFusion.partition_index`

— Method`partition_index(π::Vector{Int}, α::Vector{Int})`

Calculate a scalar index r from a multi-index α and a partitioning π.

This method implements a total ordering of multi-indices.

`DiffFusion.sub_index`

— Method`sub_index(c_k::ModelValue, π::Vector{Int}, α::Vector{Int}, Q::AbstractMatrix)`

Calculate the k-th index α*k for a scalar feature c*k, earlier indices α = (α*1, ..., α*k-1), partitioning π = (π*1, ..., π*k) up to index k and a branching matrix Q.

`DiffFusion.multi_index`

— Method`multi_index(c::AbstractVector, π::Vector{Int}, Qs::AbstractVector)`

Calculate a multi-index α = (α*1, ..., α*n). For the elements we have 1 ≤ α*k ≤ π*k. An element α*k represents the index of the subset to which the k-th feature c*k belongs (all conditional on earlier features).

`DiffFusion.branching_matrix`

— Method`branching_matrix(π::Vector{Int}, Alpha::Matrix{Int}, C_k::AbstractVector)`

Calculate a branching matrix Q*k of quantiles for a vector of features (c*k,j)*j=1,..,p. Calculation also depends on earlier multi-indices α = (α*1, ..., α*k-1) for each c*k,j and partitions π = (π*1, ..., π*k-1).

`DiffFusion.partitioning`

— Method`partitioning(C::AbstractMatrix, π::Vector{Int})`

Calculate branching matrices and indices for a matrix of features C and a partitioning vector π. The matrix C is of size (n,p) where n is the number of scalar features (per observation) and p is the number observations/samples.

The method returns a vector (or list) of branching matrices Qs, a matrix of multi-indices Alpha, and the corresponding partition index R. Qs is of length n, Alpha is of size (n,p) and R is of length p.

## Black Formula Methods

`DiffFusion.black_price`

— Function`black_price(strike, forward, nu, call_put)`

Calculate Vanilla option price V in Black model.

Argument `strike`

($K$) represents the option strike, `forward`

($F$) is the forward price of the underlying $S$, i.e. $F = E[S(T)]$ in the respective pricing measure.

Argument nu represents the standard deviation of the forward price. For annualised lognormal volatility σ, we have $ν = σ √T$. Finally, `call_put`

is the call (+1) or put (-1) option flag.

We allow broadcasting for arguments.

`black_price(strike, forward, σ, T, call_put)`

Calculate Vanilla option price $V$ in Black model with volatility parameter.

`DiffFusion.black_delta`

— Function`black_delta(strike, forward, nu, call_put)`

Calculate Vanilla option Delta in Black model.

`black_delta(strike, forward, σ, T, call_put)`

Calculate Vanilla option Delta in Black model with volatility parameter.

`DiffFusion.black_gamma`

— Function`black_gamma(strike, forward, nu)`

Calculate Vanilla option Gamma in Black model.

`black_gamma(strike, forward, σ, T)`

Calculate Vanilla option Gamma in Black model with volatility parameter.

`DiffFusion.black_theta`

— Function`black_theta(strike, forward, σ, T)`

Calculate Vanilla option Theta in Black model.

`DiffFusion.black_vega`

— Function`black_vega(strike, forward, nu)`

Calculate Vanilla option Vega in Black model.

Here, Vega is calculated as $dV / d ν$.

`black_vega(strike, forward, σ, T)`

Calculate Vanilla option Vega in Black model with volatility parameter..

Here, Vega is calculated as $dV / dσ$.

`DiffFusion.black_implied_stdev`

— Function`black_implied_stdev(price, strike, forward, call_put, min_max = (0.01, 3.00))`

Calculate the implied log-normal standard deviation ν from a Black model price.

`DiffFusion.black_implied_volatility`

— Function`black_implied_volatility(price, strike, forward, T, call_put, min_max = (0.01, 1.00))`

Calculate the implied log-normal volatility σ from a Black model price.

## Bachelier Formula Methods

`DiffFusion.bachelier_price`

— Function`bachelier_price(strike, forward, nu, call_put)`

Calculate Vanilla option price $V$ in Bachelier model.

Argument `strike`

($K$) represents the option strike, `forward`

($F$) is the forward price of the underlying $S$, i.e. $F = E[S(T)]$ in the respective pricing measure.

Argument `nu`

represents the standard deviation of the forward price. For annualised normal volatility σ, we have `ν = σ √T`

. Finally, `call_put`

is the call (+1) or put (-1) option flag.

`bachelier_price(strike, forward, σ, T, call_put)`

Calculate Vanilla option price $V$ in Bachelier model with volatility parameter.

`DiffFusion.bachelier_vega`

— Function`bachelier_vega(strike, forward, nu)`

Calculate Vanilla option Vega in Bachelier model.

Here, Vega is calculated as $dV / d ν$.

`bachelier_vega(strike, forward, σ, T)`

Calculate Vanilla option Vega in Bachelier model with volatility parameter.

Here, Vega is calculated as $dV / dσ$.

`DiffFusion.bachelier_implied_stdev`

— Function`bachelier_implied_stdev(price, strike, forward, call_put, min_max = (1.0e-4, 6.0e-2))`

Calculate the implied normal standard deviation ν from a Bachelier model price.

`DiffFusion.bachelier_implied_volatility`

— Function`bachelier_implied_volatility(price, strike, forward, T, call_put, min_max = (0.0001, 0.02))`

Calculate the implied normal volatility σ from a Bachelier model price.