Linearisation
Local linearisation replaces a function by its first-order Taylor expansion at the inputs' means. A normal passes through a linear map exactly, so the approximation is in the function, not in the moments.
The method
Near the expansion point $\hat{x}$, usually the mean,
\[f(x) ≈ f(\hat{x}) + J (x - \hat{x}) = A x + b, \qquad A = J, \quad b = f(\hat{x}) - J \hat{x},\]
where $J$ is the Jacobian of $f$ at $\hat{x}$: a derivative for a scalar function of a scalar, a gradient row for a scalar function of a vector. A normal $N(m, V)$ then maps to $N(A m + b, A V A^\top)$. The Jacobian comes from automatic differentiation with ForwardDiff, so f must accept its dual numbers, which any generic Julia function does.
approximate(::Linearization, f, x̂) returns the map (A, b), and the caller propagates the moments through it. For exp at 0, the tangent line is 1 + x:
using MessagePassingRulesApproximations
m, v = 0.0, 0.25
A, b = approximate(Linearization(), exp, (m,))
(A, b), (A * m + b, A * v * A')((1.0, 1.0), (1.0, 0.25))The linearised mean is exp(0) = 1, while the exact mean is exp(v / 2) ≈ 1.133: the expansion keeps no curvature. The error grows with the input's variance, and vanishes for an affine function.
A function of several arguments is expanded in all of them at once. The columns of A follow the arguments concatenated into one vector:
approximate(Linearization(), (x, y) -> x .- y, ([1.0, 2.0], [0.5, 0.5]))([1.0 0.0 -1.0 0.0; 0.0 1.0 0.0 -1.0], [0.0, 0.0])API
MessagePassingRulesApproximations.Linearization — Type
Linearization()The local-linearization method: a function is replaced by its first-order Taylor expansion at the inputs' means, computed by automatic differentiation (ForwardDiff), and moments pass through the linear map exactly. It has no parameters.
It is exact for affine functions and accurate when the function is close to linear over the inputs' spread; the function must be differentiable, and written generically enough for ForwardDiff's dual numbers. Unscented is the alternative that needs no derivatives.
See approximate(::Linearization, g, x̂) for the map it computes.
MessagePassingRulesApproximations.approximate — Method
approximate(::Linearization, g, x̂::Tuple) -> (A, b)The local linear map of g at the expansion point x̂, so that g(x) ≈ A * x + b near x̂.
Arguments
g: a function of one or several arguments, each a number or a vector, returning a number or a vector;x̂: the expansion point, a tuple with one entry per argument ofg, typically the inputs' means.
Returns
(A, b), where x stands for the arguments concatenated into one vector. A is a derivative for a scalar function of one scalar, a gradient row for a scalar function of a vector, and a Jacobian otherwise; b = g(x̂) - A * x̂. Propagating a normal N(m, V) of x gives N(A * m + b, A * V * A').
Examples
julia> approximate(Linearization(), (x, y) -> x .- y, ([1.0, 2.0], [0.5, 0.5]))
([1.0 0.0 -1.0 0.0; 0.0 1.0 0.0 -1.0], [0.0, 0.0])MessagePassingRulesApproximations.local_linearization — Function
local_linearization(g, x̂::Tuple) -> (A, b)The first-order expansion of g at x̂, the function behind approximate(::Linearization, g, x̂), which documents its arguments and result.