-
-
Notifications
You must be signed in to change notification settings - Fork 183
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
adding input checks for cholesky factors #3002
Conversation
@syclik I fixed the issue and pushed. Also I updated the tests to reflect the cholesky check and fixed a ref to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix was to switch the factors and use mdivide_right_tri_low
. I misread the paper as having the math on a lower tri factor.
I also updated the test to check that it gives, on average, the same values as inv_wishart_rng
for the full covariance matrix.
Thank you!!! I was going to get around to it soon.
Seth replied on slack. Sounded like there was another issue that’s
different from input checking in Julia.
…On Tue, Jan 16, 2024 at 8:19 PM Sean Pinkney ***@***.***> wrote:
@syclik <https://github.com/syclik> I fixed the issue and pushed. Also I
updated the tests to reflect the cholesky check and fixed a ref to nu.
—
Reply to this email directly, view it on GitHub
<#3002 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADH6F2ICJA57QDX652DXV3YO4RKVAVCNFSM6AAAAABBY5PQK2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJUG43TSOJQHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@@ -105,7 +105,7 @@ TEST(ProbDistributionsMultiNormalCholesky, opencl_matches_cpu_small) { | |||
std::vector<Eigen::VectorXd> mu3{mu1, mu2}; | |||
std::vector<Eigen::RowVectorXd> mu4{mu2, mu1}; | |||
Eigen::MatrixXd L(N, N); | |||
L << 1, 0, 0, 2, 3, 0, -4, 5, -6; | |||
L << 4, 0, 0, -1, 1, 0, -4, -2, 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: the original code is not a valid cholesky factor! The test was passing incorrectly.
@syclik the test
|
That's a pretty big value. Let me see what's going on with that test. |
The issue is with this test Eigen::MatrixXd y22(2, 2);
y22 << 1.0, 0.1, 0.1, 1.5;
Eigen::MatrixXd L_Y22 = y22.llt().matrixL();
Eigen::MatrixXd Sigma22(2, 2);
Sigma22 << 1.5, 0.5, 0.5, 1.1;
Eigen::MatrixXd L_S22 = Sigma22.llt().matrixL();
stan::test::expect_ad(f, L_Y22, dof, L_S22); Finite differences incorrectly perturbs the upper triangular element of the 2 x 2 matrix. Printing out the values of both the cholesky factor matrices shows that the inputs are lower triangular and the 1, 2 element is 0. This error will again happen with the @WardBrian @SteveBronder how do we update these tests for cholesky factors? Or should we just remove the check (in both the inv and regular wishart cholesky lpdfs) which is what @syclik is trying to add here? |
You could change the test functor to call |
I was looking for an equivalent expect_ad_ that accounted for cholesky
factors.
I can imagine either building a new one, updating f so that it passes if
the term is not a cholesky factor, or passing in the matrix and using f to
create cholesky factors of the matrix (I think this may still have weird
errors if the matrix does not have good properties).
I’ll search for how we deal with other constrained types (like symmetric
matrix).
…On Wed, Jan 17, 2024 at 6:31 AM Sean Pinkney ***@***.***> wrote:
The issue is with this test
Eigen::MatrixXd y22(2, 2);
y22 << 1.0, 0.1, 0.1, 1.5;
Eigen::MatrixXd L_Y22 = y22.llt().matrixL();
Eigen::MatrixXd Sigma22(2, 2);
Sigma22 << 1.5, 0.5, 0.5, 1.1;
Eigen::MatrixXd L_S22 = Sigma22.llt().matrixL();
stan::test::expect_ad(f, L_Y22, dof, L_S22);
Finite differences incorrectly perturbs the upper triangular element of
the 2 x 2 matrix. Printing out the values of both the cholesky factor
matrices shows that the inputs are lower triangular and the 1, 2 element is
0.
This error will again happen with the wishart_cholesky_lpdf in
prob_3_test.cpp.
@WardBrian <https://github.com/WardBrian> @SteveBronder
<https://github.com/SteveBronder> how do we update these tests for
cholesky factors? Or should we just remove the check (in both the inv and
regular wishart cholesky lpdfs) which is what @syclik
<https://github.com/syclik> is trying to add here?
—
Reply to this email directly, view it on GitHub
<#3002 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADH6F2V2MBTFMM2CEX47Q3YO6ZCXAVCNFSM6AAAAABBY5PQK2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJVGYZDENRSGQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Update: ignore this message. I was incorrect. @spinkney, just FYI, it's not where you thought. I added prints (because we can't tell where it failed from the output). It's in the first call to
|
@spinkney, ignore the last message; it fails before that. I misread my prints and thought it was further along. |
I tried writing a new functor and the test fails to compile.
Results in a compiler novel with the first error message:
|
@spinkney I think what @andrjohns suggested is the best idea, treat the function This is what we do for e.g. auto f = [](const auto& y) {
// need to maintain symmetry for finite diffs
auto a = ((y + y.transpose()) * 0.5).eval();
return stan::math::eigenvalues_sym(a);
}; |
@WardBrian I don't know how to update the generated jumbo test to have this new functor automatically included in the tests. Secondly, using Eigen's llt() results in a ton of template errors (see @syclik comment). If I use |
The jumbo tests are literally just compiling multiple existing tests at once to save on time. If you update the individual unit test files, the jumbos will be updated. The only place we're actually generating test code is in the expression tests. If those also need customization, you can do that by editing the dictionaries in https://github.com/stan-dev/math/blob/develop/test/sig_utils.py |
@syclik's code can be made to compile if you force evaluation of the expression, like so: auto f = [](const auto& L_Y, const auto& dof, const auto& Sigma) {
auto L_S = Sigma.llt().matrixL();
stan::plain_type_t<decltype(L_S)> L_S_plain = L_S;
return stan::math::inv_wishart_cholesky_lpdf(L_Y, dof, L_S_plain);
}; To me this seems like something we'd want the lpdf to be able to handle itself... However, you would also need to comment out the |
Using this as auto f = [](const auto& L_Y, const auto& dof, const auto& Sigma) {
auto L_S = stan::math::cholesky_decompose(Sigma);
stan::plain_type_t<decltype(L_S)> L_S_plain = L_S;
return stan::math::inv_wishart_cholesky_lpdf(L_Y, dof, L_S);
}; We'd probably also want to use something like |
Is |
eba3fc3
to
680b1a9
Compare
I'm trying to work through the expression tests that failed. |
To enable this to be in 4.8.1 without a ton of extra hassle I've created a branch called If not, you can just change the target branch back to |
…. New code properly catches the error.
2565ff0
to
ea31dad
Compare
Closing. We can use the other PR #3007. |
Please do not merge this PR. I reopened to kick off tests. #3007 isn't running tests. |
Closing this PR. #3007 is the PR that should be merged. |
Summary
We weren't checking cholesky factors in the code in multivariate distributions. This appeared in a user-facing RNG generating NaN for all quantities.
The fix here is to validate input arguments.
Tests
No new tests.
For anyone reviewing, if it makes sense, please let me know what should be tested.
Side Effects
Some existing models may no longer work if they accepted matrixes and computed something (even if it's non-sensical).
Release notes
Added checks for Cholesky factors in multi-variate distributions.
Checklist
Copyright holder: Daniel Lee
The copyright holder is typically you or your assignee, such as a university or company. By submitting this pull request, the copyright holder is agreeing to the license the submitted work under the following licenses:
- Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)
- Documentation: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
the basic tests are passing
./runTests.py test/unit
)make test-headers
)make test-math-dependencies
)make doxygen
)make cpplint
)the code is written in idiomatic C++ and changes are documented in the doxygen
the new changes are tested