dev

Matrix Gradients of Scalar Functions

Understanding the building blocks of reverse-mode automatic differentiation

These notes were written for the implementation of reverse-mode automatic differentiation in Birch, specifically the NumBirch library that provides its numerics on both CPU and GPU. The motivation is to:

  1. consolidate some essential gradients in one place, especially those commonly required for probabilistic modeling (e.g.Β Cholesky factorizations, logarithms of determinants), and

  2. present those gradients in the form required for reverse-mode automatic differentiation.

While some gradients are simply stated and cited, others are derived from first principles using element-wise calculations as an aid to understanding.

Background

In the simplest setting, we are interested in a function ff that accepts a matrix argument 𝑿\mathbf{X} and returns a scalar result. A typical setting is model training, where ff is the objective function (e.g.Β log-likelihood or mean squared error), 𝑿\mathbf{X} are some parameters (e.g.Β weights and biases of a neural network), and we wish to compute βˆ‚f/βˆ‚π‘Ώ\partial f/\partial\mathbf{X}, being the gradient of ff with respect to 𝑿\mathbf{X}. Having the gradient, we then might apply a gradient-based update to the parameters, as when optimizing with stochastic gradient descent or sampling with Langevin Monte Carlo.

We will focus in particular on reverse-mode automatic differentation. For illustration, assume that ff can be decomposed into a single chain of simpler functions f1,…,fnf_{1},\ldots,f_{n}:

f(𝑿)=(fnβˆ˜β‹―βˆ˜f1)(𝑿).f(\mathbf{X})=(f_{n}\circ\cdots\circ f_{1})(\mathbf{X}).

We first perform a forward pass to compute the intermediate results, first computing 𝒀1=f1(𝑿)\mathbf{Y}_{1}=f_{1}(\mathbf{X}) then proceeding recursively:

𝒀i=fi(𝒀iβˆ’1)=(fiβˆ˜β‹―βˆ˜f1)(𝑿) for i=2,…,nβˆ’1y=fn(𝒀nβˆ’1)=(fnβˆ˜β‹…βˆ˜f1)(𝑿)=f(𝑿).\begin{aligned} \mathbf{Y}_{i} & =f_{i}(\mathbf{Y}_{i-1})=(f_{i}\circ\cdots\circ f_{1})(\mathbf{X})\text{ for }i=2,\ldots,n-1\\ y & =f_{n}(\mathbf{Y}_{n-1})=(f_{n}\circ\cdot\circ f_{1})(\mathbf{X})=f(\mathbf{X}).\end{aligned}

We then perform a backward pass to compute the gradient by applying the chain rule, first computing βˆ‚f/βˆ‚π’€nβˆ’1\partial f/\partial\mathbf{Y}_{n-1} then proceeding recursively:

βˆ‚fβˆ‚π’€i=βˆ‚fβˆ‚π’€i+1β‹…βˆ‚π’€i+1βˆ‚π’€i for i=nβˆ’2,…,1βˆ‚fβˆ‚π‘Ώ=βˆ‚fβˆ‚π’€1β‹…βˆ‚π’€1βˆ‚π‘Ώ.\begin{aligned} \frac{\partial f}{\partial\mathbf{Y}_{i}} & =\frac{\partial f}{\partial\mathbf{Y}_{i+1}}\cdot\frac{\partial\mathbf{Y}_{i+1}}{\partial\mathbf{Y}_{i}}\text{ for }i=n-2,\ldots,1\\ \frac{\partial f}{\partial\,\mathbf{X}} & =\frac{\partial f}{\partial\mathbf{Y}_{1}}\cdot\frac{\partial\mathbf{Y}_{1}}{\partial\mathbf{X}}.\end{aligned}

The intermediate results 𝒀i\mathbf{Y}_{i} computed during the forward pass often appear in the computations required during the backward pass. They can be memoized for reuse rather than computed again.

A particular convenience of working in reverse mode for scalar functions is that each intermediate gradient has the same size (rows and columns) as the corresponding intermediate result, i.e.Β βˆ‚f/βˆ‚π’€i\partial f/\partial\mathbf{Y}_{i} has the same size as 𝒀i\mathbf{Y}_{i}, and βˆ‚f/βˆ‚π‘Ώ\partial f/\partial\mathbf{X} the same size as 𝑿\mathbf{X}.

The above is a simplification in that it assumes ff can be decomposed into a single chain. Generally, for the presence of intermediate functions with multiple arguments, it will decompose into a tree or graph (often called a compute graph in machine learning or expression template elsewhere). The principle is nonetheless the same: we apply the chain rule along branches of the graph.

We limit ourselves to reverse mode here, but it is not the only approach. Forward mode automatic differentation works in the opposite order, using a single forward pass to recursively compute 𝒀i\mathbf{Y}_{i} and βˆ‚π’€i/βˆ‚π‘Ώ\partial\mathbf{Y}_{i}/\partial\mathbf{X} simultaneouslyβ€”but for scalar functions this foregoes the sizing convenience of reverse mode. Mixed mode denotes any other order, which can be designed to exploit specific structure in the compute graph.

Results

To derive a gradient of ff with respect to 𝑿\mathbf{X}, we assume that the upstream gradient βˆ‚f/βˆ‚g(𝑿)\partial f/\partial g(\mathbf{X}) is known for some gg that denotes a matrix operation of interest, e.g.Β transpose g(𝑿)=π‘ΏβŠ€g(\mathbf{X})=\mathbf{X}^{\top} or inverse g(𝑿)=π‘Ώβˆ’1g(\mathbf{X})=\mathbf{X}^{-1}. We then apply the chain rule element-wise to compute the partial derivative of ff with respect to the (i,j)(i,j)th element of 𝑿\mathbf{X}, denoted (𝑿)ij(\mathbf{X})_{ij}:

βˆ‚fβˆ‚(𝑿)ij=βˆ‘klβˆ‚fβˆ‚g(𝑿)klβ‹…βˆ‚g(𝑿)klβˆ‚(𝑿)ij.\frac{\partial f}{\partial(\mathbf{X})_{ij}}=\sum_{kl}\frac{\partial f}{\partial g(\mathbf{X})_{kl}}\cdot\frac{\partial g(\mathbf{X})_{kl}}{\partial(\mathbf{X})_{ij}}.

We then simplify the element-wise expression into a matrix expression to allow the partial derivatives with respect to all elements to be computed simultaneouslyβ€”also more efficiently using high-performance linear algebra routinesβ€”and so obtain the gradient.

Transpose

The transpose is straightforward: the gradient of ff with respect to 𝑿\mathbf{X} is the transpose of the gradient of ff with respect to π‘ΏβŠ€\mathbf{X}^{\top}. But to demonstrate use of the above formulation, let ff be a scalar function and βˆ‚f/βˆ‚π‘ΏβŠ€\partial f/\partial\mathbf{X}^{\top} be given; we then have, element-wise:

βˆ‚fβˆ‚(𝑿)ij=βˆ‘klβˆ‚fβˆ‚(π‘ΏβŠ€)klβ‹…βˆ‚(π‘ΏβŠ€)klβˆ‚(𝑿)ij=βˆ‘klβˆ‚fβˆ‚(π‘ΏβŠ€)klβ‹…Ξ΄kjΞ΄li=βˆ‚fβˆ‚(π‘ΏβŠ€)ji,\begin{aligned} \frac{\partial f}{\partial(\mathbf{X})_{ij}} & =\sum_{kl}\frac{\partial f}{\partial\left(\mathbf{X}^{\top}\right){}_{kl}}\cdot\frac{\partial\left(\mathbf{X}^{\top}\right)_{kl}}{\partial(\mathbf{X})_{ij}}\\ & =\sum_{kl}\frac{\partial f}{\partial\left(\mathbf{X}^{\top}\right){}_{kl}}\cdot\delta_{kj}\delta_{li}\\ & =\frac{\partial f}{\partial\left(\mathbf{X}^{\top}\right){}_{ji}},\end{aligned}

where Ξ΄ij\delta_{ij} denotes the Kronecker delta (i.e.Β 1 when i=ji=j and 0 otherwise). We recognize this as a simple transpose operation on all elements simultaneously:

βˆ‚fβˆ‚π‘Ώ=(βˆ‚fβˆ‚π‘ΏβŠ€)⊀.\begin{aligned} \frac{\partial f}{\partial\mathbf{X}} & =\left(\frac{\partial f}{\partial\mathbf{X}^{\top}}\right)^{\top}.\end{aligned}$

