Skip to content

Commit

Permalink
Merge pull request #2997 from stan-dev/fix/test-ad-names
Browse files Browse the repository at this point in the history
appends name of ad types used to ad test to failure output
  • Loading branch information
WardBrian authored Jan 5, 2024
2 parents 895f3e9 + 5fc064d commit 0061d8f
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 56 deletions.
103 changes: 60 additions & 43 deletions test/unit/math/expect_near_rel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,38 @@ 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,
const relative_tolerance tol
= relative_tolerance()) {
const relative_tolerance tol = relative_tolerance(),
const char* x1_name = "x1",
const char* x2_name = "x2") {
double tol_val = tol.inexact(x1, x2);
EXPECT_NEAR(x1, x2, tol_val)
<< "expect_near_rel_finite in: " << msg << std::endl;
<< "expect_near_rel_finite in: " << msg << " for " << x1_name << " vs "
<< x2_name << std::endl;
}

template <typename EigMat1, typename EigMat2,
require_all_eigen_t<EigMat1, EigMat2>...>
void expect_near_rel_finite(const std::string& msg, const EigMat1& x1,
const EigMat2& x2) {
const EigMat2& x2, const char* x1_name = "x1",
const char* x2_name = "x2") {
EXPECT_EQ(x1.rows(), x2.rows());
EXPECT_EQ(x1.cols(), x2.cols());
auto x1_eval = x1.eval();
auto x2_eval = x2.eval();
for (int i = 0; i < x1.size(); ++i)
expect_near_rel_finite(msg, x1_eval(i), x2_eval(i));
for (int i = 0; i < x1.size(); ++i) {
expect_near_rel_finite(msg, x1_eval(i), x2_eval(i), x1_name, x2_name);
}
}

template <typename T1, typename T2>
void expect_near_rel_finite(const std::string& msg, const std::vector<T1>& x1,
const std::vector<T2>& x2) {
const std::vector<T2>& x2,
const char* x1_name = "x1",
const char* x2_name = "x2") {
EXPECT_EQ(x1.size(), x2.size());
for (size_t i = 0; i < x1.size(); ++i)
expect_near_rel_finite(x1[i], x2[i]);
for (size_t i = 0; i < x1.size(); ++i) {
expect_near_rel_finite(x1[i], x2[i], x1_name, x2_name);
}
}

} // namespace internal
Expand All @@ -72,17 +79,20 @@ 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,
relative_tolerance tol = relative_tolerance()) {
if (stan::math::is_nan(x1) || stan::math::is_nan(x2))
relative_tolerance tol = relative_tolerance(),
const char* x1_name = "x1", const char* x2_name = "x2") {
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
<< msg << std::endl;
else if (stan::math::is_inf(x1) || stan::math::is_inf(x2))
<< msg << " for " << x1_name << " vs " << x2_name << std::endl;
} else if (stan::math::is_inf(x1) || stan::math::is_inf(x2)) {
EXPECT_EQ(x1, x2) << "expect_near_rel(" << x1 << ", " << x2 << ")"
<< std::endl
<< msg << std::endl;
else
internal::expect_near_rel_finite(msg, x1, x2, tol);
<< msg << " for " << x1_name << " vs " << x2_name
<< std::endl;
} else {
internal::expect_near_rel_finite(msg, x1, x2, tol, x1_name, x2_name);
}
}

