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

Improved behavior of expect_near_rel #1657

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
80b2ba1
Implemented the tolerance
martinmodrak Jan 29, 2020
775a705
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 29, 2020
dee6551
Avoid lint for relative_tolerance(double)
martinmodrak Jan 30, 2020
e36ccfd
Making tests pass.
martinmodrak Jan 30, 2020
ecc813c
Merge commit '5b6bd37c32c7a9094981508a348360c97e0db763' into HEAD
yashikno Jan 30, 2020
82c0231
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 30, 2020
33c5cd9
Some progress on mix tests
martinmodrak Jan 30, 2020
6537eed
More effort to pass tests
martinmodrak Jan 30, 2020
56f8dfa
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 30, 2020
16897c7
[Jenkins] auto-formatting by clang-format version 5.0.0-3~16.04.1 (ta…
stan-buildbot Jan 30, 2020
bde57c3
Fixed trigamma test
martinmodrak Jan 30, 2020
ff274e2
Stricter default tolerance
martinmodrak Jan 30, 2020
11a4230
Reverted to 1e-14 default tol_min
martinmodrak Jan 30, 2020
fbb4453
Increase tolerance in quad_form_diag_test
martinmodrak Jan 30, 2020
1a915e4
Actually use tols from the previous commit
martinmodrak Jan 30, 2020
1a9c571
Documentation
martinmodrak Jan 31, 2020
4ce67d6
Merge commit 'dc096aa6a66f7cd95cb29b50fe47680556187aa1' into HEAD
yashikno Jan 31, 2020
312c4a7
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Jan 31, 2020
ec64f65
Merge remote-tracking branch 'stan-dev/develop' into feature/1656-exp…
martinmodrak Feb 4, 2020
c2d5024
Changed relative_tolerance to class, naming
martinmodrak Feb 4, 2020
f54c4a0
[Jenkins] auto-formatting by clang-format version 6.0.0 (tags/google/…
stan-buildbot Feb 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions test/unit/math/ad_tolerances.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef TEST_UNIT_MATH_AD_TOLERANCES_HPP
#define TEST_UNIT_MATH_AD_TOLERANCES_HPP

#include <test/unit/math/relative_tolerance.hpp>

namespace stan {
namespace test {

Expand All @@ -13,34 +15,35 @@ namespace test {
* if the function is implemented using only forward mode, and end
* with the quantity being calculated; for example,
* `hessian_fvar_grad_` is the gradient calculated by the `hessian`
* function using forward-mode autodiff.
* function using forward-mode autodiff. Those get interpreted as
* relative tolerances, see `relative_tolerance` class more details.
*
* `gradient_val_`: 1e-8; `gradient_grad_`: 1e-4
*
* `gradient_fvar_val_`: 1e-8; `gradient_fvar_grad_`: 1e-4
*
* `hessian_val_` : 1e-8; `hessian_grad_`: 1e-4; `hessian_hessian_`: 1e-3
* `hessian_val_` : 1e-8; `hessian_grad_`: 1e-4; `hessian_hessian_`: (1e-4,1e-3)
*
* `hessian_fvar_val_` : 1e-8; `hessian_fvar_grad_`: 1e-4;
* `hessian_fvar_hessian_`: 1e-3
* `hessian_fvar_hessian_`: (1e-4,1e-3)
*
* `grad_hessian_val_` : 1e-8; `grad_hessian_hessian_`: 1e-3;
* `grad_hessian_grad_hessian_`: 1e-2
*/
struct ad_tolerances {
double gradient_val_;
double gradient_grad_;
double gradient_fvar_val_;
double gradient_fvar_grad_;
double hessian_val_;
double hessian_grad_;
double hessian_hessian_;
double hessian_fvar_val_;
double hessian_fvar_grad_;
double hessian_fvar_hessian_;
double grad_hessian_val_;
double grad_hessian_hessian_;
double grad_hessian_grad_hessian_;
relative_tolerance gradient_val_;
relative_tolerance gradient_grad_;
relative_tolerance gradient_fvar_val_;
relative_tolerance gradient_fvar_grad_;
relative_tolerance hessian_val_;
relative_tolerance hessian_grad_;
relative_tolerance hessian_hessian_;
relative_tolerance hessian_fvar_val_;
relative_tolerance hessian_fvar_grad_;
relative_tolerance hessian_fvar_hessian_;
relative_tolerance grad_hessian_val_;
relative_tolerance grad_hessian_hessian_;
relative_tolerance grad_hessian_grad_hessian_;
ad_tolerances()
: gradient_val_(1e-8),
gradient_grad_(1e-4),
Expand All @@ -50,11 +53,11 @@ struct ad_tolerances {

hessian_val_(1e-8),
hessian_grad_(1e-4),
hessian_hessian_(1e-3),
hessian_hessian_(1e-4, 1e-3),

hessian_fvar_val_(1e-8),
hessian_fvar_grad_(1e-4),
hessian_fvar_hessian_(1e-3),
hessian_fvar_hessian_(1e-4, 1e-3),

grad_hessian_val_(1e-8),
grad_hessian_hessian_(1e-3),
Expand Down
38 changes: 11 additions & 27 deletions test/unit/math/expect_near_rel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <stan/math.hpp>
#include <gtest/gtest.h>
#include <test/unit/math/relative_tolerance.hpp>
#include <string>
#include <vector>

Expand All @@ -15,13 +16,7 @@ namespace internal {
* Test that the specified values are within the specified tolerance
* on relative error, and if not, fail the embedded google test.
*
* <p>Relative error is defined to be the error `u - v` rescaled by the
* average absolute value,
* `rel_err(u, v) = (u - v) / (0.5 * (abs(u) * + abs(v))).`
*
* <p>If at least one of `u` or `v` is zero, the absolute error is
* tested at the specified tolerance, because the relative error
* reduces to a constant.
* Uses relative_tolerance::inexact to compute the tolerance.
*
* @tparam T1 type of first argument
* @tparam T2 type of second argument
Expand All @@ -32,23 +27,11 @@ namespace internal {
*/
template <typename T1, typename T2, require_all_stan_scalar_t<T1, T2>...>
void expect_near_rel_finite(const std::string& msg, const T1& x1, const T2& x2,
double tol = 1e-8) {
using stan::math::fabs;
// if either arg near zero, must use absolute tolerance as rel tol -> 2
if (fabs(x1) < tol || fabs(x2) < tol) {
EXPECT_NEAR(x1, x2, tol) << "expect_near_rel_finite(" << x1 << ", " << x2
<< ", absolute tolerance = " << tol << ")"
<< "; absolute diff = " << fabs(x1 - x2)
<< " in: " << msg << std::endl;
return;
}
auto avg = 0.5 * (fabs(x1) + fabs(x2));
auto relative_diff = (x1 - x2) / avg;
EXPECT_NEAR(0, relative_diff, tol)
<< "expect_near_rel_finite(" << x1 << ", " << x2
<< ", relative tolerance = " << tol << ")"
<< "; relative diff = " << relative_diff << std::endl
<< " in: " << msg << std::endl;
const relative_tolerance tol
= relative_tolerance()) {
double tol_val = tol.inexact(x1, x2);
EXPECT_NEAR(x1, x2, tol_val)
<< "expect_near_rel_finite in: " << msg << std::endl;
}

template <typename EigMat1, typename EigMat2,
Expand Down Expand Up @@ -89,7 +72,7 @@ void expect_near_rel_finite(const std::string& msg, const std::vector<T1>& x1,
*/
template <typename T1, typename T2, require_all_stan_scalar_t<T1, T2>...>
void expect_near_rel(const std::string& msg, const T1& x1, const T2& x2,
double tol = 1e-8) {
relative_tolerance tol = relative_tolerance()) {
if (stan::math::is_nan(x1) || stan::math::is_nan(x2))
EXPECT_TRUE(stan::math::is_nan(x1) && stan::math::is_nan(x2))
<< "expect_near_rel(" << x1 << ", " << x2 << ")" << std::endl
Expand Down Expand Up @@ -120,7 +103,7 @@ void expect_near_rel(const std::string& msg, const T1& x1, const T2& x2,
template <typename EigMat1, typename EigMat2,
require_all_eigen_t<EigMat1, EigMat2>...>
void expect_near_rel(const std::string& msg, EigMat1&& x1, EigMat2&& x2,
double tol = 1e-8) {
relative_tolerance tol = relative_tolerance()) {
EXPECT_EQ(x1.rows(), x2.rows()) << "expect_near_rel (Eigen::Matrix)"
<< " rows must be same size."
<< " x1.rows() = " << x1.rows()
Expand All @@ -141,7 +124,8 @@ void expect_near_rel(const std::string& msg, EigMat1&& x1, EigMat2&& x2,

template <typename T1, typename T2>
void expect_near_rel(const std::string& msg, const std::vector<T1>& x1,
const std::vector<T2>& x2, double tol = 1e-8) {
const std::vector<T2>& x2,
relative_tolerance tol = relative_tolerance()) {
EXPECT_EQ(x1.size(), x2.size()) << "expect_near_rel (std::vector):"
<< " vectors must be same size."
<< " x1.size() = " << x1.size()
Expand Down
20 changes: 11 additions & 9 deletions test/unit/math/expect_near_rel_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ TEST(testUnitMath, ExpectNearRelScalar) {
expect_near_rel("test A1", 0, 0, 1e-16);
expect_near_rel("test A2", 0, 0.0, 1e-16);
expect_near_rel("test A3", 0.0, 0, 1e-16);
expect_near_rel("test B1", 0, 1e-8, 1e-5);
expect_near_rel("test B2", 0.0, 1e-8, 1e-5);
expect_near_rel("test C1", 1e-8, 0, 1e-5);
expect_near_rel("test C2", 1e-8, 0.0, 1e-5);
expect_near_rel("test B1", 0, 1e-8, 1e-4);
expect_near_rel("test B2", 0.0, 1e-8, 1e-4);
expect_near_rel("test C1", 1e-8, 0, 1e-4);
expect_near_rel("test C2", 1e-8, 0.0, 1e-4);

// non-zero examples
expect_near_rel("test D1", 1, 1, 1e-16);
Expand All @@ -33,6 +33,7 @@ TEST(testUnitMath, ExpectNearRelScalar) {
TEST(testUnitMath, ExpectNearRelMatrix) {
using Eigen::Matrix;
using stan::test::expect_near_rel;
using stan::test::relative_tolerance;
typedef Matrix<double, -1, 1> v_t;
typedef Matrix<double, 1, -1> rv_t;
typedef Matrix<double, -1, -1> m_t;
Expand All @@ -57,7 +58,7 @@ TEST(testUnitMath, ExpectNearRelMatrix) {
m_t d2(2, 3);
d1 << 1, 2, 3, 0, 0, 0 - 1e-8;
d2 << 1 + 1e-8, 2 - 1e-8, 3, 0, 0 + 1e-8, 0;
expect_near_rel("test D", d1, d2, 1e-6);
expect_near_rel("test D", d1, d2, relative_tolerance(1e-6, 1e-8));

// these will fail
// v_t e1(1);
Expand All @@ -82,7 +83,7 @@ TEST(testUnitMath, ExpectNearRelVector) {

expect_near_rel("test C", v_t{1, 1, 1}, v_t{1 + 1e-8, 1 - 1e-9, 1}, 1e-6);

expect_near_rel("test D", v_t{0, 0, 0}, v_t{0, 0 + 1e-6, 0 - 1e-6}, 1e-4);
expect_near_rel("test D", v_t{0, 0, 0}, v_t{0, 0 + 9e-9, 0 - 9e-9}, 1e-4);

// ones after here fail
// expect_near_rel("test E", v_t{1}, v_t{1, 2}, 1e-6);
Expand All @@ -91,6 +92,7 @@ TEST(testUnitMath, ExpectNearRelVector) {

TEST(testUnitMath, ExpectNearRelVectorNesting) {
using stan::test::expect_near_rel;
using stan::test::relative_tolerance;
using std::vector;
typedef vector<double> v_t;
typedef vector<v_t> vv_t;
Expand All @@ -102,19 +104,19 @@ TEST(testUnitMath, ExpectNearRelVectorNesting) {
expect_near_rel("test A", vv_t{}, vv_t{}, 1e-10);

expect_near_rel("test B", vv_t{v_t{1, 2, 3}, v_t{0, 0, 0}},
vv_t{v_t{1, 2, 3}, v_t{0, 0 + 1e-6, 0 - 1e-6}}, 1e-5);
vv_t{v_t{1, 2, 3}, v_t{0, 0 + 1e-6, 0 - 1e-6}}, 1e-3);

expect_near_rel(
"test C",
vvv_t{vv_t{v_t{1, 2, 3}, v_t{0, 0, 0}}, vv_t{v_t{1, 2, 3}, v_t{0, 0, 0}}},
vvv_t{vv_t{v_t{1, 2, 3}, v_t{0, 0 + 1e-6, 0 - 1e-6}},
vv_t{v_t{1, 2, 3}, v_t{0, 0 + 1e-6, 0 - 1e-6}}},
1e-5);
relative_tolerance(1e-5, 1e-6));

ev_t d1(3);
ev_t d2(3);
d1 << 1, 0, 0;
d2 << 1 + 1e-8, 0 + 1e-8, 0;
d2 << 1 + 1e-8, 0 + 1e-12, 0;
vev_t e1{d1, d2};
vev_t e2{d2, d1};
expect_near_rel("test E", e1, e2, 1e-6);
Expand Down
27 changes: 16 additions & 11 deletions test/unit/math/mix/fun/add_diag_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <test/unit/math/test_ad.hpp>
#include <test/unit/math/ad_tolerances.hpp>

TEST(MathMixMatFun, addDiag) {
using stan::test::relative_tolerance;
auto f
= [](const auto& x, const auto& y) { return stan::math::add_diag(x, y); };

Expand All @@ -22,18 +24,21 @@ TEST(MathMixMatFun, addDiag) {
Eigen::MatrixXd m23(2, 3);
m23 << 1, 1, 1, 1, 1, 1;

stan::test::ad_tolerances tol;
tol.hessian_hessian_ = relative_tolerance(1e-4, 1e-3);
tol.hessian_fvar_hessian_ = relative_tolerance(1e-4, 1e-3);
// these are OK calls
stan::test::expect_ad(f, m00, d);
stan::test::expect_ad(f, m00, v0);
stan::test::expect_ad(f, m11, d);
stan::test::expect_ad(f, m11, v1);
stan::test::expect_ad(f, m22, d);
stan::test::expect_ad(f, m22, v2);
stan::test::expect_ad(f, m23, d);
stan::test::expect_ad(f, m23, v2);
stan::test::expect_ad(tol, f, m00, d);
stan::test::expect_ad(tol, f, m00, v0);
stan::test::expect_ad(tol, f, m11, d);
stan::test::expect_ad(tol, f, m11, v1);
stan::test::expect_ad(tol, f, m22, d);
stan::test::expect_ad(tol, f, m22, v2);
stan::test::expect_ad(tol, f, m23, d);
stan::test::expect_ad(tol, f, m23, v2);

// these throw
stan::test::expect_ad(f, m11, v2);
stan::test::expect_ad(f, m22, v1);
stan::test::expect_ad(f, m23, v1);
stan::test::expect_ad(tol, f, m11, v2);
stan::test::expect_ad(tol, f, m22, v1);
stan::test::expect_ad(tol, f, m23, v1);
}
5 changes: 3 additions & 2 deletions test/unit/math/mix/fun/cov_matrix_constrain_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ typename stan::scalar_type<T>::type g3(const T& x) {

template <typename T>
void expect_cov_matrix_transform(const T& x) {
using stan::test::relative_tolerance;
stan::test::ad_tolerances tols;
tols.hessian_hessian_ = 1e-2;
tols.hessian_fvar_hessian_ = 1e-2;
tols.hessian_hessian_ = relative_tolerance(1e-3, 1e-3);
tols.hessian_fvar_hessian_ = relative_tolerance(1e-3, 1e-3);

auto f1 = [](const auto& x) { return g1(x); };
auto f2 = [](const auto& x) { return g2(x); };
Expand Down
5 changes: 3 additions & 2 deletions test/unit/math/mix/fun/determinant_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
#include <vector>

TEST(MathMixMatFun, determinant) {
using stan::test::relative_tolerance;
auto f = [](const auto& y) { return stan::math::determinant(y); };

stan::test::ad_tolerances tols;
tols.hessian_hessian_ = 1e-2; // default 1e-3
tols.hessian_fvar_hessian_ = 1e-2; // default 1e-3
tols.hessian_hessian_ = relative_tolerance(1e-4, 1e-2);
tols.hessian_fvar_hessian_ = relative_tolerance(1e-4, 1e-2);

Eigen::MatrixXd z(0, 0);

Expand Down
5 changes: 3 additions & 2 deletions test/unit/math/mix/fun/diag_post_multiply_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void expect_diag_post_multiply(const Eigen::MatrixXd& a,
}

TEST(MathMixMatFun, diagPostMultiply) {
using stan::test::relative_tolerance;
// 0 x 0
Eigen::MatrixXd a00(0, 0);
Eigen::VectorXd u0(0);
Expand Down Expand Up @@ -50,8 +51,8 @@ TEST(MathMixMatFun, diagPostMultiply) {
expect_diag_post_multiply(a33c, u3c);

stan::test::ad_tolerances tols;
tols.hessian_hessian_ = 2e-2; // default 1e-3
tols.hessian_fvar_hessian_ = 2e-2; // default 1e-3
tols.hessian_hessian_ = relative_tolerance(1e-4, 2e-2);
tols.hessian_fvar_hessian_ = relative_tolerance(1e-4, 2e-2);

Eigen::MatrixXd a33(3, 3);
a33 << 1, 10, 100, 1000, 2, -4, 8, -16, 32;
Expand Down
5 changes: 3 additions & 2 deletions test/unit/math/mix/fun/diag_pre_multiply_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ void expect_diag_pre_multiply(const Eigen::VectorXd& v,
expect_diag_pre_multiply(v, a, tols);
}
TEST(MathMixMatFun, diagPreMultiply) {
using stan::test::relative_tolerance;
// 0 x 0
Eigen::MatrixXd a00(0, 0);
Eigen::VectorXd u0(0);
Expand Down Expand Up @@ -49,8 +50,8 @@ TEST(MathMixMatFun, diagPreMultiply) {
expect_diag_pre_multiply(u3c, a33c);

stan::test::ad_tolerances tols;
tols.hessian_hessian_ = 2e-2; // default 1e-3
tols.hessian_fvar_hessian_ = 2e-2; // default 1e-3
tols.hessian_hessian_ = relative_tolerance(1e-4, 2e-2);
tols.hessian_fvar_hessian_ = relative_tolerance(1e-4, 2e-2);

Eigen::MatrixXd a33(3, 3);
a33 << 1, 10, 100, 1000, 2, -4, 8, -16, 32;
Expand Down
5 changes: 3 additions & 2 deletions test/unit/math/mix/fun/dot_product_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

template <class F>
void test_dot_product(const F& f) {
using stan::test::relative_tolerance;
stan::test::ad_tolerances tols;
tols.hessian_hessian_ = 1e-2; // default is 1e-3
tols.hessian_fvar_hessian_ = 1e-2; // default is 1e-3
tols.hessian_hessian_ = relative_tolerance(1e-3, 1e-3);
tols.hessian_fvar_hessian_ = relative_tolerance(1e-3, 1e-3);

// size 0
Eigen::VectorXd v0(0);
Expand Down
3 changes: 2 additions & 1 deletion test/unit/math/mix/fun/eigenvalues_sym_test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <test/unit/math/test_ad.hpp>

TEST(MathMixMatFun, eigenvaluesSym) {
using stan::test::relative_tolerance;
auto f = [](const auto& y) {
// need to maintain symmetry for finite diffs
auto a = ((y + y.transpose()) * 0.5).eval();
Expand Down Expand Up @@ -35,6 +36,6 @@ TEST(MathMixMatFun, eigenvaluesSym) {
a22 << 1, 2, 2, 1;
tols.hessian_hessian_ = 5e-1;
tols.hessian_fvar_hessian_ = 5e-1;
tols.grad_hessian_grad_hessian_ = 5e-1;
tols.grad_hessian_grad_hessian_ = relative_tolerance(1e-1, 5e-1);
stan::test::expect_ad(tols, f, a22);
}
Loading