Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented reverse mode for symmetric eigendecomposition #1878

Merged

Conversation

IvanYashchuk
Copy link
Contributor

Summary

This PR implements reverse mode differentiation for stan::math::eigenvectors_sym and stan::math::eigenvalues_sym.

Tests

There are already tests for AD with eigenvalues_sym and eigenvectors_sym.

I have added a test that checks the derivative of sum(log(eigenvalues_sym(A))). The derivative should be equal to the inverse of A. This test fails on the current develop branch. See #1803.

Side Effects

Currently, derivatives of eigenvalues_sym return lower triangular matrix.
I think that the correct derivative matrix should be symmetric and not lower triangular. This also affects any other function involved in the computation and the calculated autodiff derivative is not correct anymore. See #1803.

Release notes

Reverse mode differentiation of stan::math::eigenvectors_sym and stan::math::eigenvalues_sym now returns symmetric matrix (previously lower triangular).

Checklist

@bob-carpenter
Copy link
Contributor

Thanks! The code for this looks beautiful and is well-documented and references. I don't quite feel up to reviewing the linear algebra here or the implications for matrix autodiff. I'm totally happy to sign off on the code, especially as we have generic autodiff tests in place already.

@stan-buildbot
Copy link
Contributor


Name Old Result New Result Ratio Performance change( 1 - new / old )
gp_pois_regr/gp_pois_regr.stan 5.07 5.09 1.0 -0.24% slower
low_dim_corr_gauss/low_dim_corr_gauss.stan 0.02 0.02 1.0 -0.3% slower
eight_schools/eight_schools.stan 0.09 0.09 0.98 -1.82% slower
gp_regr/gp_regr.stan 0.22 0.23 0.99 -1.09% slower
irt_2pl/irt_2pl.stan 6.56 6.57 1.0 -0.16% slower
performance.compilation 85.32 86.46 0.99 -1.33% slower
low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan 7.71 7.69 1.0 0.18% faster
pkpd/one_comp_mm_elim_abs.stan 20.37 20.62 0.99 -1.26% slower
sir/sir.stan 95.64 95.12 1.01 0.55% faster
gp_regr/gen_gp_data.stan 0.05 0.05 1.0 -0.31% slower
low_dim_gauss_mix/low_dim_gauss_mix.stan 3.01 3.06 0.98 -1.53% slower
pkpd/sim_one_comp_mm_elim_abs.stan 0.33 0.32 1.02 2.23% faster
arK/arK.stan 1.84 1.82 1.01 0.61% faster
arma/arma.stan 0.83 0.83 1.0 0.27% faster
garch/garch.stan 0.56 0.57 0.99 -0.5% slower
Mean result: 0.996973205053

Jenkins Console Log
Blue Ocean
Commit hash: ac9ee2e


Machine information ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010

CPU:
Intel(R) Xeon(R) CPU E5-1680 v2 @ 3.00GHz

G++:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

Clang:
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

@bbbales2 bbbales2 self-assigned this May 18, 2020
Copy link
Member

@bbbales2 bbbales2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! Looks good, just a couple simplifications. For the eigenvalues function, you don't need to make eigenvector varis (there won't be any vars created for these eigenvectors). Same for the eigenvectors function.

A little bit of math disappears from the chains as well (the adjoints of the eigenvectors for the eigenvalues function will be zero).

stan/math/rev/fun/eigenvalues_sym.hpp Outdated Show resolved Hide resolved
stan/math/rev/fun/eigenvalues_sym.hpp Outdated Show resolved Hide resolved
stan/math/rev/fun/eigenvalues_sym.hpp Outdated Show resolved Hide resolved
stan/math/rev/fun/eigenvectors_sym.hpp Outdated Show resolved Hide resolved
stan/math/rev/fun/eigenvectors_sym.hpp Outdated Show resolved Hide resolved
@IvanYashchuk
Copy link
Contributor Author

@bbbales2, thank you for the review! I think I've addressed the comments.

@bbbales2
Copy link
Member

Thanks! Yeah the code looks great. I was just having a look at the original issue: #1803

I'm not convinced we want to do the full matrix of derivatives, if that makes sense. Can you take a look at what I posted over there? I kinda think the lower triangle is the way to go, as weird as that may seem.

@bbbales2
Copy link
Member

I kinda think

And by this argue back and tell me I'm wrong if I'm wrong I'm just trying to square it all in my head so I know what to do going forward.

@stan-buildbot
Copy link
Contributor


