Function Repository Resource:

LDLDecomposition

Source Notebook

Find the LDL decomposition of a Hermitian matrix

Contributed by: Jan Mangaldan and Daniel Lichtblau

ResourceFunction["LDLDecomposition"][mat]

finds the LDL decomposition of Hermitian matrix mat.

Details

For a Hermitian matrix mat, the LDL decomposition is a pair {lower,diag} such that lower is lower diagonal matrix with ones on the main diagonal, diag is a diagonal matrix and mat=lower.diag.ConjugateTranspose[lower].
When mat is positive definite the LDL decomposition is a simple modification of CholeskyDecomposition. In this case it is equivalent to the resource function RationalCholeskyDecomposition.

Examples

Basic Examples (5) 

Create a Hankel matrix:

In[1]:=
hmat = N@HankelMatrix[4]
Out[1]=

Check that it is Hermitian:

In[2]:=
HermitianMatrixQ[hmat]
Out[2]=

Compute the LDL decomposition:

In[3]:=
{l, d} = ResourceFunction["LDLDecomposition"][hmat]
Out[3]=

Check that these matrices are lower triangular with ones on the main diagonal, and diagonal respectively:

In[4]:=
{LowerTriangularMatrixQ[l], Diagonal[l] == ConstantArray[1., Length[l]], DiagonalMatrixQ[d]}
Out[4]=

Check that we recover the original hmat from the LDL product:

In[5]:=
Chop[hmat - l . d . ConjugateTranspose[l]]
Out[5]=

Scope (3) 

LDLDecomposition works with complex Hermitian matrices:

In[6]:=
mat0 = RandomComplex[{-1 - I, 1 + I}, {4, 4}];
mat = mat0 + ConjugateTranspose[mat0]
Out[7]=

Compute the LDL decomposition:

In[8]:=
{l, d} = ResourceFunction["LDLDecomposition"][mat]
Out[8]=

Check that these matrices have the required properties:

In[9]:=
{LowerTriangularMatrixQ[l], Diagonal[l] == ConstantArray[1., Length[l]], DiagonalMatrixQ[d]}
Out[9]=

Check that we recover the original matrix:

In[10]:=
Chop[mat - l . d . ConjugateTranspose[l]]
Out[10]=

LDLDecomposition works with exact numeric matrices:

In[11]:=
hilb = HilbertMatrix[4]
Out[11]=

Compute the LDL decomposition:

In[12]:=
{l, d} = ResourceFunction["LDLDecomposition"][hilb]
Out[12]=

Check that these matrices have the required properties:

In[13]:=
{LowerTriangularMatrixQ[l], Diagonal[l] == ConstantArray[1., Length[l]], DiagonalMatrixQ[d]}
Out[13]=

Check that we recover the original matrix:

In[14]:=
hilb == l . d . ConjugateTranspose[l]
Out[14]=

LDLDecomposition works with symbolic matrices provided it can determine that they are Hermitian:

In[15]:=
mat = Array[a, {3, 3}] + ConjugateTranspose[Array[a, {3, 3}]]
Out[15]=

Check that mat is Hermitian:

In[16]:=
HermitianMatrixQ[mat]
Out[16]=

Compute the LDL decomposition:

In[17]:=
{l, d} = ResourceFunction["LDLDecomposition"][mat]
Out[17]=

Check that we recover the original matrix:

In[18]:=
mat == l . d . ConjugateTranspose[l]
Out[18]=

Properties and Relations (2) 

Create a Hilbert matrix of dimension 5:

In[19]:=
hilb = N@HilbertMatrix[5]
Out[19]=

Check that it is positive definite:

In[20]:=
PositiveDefiniteMatrixQ[hilb]
Out[20]=

Compute the LDL decomposition:

In[21]:=
{l1, d1} = ResourceFunction["LDLDecomposition"][hilb]
Out[21]=

Check that this agrees with the rational Cholesky decomposition up to numeric machine precision error:

In[22]:=
{l2, d2} = ResourceFunction["RationalCholeskyDecomposition"][hilb];
d2 = DiagonalMatrix[d2];
Chop[{l1 - l2, d1 - d2}]
Out[24]=

For positive definite matrices one can obtain the LDL decomposition from the LU decomposition (when no pivoting was performed) and also from the Cholesky decomposition. Form a positive definite matrix:

In[25]:=
mat = HankelMatrix[4] + DiagonalMatrix[{2, 0, 8, 20}] + 1/HilbertMatrix[4];
PositiveDefiniteMatrixQ[mat]
Out[26]=

Check that the LUDecomposition did not permute any rows:

In[27]:=
lud = LUDecomposition[mat];
lud[[2]] == Range[4]
Out[28]=

Extract the diagonal and use it to form a lower triangular matrix with ones on the main diagonal:

In[29]:=
uu = UpperTriangularize[lud[[1]]];
dd = Diagonal[uu];
{ll, dd} = {Transpose[DiagonalMatrix[1/dd] . uu], DiagonalMatrix[dd]}
Out[31]=

Check that this recovers the LDL decomposition:

In[32]:=
{ll, dd} == ResourceFunction["LDLDecomposition"][mat]
Out[32]=

Compute the CholeskyDecomposition:

In[33]:=
chmat = CholeskyDecomposition[mat]
Out[33]=

Extract the diagonal and modify the Cholesky upper triangular matrix to recover the LDL decomposition:

In[34]:=
diag = Diagonal[chmat];
lower = ConjugateTranspose[chmat/diag];
{ll, dd} == {lower, DiagonalMatrix[diag^2]}
Out[36]=

Requirements

Wolfram Language 13.0 (December 2021) or above

Version History

  • 1.0.0 – 02 October 2024

Source Metadata

Related Resources

License Information