#
Computing the Inverse of a Matrix, Using the \( LU \) Factorization (tri)

**tri** (defined in namespace `flens::lapack`) computes the inverse of a matrix \( A \). For convenience a sub-variant is provided that implicitly creates a temporary workspaces.

For \( A \) containing the \( LU \) factorization this method inverts \( U \) and then computes \( A^{-1} \) by solving the system \( A^{-1} L = U^{-1} \) for \( A^{-1} \).

##
Real Variant

A |
`(input/output) real valued GeMatrix` On entry, the \( n \times n \) matrix \( A \) contains the factors \( L \) and \( U \) from the factorization \( A = P L U \) as computed by trf. On exit, if the return value equals \( 0 \), the inverse of the original matrix \( A \). |

piv |
`(input) integer valued DenseVector` The pivot indices from trf. For \( 1 \leq i \leq n \) row \( i \) of the original matrix \( A \) was interchanged with \( piv_i \). |

work |
`(input) real valued DenseVector` For optimal performance the length of the workspace should be at least \( n \cdot n_b \), where \( n_b \) is the optimal blocksize returned by ilaenv.
**Note:** If \( work \) has length zero the optimal length gets computed and vector \( work \) gets resized. Opposed to the worksize queries in LAPACK the function does not stop after computing the worksize. Instead it will continue the computation with the resized workspace. |

**Return value:**

\( i=0 \) |
Successfull exit. |

\( i>0 \) |
\( U_{i,i} \) is exactly zero. The factorization has been completed, but the factor U is exactly singular, so the solution could not be computed. |

##
Complex Variant

A |
`(input/output) complex valued GeMatrix` On entry, the \( n \times n \) matrix \( A \) contains the factors \( L \) and \( U \) from the factorization \( A = P L U \) as computed by trf. On exit, if the return value equals \( 0 \), the inverse of the original matrix \( A \). |

piv |
`(input) integer valued DenseVector` The pivot indices from trf. For \( 1 \leq i \leq n \) row \( i \) of the original matrix \( A \) was interchanged with \( piv_i \). |

work |
`(input) complex valued DenseVector` For optimal performance the length of the workspace should be at least \( n \cdot n_b \), where \( n_b \) is the optimal blocksize returned by ilaenv.
**Note:** If \( work \) has length zero the optimal length gets computed and vector \( work \) gets resized. Opposed to the worksize queries in LAPACK the function does not stop after computing the worksize. Instead it will continue the computation with the resized workspace. |

**Return value:**

\( i=0 \) |
Successfull exit. |

\( i>0 \) |
\( U_{i,i} \) is exactly zero. The factorization has been completed, but the factor U is exactly singular, so the solution could not be computed. |

##
Variant with Implicit Workspace Creation

This variant implicitly creates a temporary workspace and calls the real or complex variant.

A |
`(input/output) real or complex valued GeMatrix` On entry, the \( n \times n \) matrix \( A \) contains the factors \( L \) and \( U \) from the factorization \( A = P L U \) as computed by trf. On exit, if the return value equals \( 0 \), the inverse of the original matrix \( A \). |

piv |
`(input) integer valued DenseVector` The pivot indices from trf. For \( 1 \leq i \leq n \) row \( i \) of the original matrix \( A \) was interchanged with \( piv_i \). |

##
Notes