Name Old Result New Result Ratio Performance change( 1 - new / old )
gp_pois_regr/gp_pois_regr.stan 3.98 4.02 0.99 -1.03% slower
low_dim_corr_gauss/low_dim_corr_gauss.stan 0.02 0.02 0.95 -5.34% slower
eight_schools/eight_schools.stan 0.09 0.09 0.96 -4.59% slower
gp_regr/gp_regr.stan 0.19 0.19 1.0 0.24% faster
irt_2pl/irt_2pl.stan 6.56 6.56 1.0 -0.02% slower
performance.compilation 86.73 86.53 1.0 0.22% faster
low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan 7.73 7.72 1.0 0.1% faster
pkpd/one_comp_mm_elim_abs.stan 20.69 21.55 0.96 -4.15% slower
sir/sir.stan 92.32 92.41 1.0 -0.09% slower
gp_regr/gen_gp_data.stan 0.04 0.04 1.0 -0.17% slower
low_dim_gauss_mix/low_dim_gauss_mix.stan 3.04 3.08 0.99 -1.25% slower
pkpd/sim_one_comp_mm_elim_abs.stan 0.32 0.33 0.97 -3.34% slower
arK/arK.stan 2.42 2.45 0.99 -1.04% slower
arma/arma.stan 0.61 0.61 1.0 -0.28% slower
garch/garch.stan 0.52 0.52 1.0 -0.1% slower
Mean result: 0.986627662748

Jenkins Console Log
Blue Ocean
Commit hash: b2ab104


Machine information ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010

CPU:
Intel(R) Xeon(R) CPU E5-1680 v2 @ 3.00GHz

G++:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

Clang:
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

@stan-buildbot
Copy link
Contributor


Name Old Result New Result Ratio Performance change( 1 - new / old )
gp_pois_regr/gp_pois_regr.stan 4.04 4.05 1.0 -0.28% slower
low_dim_corr_gauss/low_dim_corr_gauss.stan 0.02 0.02 1.0 0.2% faster
eight_schools/eight_schools.stan 0.09 0.09 0.96 -4.45% slower
gp_regr/gp_regr.stan 0.19 0.19 1.0 0.49% faster
irt_2pl/irt_2pl.stan 6.59 6.58 1.0 0.12% faster
performance.compilation 86.97 86.23 1.01 0.84% faster
low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan 7.77 7.7 1.01 0.95% faster
pkpd/one_comp_mm_elim_abs.stan 21.68 20.37 1.06 6.03% faster
sir/sir.stan 92.77 92.52 1.0 0.27% faster
gp_regr/gen_gp_data.stan 0.04 0.04 0.99 -0.66% slower
low_dim_gauss_mix/low_dim_gauss_mix.stan 3.2 3.04 1.05 5.01% faster
pkpd/sim_one_comp_mm_elim_abs.stan 0.31 0.31 0.99 -1.48% slower
arK/arK.stan 2.43 2.42 1.0 0.25% faster
arma/arma.stan 0.61 0.61 1.01 0.86% faster
garch/garch.stan 0.52 0.52 1.0 -0.13% slower
Mean result: 1.00595463618

Jenkins Console Log
Blue Ocean
Commit hash: b2ab104


Machine information ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010

CPU:
Intel(R) Xeon(R) CPU E5-1680 v2 @ 3.00GHz

G++:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

Clang:
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

@bbbales2
Copy link
Member

I'm gonna just merge this once the tests pass. I didn't notice they were hung up.

@stan-buildbot
Copy link
Contributor


Name Old Result New Result Ratio Performance change( 1 - new / old )
gp_pois_regr/gp_pois_regr.stan 4.13 4.01 1.03 2.74% faster
low_dim_corr_gauss/low_dim_corr_gauss.stan 0.02 0.02 0.98 -1.92% slower
eight_schools/eight_schools.stan 0.09 0.09 1.0 -0.4% slower
gp_regr/gp_regr.stan 0.2 0.19 1.05 4.88% faster
irt_2pl/irt_2pl.stan 6.57 6.56 1.0 0.08% faster
performance.compilation 85.34 86.06 0.99 -0.84% slower
low_dim_gauss_mix_collapse/low_dim_gauss_mix_collapse.stan 7.79 7.71 1.01 1.06% faster
pkpd/one_comp_mm_elim_abs.stan 20.82 20.83 1.0 -0.02% slower
sir/sir.stan 92.51 94.49 0.98 -2.14% slower
gp_regr/gen_gp_data.stan 0.04 0.04 1.01 0.95% faster
low_dim_gauss_mix/low_dim_gauss_mix.stan 3.03 3.08 0.98 -1.8% slower
pkpd/sim_one_comp_mm_elim_abs.stan 0.32 0.31 1.04 3.77% faster
arK/arK.stan 2.41 2.42 1.0 -0.35% slower
arma/arma.stan 0.6 0.61 0.98 -1.72% slower
garch/garch.stan 0.52 0.52 1.01 1.15% faster
Mean result: 1.00407535416

Jenkins Console Log
Blue Ocean
Commit hash: a2d62b7


Machine information ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G22010

CPU:
Intel(R) Xeon(R) CPU E5-1680 v2 @ 3.00GHz

G++:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

Clang:
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.6.0
Thread model: posix

@bbbales2
Copy link
Member

@rok-cesnovar this is good to go. I made a change to how the tests are organized (just moved code from mix to rev in tests here), so I'm just leaving this to you to check I didn't do anything obviously silly and merge.

@rok-cesnovar
Copy link
Member

That change look ok to me. The test tests rev so that is where it should be. Merging.

@rok-cesnovar rok-cesnovar merged commit d584931 into stan-dev:develop May 23, 2020
@IvanYashchuk IvanYashchuk deleted the feature/issue-989-rev-mat-eig2 branch May 23, 2020 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants