-
-
Notifications
You must be signed in to change notification settings - Fork 190
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 issue 3146 for multiply_log #3147
base: develop
Are you sure you want to change the base?
Conversation
…most of the template function for offset_multiplier to simplify
Does this affect stan-dev/stan#3330 or is it unrelated? |
This is just #3146 I'm writing a separate PR for stan-dev/stan#3330 |
Jenkins Console Log Machine informationNo LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.3 LTS Release: 20.04 Codename: focalCPU: G++: Clang: |
Jenkins Console Log Machine informationNo LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.3 LTS Release: 20.04 Codename: focalCPU: G++: Clang: |
@nhuurre or @andrjohns would either of you mind taking a look at this? @nhuurre Brian pointed out you handled #3033 which is very similar |
Can these scalar/matrix/etc overloads all be condensed? They all follow a similar pattern/logic (afaict). We have |
Does lmultiply need to also be considered? |
Huh, I didn't realize lmultiply even really existed in the math library. I'm pretty sure the stan compiler still just rewrites it to They definitely should be consistent between the two |
…inations of matrices and scalars
…inations of matrices and scalars
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.
Brian pointed out you handled #3033 which is very similar
You mean similar to the part that handles 0*log(0)
corner case. Most of this PR is if-constexpr-template magic that goes way over my head.
* NOTE: We do not test values of (0.0, 0.0) as inputs. | ||
* This is because the testing framework uses | ||
* finite difference as the comparison. The small finite | ||
* purtubations lead to cases where the value of the | ||
* function inputs is either slightly negative or slightly positive, | ||
* which can lead to the function returning NaN when we would expect a | ||
* value of 0. |
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.
Some testing is still technically possible. On #3033 I added a test that tricks the finite difference calculation by extending the function symmetrically.
Here that would be
return multiply_log((x1 >= 0) ? x1 : -x1, (x2 >= 0) ? x2 : -x2);
(i.e. multiply_log(|x1|,|x2|)
without using stan::math::abs
since it would overwrite the autodiff derivatives)
However, I do not like this hack. The value added by such a test is low compared to the effort required to understand what it does and why it works.
It's better to extend the test framework. stan::test::test_ad
needs both positive and negative perturbations because it compares autodiff to central finite differences. It shouldn't be hard to work out the equations for lateral finite differences which need perturbations only in one direction (but are less accurate). I can try and add something like stan::test::test_ad_positive
if you want.
Positive-perturbation-only test can handle multiply_log(0, x)
. But the derivative of multiply_log(x, 0)
is formally infinite so finite difference is going to blow up anyway. Maybe we need a stan::test::test_ad
variant that just checks the autodiff derivatives are finite but does not compare them with any reference value.
This is, luckily, the part that I feel comfortable reviewing, so between the two of us it seems likely we will be able to make it work |
Summary
Fixes #3146 by making the deduction for branch logic be compile time using
if constexpr
. This also cleans up a lot of the code foroffset_multiply_constrain
. Instead of having all combinations of signatures for vector inputs we just use a littleif constexpr
to deduce which inputs need iterated over.Tests
There is 1 new test in
rev
for testing issue #3146 specifically. You can run all tests associated with this PR viaSide Effects
Nope
Release notes
Fix issue so that rep_matrix can be used inside of offset_multiplier constraints.
Checklist
Copyright holder: Simons Foundation
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