Multiplication

Let ff be a scalar function and βˆ‚f/βˆ‚π‘Ώπ’€\partial f/\partial\mathbf{XY} be given. Element-wise, we have:

βˆ‚fβˆ‚(𝑿)ij=βˆ‘klβˆ‚fβˆ‚(𝑿𝒀)klβ‹…βˆ‚(𝑿𝒀)klβˆ‚(𝑿)ij=βˆ‘klβˆ‚fβˆ‚(𝑿𝒀)klΞ΄ki(𝒀)jl=βˆ‘lβˆ‚fβˆ‚(𝑿𝒀)il(𝒀)jl.\begin{aligned} \frac{\partial f}{\partial(\mathbf{X})_{ij}} & =\sum_{kl}\frac{\partial f}{\partial(\mathbf{XY})_{kl}}\cdot\frac{\partial(\mathbf{XY})_{kl}}{\partial(\mathbf{X})_{ij}}\\ & =\sum_{kl}\frac{\partial f}{\partial(\mathbf{XY})_{kl}}\delta_{ki}(\mathbf{Y})_{jl}\\ & =\sum_{l}\frac{\partial f}{\partial(\mathbf{XY})_{il}}(\mathbf{Y})_{jl}.\end{aligned}

We observe from this that βˆ‚f/βˆ‚(𝑿)ij\partial f/\partial(\mathbf{X})_{ij} is the dot product between the iith row of βˆ‚f/βˆ‚π‘Ώπ’€\partial f/\partial\mathbf{X}\mathbf{Y} and jjth row of 𝒀\mathbf{Y}, and consolidate in matrix form as:

βˆ‚fβˆ‚π‘Ώ=βˆ‚fβˆ‚π‘Ώπ’€π’€βŠ€.\frac{\partial f}{\partial\mathbf{X}}=\frac{\partial f}{\partial\mathbf{XY}}\mathbf{Y}^{\top}.

Next we wish to compute βˆ‚f/βˆ‚π’€\partial f/\partial\mathbf{Y}. We can derive using the same element-wise approach, or simply apply the transpose property above to obtain:

βˆ‚fβˆ‚π’€=π‘ΏβŠ€βˆ‚fβˆ‚π‘Ώπ’€.\begin{aligned} \frac{\partial f}{\partial\mathbf{Y}} & =\mathbf{X}^{\top}\frac{\partial f}{\partial\mathbf{XY}}.\end{aligned}

Inverse

Let ff be a scalar function and βˆ‚f/βˆ‚π‘Ώβˆ’1\partial f/\partial\mathbf{X}^{-1} be given. We have (Petersen & Pedersen, 2016):

βˆ‚fβˆ‚π‘Ώ=βˆ’π‘Ώβˆ’βŠ€βˆ‚fβˆ‚π‘Ώβˆ’1π‘Ώβˆ’βŠ€,\frac{\partial f}{\partial\mathbf{X}}=-\mathbf{X}^{-\top}\frac{\partial f}{\partial\mathbf{X}^{-1}}\mathbf{X}^{-\top},

using the shorthand notation π‘Ώβˆ’βŠ€=(π‘Ώβˆ’1)⊀=(π‘ΏβŠ€)βˆ’1\mathbf{X}^{-\top}=\left(\mathbf{X}^{-1}\right)^{\top}=\left(\mathbf{X}^{\top}\right)^{-1}. We can derive this element-wise but it requires a non-obvious property given in (Petersen & Pedersen, 2016):=

βˆ‚(π‘Ώβˆ’1)klβˆ‚(𝑿)ij=(π‘Ώβˆ’1)ki(π‘Ώβˆ’1)jl.\frac{\partial(\mathbf{X}^{-1})_{kl}}{\partial(\mathbf{X})_{ij}}=(\mathbf{X}^{-1})_{ki}(\mathbf{X}^{-1})_{jl}.

Using this, the derivation proceeds:

