math icon indicating copy to clipboard operation
math copied to clipboard

Math does not have the matrix (inverse) square root

Open bgoodri opened this issue 6 years ago • 2 comments

Description

You can apply the sqrt function elementwise to a matrix, but Stan Math does not have a function to take the (symmetric) square root of a positive definite matrix (or its inverse), defined as V * diag_matrix(sqrt(v)) * V' where V is a matrix of eigenvectors and v is a vector of eigenvalues. In the case of the inverse square root of a matrix, there is a diag_matrix(inv_sqrt(v)) in the middle. Eigen already calculates these, so it is just a matter of exposing them and working through the Jacobians.

Example

data {
  int<lower = 1> K;
  matrix[K, K] X;
}
transformed data {
  matrix[K, K] sqrt_X = sqrt_spd(X);
  matrix[K, K] inv_sqrt_X = inv_sqrt_spd(X);
  real<lower = 0, upper = 1e-15> check = fabs(X - sqrt_X * sqrt_X);
}

[Note: The sqrt_spd and inv_sqrt_spd functions do not exist in Stan yet.]

Expected Output

Satisfies inequality restrictions on check.

Current Version:

v2.33

bgoodri avatar Mar 07 '19 15:03 bgoodri

I'd like to boost the priority on this one and I suggest we name the function matrix_sqrt(). Sarah Heaps has an elegant unconstrained parameterization of stationary parameters for a vector autoregressive (VAR) model. It uses matrix square root. She sent along the code she was using for it in Stan, without the new tuple feature

matrix sqrtm(matrix A) {
    int m = rows(A);
    vector[m] root_root_evals = sqrt(sqrt(eigenvalues_sym(A)));
    matrix[m, m] evecs = eigenvectors_sym(A);
    matrix[m, m] eprod = diag_post_multiply(evecs, root_root_evals);
    return tcrossprod(eprod);
  }

and with:

matrix sqrtm(matrix A) {
    int m = rows(A);
    tuple(matrix[m, m], vector[m]) eigen = eigendecompose_sym(A);
    matrix[m, m] eprod = diag_post_multiply(eigen.1, sqrt(sqrt(eigen.2)));
    return tcrossprod(eprod);
  }

I'd also like to add the full constraining transform and the unconstraining transform, but that will be in a separate issue.

bob-carpenter avatar Sep 20 '23 15:09 bob-carpenter

If we were to boost the priority of this, then https://github.com/KingJamesSong/FastDifferentiableMatSqrt is better than the closed PR I wrote a long time ago.

bgoodri avatar Jun 21 '24 15:06 bgoodri