math icon indicating copy to clipboard operation
math copied to clipboard

Improve Numerical Stability of Bernoulli CDF functions

Open andrjohns opened this issue 3 years ago • 2 comments

Summary

This PR updates the Bernoulli CDF functions (_cdf, _lcdf, and _lccdf) to operate on the log scale as much as possible, to avoid issues with underflow and resolution around 1

Tests

Additional mix/prob tests have been added to ensure that the gradients aren't impacted (prim behaviour covered by the distribution tests)

Side Effects

N/A

Release notes

Improved numerical stability of Bernoulli CDF functions

Checklist

  • [x] Math issue #2783

  • [x] Copyright holder: Andrew Johnson

    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/)

  • [x] the basic tests are passing

    • unit tests pass (to run, use: ./runTests.py test/unit)
    • header checks pass, (make test-headers)
    • dependencies checks pass, (make test-math-dependencies)
    • docs build, (make doxygen)
    • code passes the built in C++ standards checks (make cpplint)
  • [x] the code is written in idiomatic C++ and changes are documented in the doxygen

  • [x] the new changes are tested

andrjohns avatar Jul 08 '22 04:07 andrjohns

@andrjohns: please let me know when this is ready to review and merge. Thanks!

bob-carpenter avatar Jul 12 '22 14:07 bob-carpenter

Thanks @bob-carpenter! This is ready for another look. I've updated the vectorisation by adding a prim implementation of the select function that is currently used by the OpenCL code for the same purpose (ternary operations that can be agnostic between scalar and Eigen inputs)

andrjohns avatar Jul 13 '22 07:07 andrjohns

@SteveBronder when you have a minute (no rush at all), can you have a look at this PR? It involves re-implementing the the OpenCL code's select function, so would be great to have eyes on from someone that knows how it should be behaving

andrjohns avatar Oct 21 '22 07:10 andrjohns

@bob-carpenter are you able to re-review this?

@SteveBronder are you able to double check the opencl select code?

spinkney avatar Oct 26 '22 09:10 spinkney

dismiss the closed/reopened, I hit the trackpad on my laptop by accident

spinkney avatar Oct 26 '22 09:10 spinkney

Thanks for the heads up. I just dismissed my review so that someone else could review it. I still don't feel I understand our new C++ conventions well enough to review PRs.

bob-carpenter avatar Oct 27 '22 10:10 bob-carpenter

Sorry didn't have time today but Tuesday I can look at this

SteveBronder avatar Oct 27 '22 21:10 SteveBronder

@SteveBronder I'll add an any() function, since I agree that would be super handy. Should I open a separate PR for the select() and any() functions and tests, or are you happy for me to include them in this one?

andrjohns avatar Nov 15 '22 09:11 andrjohns

I'll update this PR once the helper functions from #2852 have been added and merged

andrjohns avatar Dec 10 '22 15:12 andrjohns

@SteveBronder would you mind having another look at this when you get a minute? No rush

andrjohns avatar Aug 15 '23 16:08 andrjohns

develop tests have been failing in the distribution tests since this was merged (https://jenkins.flatironinstitute.org/blue/organizations/jenkins/Stan%2FMath/detail/develop/194/pipeline/500)

I'm guessing this is due to -DSTAN_TEST_ROW_VECTORS which we don't use in CI for PRs

In file included from test/prob/bernoulli/bernoulli_cdf_00000_generated_ffv_test.cpp:3:
In file included from ./test/prob/test_fixture_distr.hpp:4:
In file included from ./stan/math/mix.hpp:4:
In file included from ./stan/math/mix/meta.hpp:6:
In file included from ./stan/math/fwd/core.hpp:4:
In file included from ./stan/math/fwd/core/fvar.hpp:4:
In file included from ./stan/math/prim/meta.hpp:72:
In file included from ./stan/math/prim/meta/append_return_type.hpp:4:
In file included from ./stan/math/prim/fun/Eigen.hpp:22:
In file included from lib/eigen_3.4.0/Eigen/Dense:1:
In file included from lib/eigen_3.4.0/unsupported/Eigen/../../Eigen/Core:295:
lib/eigen_3.4.0/Eigen/src/Core/PlainObjectBase.h:970:7: error: static_assert failed "INVALID_MATRIX_TEMPLATE_PARAMETERS"
      EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (int(Options)&RowMajor)==RowMajor)
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/eigen_3.4.0/Eigen/src/Core/util/StaticAssert.h:33:40: note: expanded from macro 'EIGEN_STATIC_ASSERT'
    #define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
                                       ^             ~
lib/eigen_3.4.0/Eigen/src/Core/Map.h:159:30: note: in instantiation of member function 'Eigen::PlainObjectBase<Eigen::Array<stan::math::var_value<double, void>, 1, -1, 0, 1, -1> >::_check_template_params' requested here
      PlainObjectType::Base::_check_template_params();
                             ^
./stan/math/rev/core/arena_matrix.hpp:62:9: note: in instantiation of member function 'Eigen::Map<Eigen::Array<stan::math::var_value<double, void>, 1, -1, 0, 1, -1>, 0, Eigen::Stride<0, 0> >::Map' requested here
      : Base::Map(

@andrjohns are you able to take a look at this soon? Otherwise I think we may need to revert this to unblock our CI

WardBrian avatar Sep 30 '23 15:09 WardBrian

Ah damn, yeah I'll have a look now

andrjohns avatar Sep 30 '23 16:09 andrjohns