βˆ‚fβˆ‚(𝑿)ij=βˆ‘klβˆ‚fβˆ‚(π‘Ώβˆ’1)klβ‹…βˆ‚(π‘Ώβˆ’1)klβˆ‚(𝑿)ij=βˆ’βˆ‘klβˆ‚fβˆ‚(π‘Ώβˆ’1)kl(π‘Ώβˆ’1)ki(π‘Ώβˆ’1)jl=βˆ’βˆ‘k(π‘Ώβˆ’1)kiβˆ‘lβˆ‚fβˆ‚(π‘Ώβˆ’1)kl(π‘Ώβˆ’1)jl,\begin{aligned} \frac{\partial f}{\partial(\mathbf{X})_{ij}} & =\sum_{kl}\frac{\partial f}{\partial(\mathbf{X}^{-1})_{kl}}\cdot\frac{\partial(\mathbf{X}^{-1})_{kl}}{\partial(\mathbf{X})_{ij}}\\ & =-\sum_{kl}\frac{\partial f}{\partial(\mathbf{X}^{-1})_{kl}}(\mathbf{X}^{-1})_{ki}(\mathbf{X}^{-1})_{jl}\\ & =-\sum_{k}(\mathbf{X}^{-1})_{ki}\sum_{l}\frac{\partial f}{\partial(\mathbf{X}^{-1})_{kl}}(\mathbf{X}^{-1})_{jl},\end{aligned}

from which we recognize the matrix form above.

Inverse of symmetric positive definite matrix

Let ff be a scalar function and βˆ‚f/βˆ‚π‘Ίβˆ’1\partial f/\partial\mathbf{S}^{-1} be given, where 𝑺\mathbf{S} is a symmetric positive definite matrix with Cholesky decomposition 𝑺=π‘³π‘³βŠ€\mathbf{S}=\mathbf{L}\mathbf{L}^{\top}, and so inverse π‘Ίβˆ’1=π‘³βˆ’βŠ€π‘³βˆ’1\mathbf{S}^{-1}=\mathbf{L}^{-\top}\mathbf{L}^{-1}, where 𝑳\mathbf{L} is a lower-triangular matrix. We use the transpose, multiplication and inverse properties to obtain:

βˆ‚fβˆ‚π‘³=βˆ’π‘³βˆ’βŠ€βˆ‚fβˆ‚π‘³βˆ’1π‘³βˆ’βŠ€=βˆ’π‘³βˆ’βŠ€((βˆ‚fβˆ‚π‘Ίβˆ’1π‘³βˆ’βŠ€)⊀+π‘³βˆ’1βˆ‚fβˆ‚π‘Ίβˆ’1)π‘³βˆ’βŠ€=βˆ’π‘³βˆ’βŠ€(π‘³βˆ’1βˆ‚fβˆ‚π‘Ίβˆ’T+π‘³βˆ’1βˆ‚fβˆ‚π‘Ίβˆ’1)π‘³βˆ’βŠ€=βˆ’π‘³βˆ’βŠ€π‘³βˆ’1(βˆ‚fβˆ‚π‘Ίβˆ’βŠ€+βˆ‚fβˆ‚π‘Ίβˆ’1)π‘³βˆ’βŠ€.\begin{aligned} \frac{\partial f}{\partial\mathbf{L}} & =-\mathbf{\mathbf{L}}^{-\top}\frac{\partial f}{\partial\mathbf{L}^{-1}}\mathbf{\mathbf{L}}^{-\top}\\ & =-\mathbf{\mathbf{L}}^{-\top}\left(\left(\frac{\partial f}{\partial\mathbf{S}^{-1}}\mathbf{L}^{-\top}\right)^{\top}+\mathbf{L}^{-1}\frac{\partial f}{\partial\mathbf{S}^{-1}}\right)\mathbf{\mathbf{L}}^{-\top}\\ & =-\mathbf{\mathbf{L}}^{-\top}\left(\mathbf{L}^{-1}\frac{\partial f}{\partial\mathbf{S}^{-T}}+\mathbf{L}^{-1}\frac{\partial f}{\partial\mathbf{S}^{-1}}\right)\mathbf{\mathbf{L}}^{-\top}\\ & =-\mathbf{\mathbf{L}}^{-\top}\mathbf{L}^{-1}\left(\frac{\partial f}{\partial\mathbf{S}^{-\top}}+\frac{\partial f}{\partial\mathbf{S}^{-1}}\right)\mathbf{\mathbf{L}}^{-\top}.\end{aligned}