/**
Expand All @@ -103,17 +113,18 @@ 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,
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()
<< "; x2.rows() = " << x2.rows() << std::endl
<< msg << std::endl;
relative_tolerance tol = relative_tolerance(),
const char* x1_name = "x1", const char* x2_name = "x2") {
EXPECT_EQ(x1.rows(), x2.rows())
<< "expect_near_rel (Eigen::Matrix)"
<< " rows must be same size." << x1_name << ".rows() = " << x1.rows()
<< "; " << x2_name << ".rows() = " << x2.rows() << std::endl
<< msg << std::endl;

EXPECT_EQ(x1.cols(), x2.cols())
<< "expect_near_rel:"
<< "cols must be same size."
<< "x1.cols() = " << x1.cols() << "x2.cols() = " << x2.cols() << ")"
<< std::endl
<< "cols must be same size." << x1_name << ".cols() = " << x1.cols()
<< "; " << x2_name << ".cols() = " << x2.cols() << std::endl
<< msg << std::endl;
auto x1_eval = x1.eval();
auto x2_eval = x2.eval();
Expand All @@ -128,7 +139,8 @@ void expect_near_rel(const std::string& msg, EigMat1&& x1, EigMat2&& x2,
msg2 += std::to_string(i) + ", " + std::to_string(j) + ") = x2("
+ std::to_string(i) + ", " + std::to_string(j) + "): " + msg;
}
expect_near_rel(msg2, x1_eval(sentinal_val), x2_eval(sentinal_val), tol);
expect_near_rel(msg2, x1_eval(sentinal_val), x2_eval(sentinal_val), tol,
x1_name, x2_name);
sentinal_val++;
}
}
Expand Down Expand Up @@ -156,15 +168,17 @@ 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,
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()
<< "; x2.size() = " << x2.size() << std::endl
<< msg << std::endl;
std::string msg2 = "expect_near_rel; requite items x1[i] = x2[i]: " + msg;
relative_tolerance tol = relative_tolerance(),
const char* x1_name = "x1", const char* x2_name = "x2") {
EXPECT_EQ(x1.size(), x2.size())
<< "expect_near_rel (std::vector):"
<< " vectors must be same size. " << x1_name << ".size() = " << x1.size()
<< "; " << x2_name << ".size() = " << x2.size() << std::endl
<< msg << std::endl;
std::string msg2 = std::string("expect_near_rel; require items ") + "x1[i] = "
+ "x2[i]: " + msg + " for " + x1_name + " vs " + x2_name;
for (size_t i = 0; i < x1.size(); ++i)
expect_near_rel(msg2, x1[i], x2[i], tol);
expect_near_rel(msg2, x1[i], x2[i], tol, x1_name, x2_name);
}

/**
Expand All @@ -182,9 +196,10 @@ void expect_near_rel(const std::string& msg, const std::vector<T1>& x1,
template <typename T1, typename T2>
void expect_near_rel(const std::string& msg, const std::complex<T1>& z1,
const std::complex<T2>& z2,
relative_tolerance tol = relative_tolerance()) {
expect_near_rel(msg, z1.real(), z2.real(), tol);
expect_near_rel(msg, z1.imag(), z2.imag(), tol);
relative_tolerance tol = relative_tolerance(),
const char* x1_name = "x1", const char* x2_name = "x2") {
expect_near_rel(msg, z1.real(), z2.real(), tol, x1_name, x2_name);
expect_near_rel(msg, z1.imag(), z2.imag(), tol, x1_name, x2_name);
}

/**
Expand All @@ -203,9 +218,10 @@ void expect_near_rel(const std::string& msg, const std::complex<T1>& z1,
template <typename T1, typename T2>
void expect_near_rel(const std::string& msg, const T1& x1,
const std::complex<T2>& z2,
relative_tolerance tol = relative_tolerance()) {
expect_near_rel(msg, x1, z2.real(), tol);
expect_near_rel(msg, 0, z2.imag(), tol);
relative_tolerance tol = relative_tolerance(),
const char* x1_name = "x1", const char* x2_name = "x2") {
expect_near_rel(msg, x1, z2.real(), tol, x1_name, x2_name);
expect_near_rel(msg, 0, z2.imag(), tol, x1_name, x2_name);
}

/**
Expand All @@ -224,9 +240,10 @@ void expect_near_rel(const std::string& msg, const T1& x1,
template <typename T1, typename T2>
void expect_near_rel(const std::string& msg, const std::complex<T1>& z1,
const T2& x2,
relative_tolerance tol = relative_tolerance()) {
expect_near_rel(msg, z1.real(), x2, tol);
expect_near_rel(msg, z1.imag(), 0, tol);
relative_tolerance tol = relative_tolerance(),
const char* x1_name = "x1", const char* x2_name = "x2") {
expect_near_rel(msg, z1.real(), x2, tol, x1_name, x2_name);
expect_near_rel(msg, z1.imag(), 0, tol, x1_name, x2_name);
}

} // namespace test
Expand Down
35 changes: 22 additions & 13 deletions test/unit/math/test_ad.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,15 @@ void test_gradient(const ad_tolerances& tols, const F& f,
Eigen::VectorXd grad_ad;
double fx_ad = fx;
stan::math::gradient<F>(f, x, fx_ad, grad_ad);
expect_near_rel("gradient() val", fx, fx_ad, tols.gradient_val_);
expect_near_rel("gradient() val", fx, fx_ad, tols.gradient_val_, "double",
"var");
if (!test_derivs || !is_finite(x) || !is_finite(fx))
return;
Eigen::VectorXd grad_fd;
double fx_fd;
stan::math::finite_diff_gradient_auto(f, x, fx_fd, grad_fd);
expect_near_rel("gradient() grad for finite diff vs auto diff", grad_fd,
grad_ad, tols.gradient_grad_);
grad_ad, tols.gradient_grad_, "finite_diff", "var");
}

#ifndef STAN_MATH_TESTS_REV_ONLY
Expand Down Expand Up @@ -169,14 +170,15 @@ void test_gradient_fvar(const ad_tolerances& tols, const F& f,
Eigen::VectorXd grad_ad;
double fx_ad = fx;
stan::math::gradient<double, F>(f, x, fx_ad, grad_ad);
expect_near_rel("gradient_fvar() val", fx, fx_ad, tols.gradient_fvar_val_);
expect_near_rel("gradient_fvar() val", fx, fx_ad, tols.gradient_fvar_val_,
"double", "fvar<double>");
if (!test_derivs || !is_finite(x) || !is_finite(fx))
return;
Eigen::VectorXd grad_fd;
double fx_fd;
stan::math::finite_diff_gradient_auto(f, x, fx_fd, grad_fd);
expect_near_rel("gradient_fvar() grad", grad_fd, grad_ad,
tols.gradient_fvar_grad_);
tols.gradient_fvar_grad_, "finite_diff", "fvar<double>");
}

/**
Expand Down Expand Up @@ -210,17 +212,19 @@ void test_hessian_fvar(const ad_tolerances& tols, const F& f,
Eigen::VectorXd grad_ad;
Eigen::MatrixXd H_ad;
stan::math::hessian<double, F>(f, x, fx_ad, grad_ad, H_ad);
expect_near_rel("hessian_fvar() val", fx, fx_ad, tols.hessian_fvar_val_);
expect_near_rel("hessian_fvar() val", fx, fx_ad, tols.hessian_fvar_val_,
"double", "fvar<fvar<double>>");
if (!test_derivs || !is_finite(x) || !is_finite(fx))
return;
double fx_fd;
Eigen::VectorXd grad_fd;
Eigen::MatrixXd H_fd;
stan::math::internal::finite_diff_hessian_auto(f, x, fx_fd, grad_fd, H_fd);
expect_near_rel("hessian_fvar() grad", grad_fd, grad_ad,
tols.hessian_fvar_grad_);
tols.hessian_fvar_grad_, "finite_diff", "fvar<fvar<double>>");
expect_near_rel("hessian_fvar() Hessian", H_fd, H_ad,
tols.hessian_fvar_hessian_);
tols.hessian_fvar_hessian_, "finite_diff",
"fvar<fvar<double>>");
}

/**
Expand Down Expand Up @@ -254,15 +258,18 @@ void test_hessian(const ad_tolerances& tols, const F& f,
Eigen::VectorXd grad_ad;
Eigen::MatrixXd H_ad;
stan::math::hessian<F>(f, x, fx_ad, grad_ad, H_ad);
expect_near_rel("hessian val", fx, fx_ad, tols.hessian_val_);
expect_near_rel("hessian val", fx, fx_ad, tols.hessian_val_, "double",
"fvar<var>");
if (!test_derivs || !is_finite(x) || !is_finite(fx))
return;
double fx_fd;
Eigen::VectorXd grad_fd;
Eigen::MatrixXd H_fd;
stan::math::internal::finite_diff_hessian_auto(f, x, fx_fd, grad_fd, H_fd);
expect_near_rel("hessian() grad", grad_fd, grad_ad, tols.hessian_grad_);
expect_near_rel("hessian() Hessian", H_fd, H_ad, tols.hessian_hessian_);
expect_near_rel("hessian() grad", grad_fd, grad_ad, tols.hessian_grad_,
"finite_diff", "fvar<var>");
expect_near_rel("hessian() Hessian", H_fd, H_ad, tols.hessian_hessian_,
"finite_diff", "fvar<var>");
}

/**
Expand Down Expand Up @@ -296,19 +303,21 @@ void test_grad_hessian(const ad_tolerances& tols, const F& f,
Eigen::MatrixXd H_ad;
std::vector<Eigen::MatrixXd> grad_H_ad;
stan::math::grad_hessian(f, x, fx_ad, H_ad, grad_H_ad);
expect_near_rel("grad_hessian() val", fx, fx_ad, tols.grad_hessian_val_);
expect_near_rel("grad_hessian() val", fx, fx_ad, tols.grad_hessian_val_,
"double", "fvar<fvar<var>>");
if (!test_derivs || !is_finite(x) || !is_finite(fx))
return;
double fx_fd;
Eigen::MatrixXd H_fd;
std::vector<Eigen::MatrixXd> grad_H_fd;
stan::math::finite_diff_grad_hessian_auto(f, x, fx_fd, H_fd, grad_H_fd);
expect_near_rel("grad_hessian() Hessian", H_fd, H_ad,
tols.grad_hessian_hessian_);
tols.grad_hessian_hessian_, "finite_diff", "fvar<fvar<var>>");
EXPECT_EQ(x.size(), grad_H_fd.size());
for (size_t i = 0; i < grad_H_fd.size(); ++i)
expect_near_rel("grad_hessian() grad Hessian", grad_H_fd[i], grad_H_ad[i],
tols.grad_hessian_grad_hessian_);
tols.grad_hessian_grad_hessian_, "finite_diff",
"fvar<fvar<var>>");
}
#endif

Expand Down

0 comments on commit 0061d8f

Please sign in to comment.