-
-
Notifications
You must be signed in to change notification settings - Fork 188
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
fix matrix_exp_multiply accuracy bug #2619
Conversation
…4.1 (tags/RELEASE_600/final)
…4.1 (tags/RELEASE_600/final)
…4.1 (tags/RELEASE_600/final)
I'm not sure how to interpret the failure of expression test (tests7_test.cpp). @rok-cesnovar can you take a look? |
If I run it locally for the matrix_exp_multiply only (
It seemed as if the second matrix would be an Eigen expression it would be evaluated twice. And it was, see last commit for the fix. |
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.
I honestly have zero knowledge of these algorithms, so cant review the changes in the sense of correctness, here are just a few general code-related comments.
I was able to reproduce the expression test failure on linux but not on mac. @rok-cesnovar can you take another look? Thanks. |
Will check tomorrow. |
I am unable to replicate locally (even with clang++-6.0) on Ubuntu. My next guess would be that the instance runs out of memory compiling 15 tests in parallel or something along these lines. Not sure why that would happen after this change, but who knows. Decreasing the parallel We are in the middle of a move of our testing infrastructure, so there will be a bit of downtime or a period of unrelated issues popping up, so testing on the actual instances will be a bit difficult in the next few day, but will make sure to test this as soon we are back up. |
@rok-cesnovar thanks. We can continue after the migration. |
…4.1 (tags/RELEASE_600/final)
Getting back to this finally.
|
8ed5a59
to
a53874a
Compare
// L1 norm | ||
double normA = mat.colwise().template lpNorm<1>().maxCoeff(); | ||
|
||
if (normA < tol || t < tol) { | ||
m = 0; | ||
s = 1; |
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.
I'd want to eagerly return here so it's clear that there's no more that happens below it.
That will unnest the lower else
statement and it'll be slightly easier to read.
const std::vector<double>& theta = theta_m_double; | ||
Eigen::VectorXd alpha(p_max - 1); | ||
|
||
if (normA |
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.
for efficiency, I'd move the / (m_max * b.cols())
to the left hand side by * (m_max * b.cols())
.
m = m_max; | ||
const std::vector<double>& theta = theta_m_double; | ||
Eigen::VectorXd alpha(p_max - 1); | ||
|
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.
I would put whitespace above 185 and remove the whitespace in 186.
The output of the if
statement here is alpha
. We want to keep that declaration close together if possible for readability.
@yizhang-yiz, for what it's worth, it's implemented really cleanly relative to the paper. The naming convention follows and is close. It looks right to me. |
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 implementation looks good to me.
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.
lgtm
@syclik I completely let this slip through. Thanks for fixing the PR! |
Looks like the "fix" I introduced causes it to have linking issues with multiple translation units. From Jenkins https://jenkins.flatironinstitute.org/blue/organizations/jenkins/Stan%2FMath/detail/PR-2619/11/pipeline/214: I believe this is real. I'll try to address it in a different way. |
I'm looking at the intent of the code and I think the optimization is too much effort relative to the difficulty in getting it working reliably across C++ versions. To be specific, there are two major optimizations happening. The first is that the variable is a static class member variable. I believe the idea is that on multiple uses of the class these constants don't have to be reallocated with the class. This, in and of itself, is great, but it interacts with the second thing. The second is the use of So... I think we can simplify this a bit and lose this optimization. Note: this is for 3 primitives only. I doubt it'd be that much of a difference in practice. |
Also, this would be dominated by the allocation of the |
…renaming for consistency
Summary
Fix #2529 by re-implementing the
prim
version of the function.Tests
matrix_exp_multiply_handle
components that calculate the taylor expansion order and helper function approximating matrix power norm.Side Effects
n/a
Release notes
Bugfix:
matrix_exp_multiply
function's accuracy issue.Checklist
Math issue #(issue number)
Copyright holder: Metrum Research Group.
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