Solve

When computing, matrix inversions π‘Ώβˆ’1\mathbf{X}^{-1} are replaced with the solutions of equations 𝒀=𝑿𝒁\mathbf{Y}=\mathbf{X}\mathbf{Z} wherever possible, for numerical stability. We can think of this as 𝒁=π‘Ώβˆ’1𝒀\mathbf{Z}=\mathbf{X}^{-1}\mathbf{Y}.

Let ff be a scalar function and βˆ‚f/βˆ‚π‘Ώβˆ’1𝒀\partial f/\partial\mathbf{X}^{-1}\mathbf{Y} be given. We use the multiplication and inverse properties above to obtain:

βˆ‚fβˆ‚π’€=π‘Ώβˆ’βŠ€βˆ‚fβˆ‚π‘Ώβˆ’1π’€βˆ‚fβˆ‚π‘Ώ=βˆ’π‘Ώβˆ’βŠ€βˆ‚fβˆ‚π‘Ώβˆ’1π‘Ώβˆ’βŠ€=βˆ’π‘Ώβˆ’βŠ€βˆ‚fβˆ‚π‘Ώβˆ’1π’€π’€βŠ€π‘Ώβˆ’βŠ€=βˆ’βˆ‚fβˆ‚π’€(π‘Ώβˆ’1𝒀)⊀=βˆ’βˆ‚fβˆ‚π’€π’βŠ€.\begin{aligned} \frac{\partial f}{\partial\mathbf{Y}} & =\mathbf{X}^{-\top}\frac{\partial f}{\partial\mathbf{X}^{-1}\mathbf{Y}}\\ \frac{\partial f}{\partial\mathbf{X}} & =-\mathbf{X}^{-\top}\frac{\partial f}{\partial\mathbf{X}^{-1}}\mathbf{X}^{-\top}\\ & =-\mathbf{X}^{-\top}\frac{\partial f}{\partial\mathbf{X}^{-1}\mathbf{Y}}\mathbf{Y}^{\top}\mathbf{X}^{-\top}\\ & =-\frac{\partial f}{\partial\mathbf{Y}}(\mathbf{X}^{-1}\mathbf{Y})^{\top}\\ & =-\frac{\partial f}{\partial\mathbf{Y}}\mathbf{Z}^{\top}.\end{aligned}

In the second last line we substitute in βˆ‚f/βˆ‚π’€\partial f/\partial\mathbf{Y} from the first line, and in the last line 𝒁=π‘Ώβˆ’1𝒀\mathbf{Z}=\mathbf{X}^{-1}\mathbf{Y} from the forward pass, to avoid repeating expensive computations.

Solve with symmetric positive definite matrix

Let ff be a scalar function and βˆ‚f/βˆ‚π‘Ίβˆ’1𝒀\partial f/\partial\mathbf{S}^{-1}\mathbf{Y} be given, where 𝑺\mathbf{S} is a symmetric positive definite matrix with Cholesky decomposition 𝑺=π‘³π‘³βŠ€\mathbf{S}=\mathbf{L}\mathbf{L}^{\top}, and 𝑳\mathbf{L} a lower-triangular matrix. Using the solve and multiplication properties above we obtain:

βˆ‚fβˆ‚π’€=π‘³βˆ’βŠ€π‘³βˆ’1βˆ‚fβˆ‚π‘Ίβˆ’1π’€βˆ‚fβˆ‚π‘³=tril(βˆ‚fβˆ‚π‘Ίπ‘³+(π‘³βŠ€βˆ‚fβˆ‚π‘Ί)⊀)=tril((βˆ‚fβˆ‚π‘Ί+βˆ‚fβˆ‚π‘ΊβŠ€)𝑳)=tril(βˆ’(βˆ‚fβˆ‚π’€π’βŠ€+π’βˆ‚fβˆ‚π’€βŠ€)𝑳).\begin{aligned} \frac{\partial f}{\partial\mathbf{Y}} & =\mathbf{L}^{-\top}\mathbf{L}^{-1}\frac{\partial f}{\partial\mathbf{S}^{-1}\mathbf{Y}}\\ \frac{\partial f}{\partial\mathbf{L}} & =\mathrm{tril}\left(\frac{\partial f}{\partial\mathbf{S}}\mathbf{L}+\left(\mathbf{L}^{\top}\frac{\partial f}{\partial\mathbf{S}}\right)^{\top}\right)\\ & =\mathrm{tril}\left(\left(\frac{\partial f}{\partial\mathbf{S}}+\frac{\partial f}{\partial\mathbf{S}^{\top}}\right)\mathbf{L}\right)\\ & =\mathrm{tril}\left(-\left(\frac{\partial f}{\partial\mathbf{Y}}\mathbf{Z}^{\top}+\mathbf{Z}\frac{\partial f}{\partial\mathbf{Y}^{\top}}\right)\mathbf{L}\right).\end{aligned}

