Skip to content

matfree.bounds

matfree.bounds

Matrix-free bounds on functions of matrices.

matfree.bounds.baigolub96_logdet_spd(bound_spectrum, /, nrows, trace, norm_frobenius_squared)

Bound the log-determinant of a symmetric, positive definite matrix.

This function implements Theorem 2 in the paper by Bai and Golub (1996).

bound_spectrum is either an upper or a lower bound on the spectrum of the matrix. If it is an upper bound, the function returns an upper bound of the log-determinant. If it is a lower bound, the function returns a lower bound of the log-determinant.

BibTex for Bai and Golub (1996)
@article{bai1996bounds,
    title={Bounds for the trace of the inverse and the
    determinant of symmetric positive definite matrices},
    author={Bai, Zhaojun and Golub, Gene H},
    journal={Annals of Numerical Mathematics},
    volume={4},
    pages={29--38},
    year={1996},
    publisher={Citeseer}
}
Source code in matfree/bounds.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def baigolub96_logdet_spd(bound_spectrum, /, nrows, trace, norm_frobenius_squared):
    """Bound the log-determinant of a symmetric, positive definite matrix.

    This function implements Theorem 2 in the paper by Bai and Golub (1996).

    ``bound_spectrum`` is either an upper or a lower bound
    on the spectrum of the matrix.
    If it is an upper bound,
    the function returns an upper bound of the log-determinant.
    If it is a lower bound,
    the function returns a lower bound of the log-determinant.



    ??? note "BibTex for Bai and Golub (1996)"
        ```bibtex
        @article{bai1996bounds,
            title={Bounds for the trace of the inverse and the
            determinant of symmetric positive definite matrices},
            author={Bai, Zhaojun and Golub, Gene H},
            journal={Annals of Numerical Mathematics},
            volume={4},
            pages={29--38},
            year={1996},
            publisher={Citeseer}
        }
        ```
    """
    mu1, mu2 = trace, norm_frobenius_squared
    beta = bound_spectrum
    tbar = (beta * mu1 - mu2) / (beta * nrows - mu1)
    v = np.asarray([np.log(beta), np.log(tbar)])
    w = np.asarray([mu1, mu2])
    A = np.asarray([[beta, tbar], [beta**2, tbar**2]])
    return v @ linalg.solve(A, w)