where tril\mathrm{tril} is a function that returns a matrix with its lower triangle set to that of its argument, and its strictly upper triangle set to zero. This form gives the gradient in the space of lower-triangular matrices, rather than the space of arbitrary dense matrices, to ensure that a gradient update maintains 𝑳\mathbf{L} as lower triangular.

Trace

Let ff be a scalar function and βˆ‚f/βˆ‚tr(𝑿)\partial f/\partial\mathrm{tr}(\mathbf{X}) be given. We have:

βˆ‚fβˆ‚(𝑿)ij=βˆ‚fβˆ‚tr(𝑿)β‹…βˆ‚tr(𝑿)βˆ‚(𝑿)ij=βˆ‚fβˆ‚tr(𝑿).\frac{\partial f}{\partial(\mathbf{X})}_{ij}=\frac{\partial f}{\partial\mathrm{tr}(\mathbf{X})}\cdot\frac{\partial\mathrm{tr}(\mathbf{X})}{\partial(\mathbf{X})_{ij}}=\frac{\partial f}{\partial\mathrm{tr}(\mathbf{X})}.

Or in matrix form:

βˆ‚fβˆ‚π‘Ώ=tr(𝑿)𝑰.\frac{\partial f}{\partial\mathbf{X}}=\mathrm{tr}(\mathbf{X})\mathbf{I}.

Logarithm of the determinant

Let ff be a scalar function and βˆ‚f/βˆ‚det⁡(𝑿)\partial f/\partial\det(\mathbf{X}) be given. We have (Petersen & Pedersen, 2016):

βˆ‚fβˆ‚π‘Ώ=βˆ‚fβˆ‚det⁡(𝑿)β‹…βˆ‚det⁡(𝑿)βˆ‚π‘Ώ=βˆ‚fβˆ‚det⁡(𝑿)det⁡(𝑿)π‘Ώβˆ’βŠ€.\frac{\partial f}{\partial\mathbf{X}}=\frac{\partial f}{\partial\det(\mathbf{X})}\cdot\frac{\partial\det(\mathbf{X})}{\partial\mathbf{X}}=\frac{\partial f}{\partial\det(\mathbf{X})}\det(\mathbf{X})\mathbf{X}^{-\top}.

By extension, and assuming that the determinant is positive so that we can take the logarithm, let βˆ‚f/βˆ‚log⁡(det(𝑿))\partial f/\partial\log\left(\det(\mathbf{X})\right) be given:

βˆ‚fβˆ‚π‘Ώ=βˆ‚fβˆ‚log⁡(det(𝑿))β‹…βˆ‚log⁡(det(𝑿))βˆ‚π‘Ώ=βˆ‚fβˆ‚log⁡(det(𝑿))π‘Ώβˆ’βŠ€.\frac{\partial f}{\partial\mathbf{X}}=\frac{\partial f}{\partial\log\left(\det(\mathbf{X})\right)}\cdot\frac{\partial\log\left(\det(\mathbf{X})\right)}{\partial\mathbf{X}}=\frac{\partial f}{\partial\log\left(\det(\mathbf{X})\right)}\mathbf{X}^{-\top}.

These seem non-trivial to derive element-wise.

Logarithm of the determinant of a symmetric positive definite matrix

Let 𝑺\mathbf{S} be a symmetric positive definite matrix with Cholesky decomposition 𝑺=π‘³π‘³βŠ€\mathbf{S}=\mathbf{L}\mathbf{L}^{\top}, with 𝑳\mathbf{L} a lower-triangular matrix consisting of positive elements along its main diagonal. The determinant of 𝑳\mathbf{L} (or indeed any triangular matrix) is the product of the elements along its main diagonal, and so the logarithm of the determinant the sum of the logarithms of the elements along its main diagonal.

Let ff be a scalar function and βˆ‚f/βˆ‚log⁡(det(𝑳))\partial f/\partial\log\left(\det(\mathbf{L})\right) be given. We then have:

βˆ‚fβˆ‚(𝑳)ij=βˆ‚fβˆ‚log⁡(det(𝑳))β‹…βˆ‚log⁡(det(𝑳))βˆ‚(𝑳)ij=βˆ‚fβˆ‚log⁡(det(𝑳))β‹…Ξ΄ij(𝑳)ij,\begin{aligned} \frac{\partial f}{\partial(\mathbf{L})_{ij}} & =\frac{\partial f}{\partial\log\left(\det(\mathbf{L})\right)}\cdot\frac{\partial\log\left(\det(\mathbf{L})\right)}{\partial(\mathbf{L})_{ij}}\\ & =\frac{\partial f}{\partial\log\left(\det(\mathbf{L})\right)}\cdot\frac{\delta_{ij}}{(\mathbf{L})_{ij}},\end{aligned}

which can be written as:

βˆ‚fβˆ‚π‘³=βˆ‚fβˆ‚log⁡(det(𝑳))β‹…diag(𝑳)βˆ’1,\frac{\partial f}{\partial\mathbf{L}}=\frac{\partial f}{\partial\log\left(\det(\mathbf{L})\right)}\cdot\mathrm{diag}(\mathbf{L})^{-1},

where diag\mathrm{diag} is a function that returns a diagonal matrix with its main diagonal set to that of the argument, and all off-diagonal elements set to zero.

As det⁡(𝑺)=det⁡(𝑳)2\det(\mathbf{S})=\det(\mathbf{L})^{2}, we have log⁡(det(𝑺))=2log⁡(det(𝑳))\log\left(\det(\mathbf{S})\right)=2\log\left(\det(\mathbf{L})\right) and so:

βˆ‚fβˆ‚π‘³=2βˆ‚fβˆ‚log⁡(det(𝑺))β‹…diag(𝑳)βˆ’1.\frac{\partial f}{\partial\mathbf{L}}=2\frac{\partial f}{\partial\log\left(\det(\mathbf{S})\right)}\cdot\mathrm{diag}(\mathbf{L})^{-1}.

Cholesky factorization

Let ff be a scalar function and βˆ‚f/βˆ‚π‘³\partial f/\partial\mathbf{L} be given, where 𝑺=𝑳𝑳T\mathbf{S}=\mathbf{L}\mathbf{L}^{T}. DefineΒ (Murray, 2016):

𝑷=Ξ¦(π‘³βŠ€βˆ‚fβˆ‚π‘³),\begin{aligned} \mathbf{P} & =\Phi\left(\mathbf{L}^{\top}\frac{\partial f}{\partial\mathbf{L}}\right),\end{aligned}

where Ξ¦\Phi is a function that returns a lower-triangular matrix with the strictly lower triangle set to that of its argument, the main diagonal set to half that of its argument, and the upper triangle set to zero. We then haveΒ (Murray, 2016):

βˆ‚fβˆ‚π‘Ί=Ξ¦(π‘³βˆ’βŠ€(𝑷+π‘·βŠ€)π‘³βˆ’1).\begin{aligned} \frac{\partial f}{\partial\mathbf{S}} & =\Phi\left(\mathbf{L}^{-\top}(\mathbf{P}+\mathbf{P}^{\top})\mathbf{L}^{-1}\right).\end{aligned}

This form gives the gradient in the space of symmetric matrices, rather than the space of arbitrary dense matrices. A gradient update on 𝑺\mathbf{S} will only affect the lower triangle. This is suitable when using linear algebra routines for symmetric matrices, which typically reference only one triangle (in this case, the lower) and assume that the other matches by symmetry. If a dense matrix must be formed, however, the strictly lower triangle should be transposed and copied into the strictly upper.

References