Thanks for giving me that example. I’m trying to figure out how it triggers those NaNs. Here’s what I’ve done so far. I put this into a test called test/inv_chi_square_test.cpp
and am running it with ./runTests.py test/inv_chi_square_test.cpp
. I don’t see it failing (yet), so I need to dig into how the failing distribution test is instantiating it.
#include <stan/math/mix/scal.hpp>
#include <gtest/gtest.h>
double ccdf_log = std::log(1.0 - 0.317528038297796704186230);
double d_dy = -0.0728606;
double d_dnu = -0.83451658;
double d_dy2 = 0.021002101;
double d_dnu2 = -0.25922951;
TEST(inv_chi_square_ccdf, prim) {
double y = 3.0;
double nu = 0.5;
double result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result);
}
TEST(inv_chi_square_ccdf, rev1) {
stan::math::var y = 3.0;
double nu = 0.5;
stan::math::var result = stan::math::inv_chi_square_ccdf_log(y, nu);
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(y);
result.grad(vars, grad);
EXPECT_FLOAT_EQ(ccdf_log, result.val());
EXPECT_FLOAT_EQ(d_dy, grad[0]);
stan::math::recover_memory();
}
TEST(inv_chi_square_ccdf, rev2) {
double y = 3.0;
stan::math::var nu = 0.5;
stan::math::var result = stan::math::inv_chi_square_ccdf_log(y, nu);
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(nu);
result.grad(vars, grad);
EXPECT_FLOAT_EQ(ccdf_log, result.val());
EXPECT_FLOAT_EQ(d_dnu, grad[0]);
stan::math::recover_memory();
}
TEST(inv_chi_square_ccdf, rev3) {
stan::math::var y = 3.0;
stan::math::var nu = 0.5;
stan::math::var result = stan::math::inv_chi_square_ccdf_log(y, nu);
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(y);
vars.push_back(nu);
result.grad(vars, grad);
EXPECT_FLOAT_EQ(ccdf_log, result.val());
EXPECT_FLOAT_EQ(d_dy, grad[0]);
EXPECT_FLOAT_EQ(d_dnu, grad[1]);
stan::math::recover_memory();
}
TEST(inv_chi_square_ccdf, fwd1) {
stan::math::fvar<double> y(3.0, 1.0);
double nu = 0.5;
stan::math::fvar<double> result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result.val_);
EXPECT_FLOAT_EQ(d_dy, result.d_);
}
TEST(inv_chi_square_ccdf, fwd2) {
double y = 3.0;
stan::math::fvar<double> nu(0.5, 1.0);
stan::math::fvar<double> result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result.val_);
EXPECT_FLOAT_EQ(d_dnu, result.d_);
}
TEST(inv_chi_square_ccdf, mix_1stDeriv) {
stan::math::fvar<stan::math::var> y(3.0, 1.0);
double nu = 0.5;
stan::math::fvar<stan::math::var> result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result.val_.val());
EXPECT_FLOAT_EQ(d_dy, result.d_.val());
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(y.val_);
result.val_.grad(vars, grad);
EXPECT_FLOAT_EQ(d_dy, grad[0]);
stan::math::recover_memory();
// for (auto g : grad) {
// std::cout << "gradient = " << g << std::endl;
// }
}
TEST(inv_chi_square_ccdf, mix_2ndDeriv1) {
stan::math::fvar<stan::math::var> y(3.0, 1.0);
double nu = 0.5;
stan::math::fvar<stan::math::var> result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result.val_.val());
EXPECT_FLOAT_EQ(d_dy, result.d_.val());
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(y.val_);
result.d_.grad(vars, grad);
EXPECT_FLOAT_EQ(d_dy2, grad[0]);
stan::math::recover_memory();
}
TEST(inv_chi_square_ccdf, mix_2ndDeriv2) {
double y = 3.0;
stan::math::fvar<stan::math::var> nu(0.5, 1.0);
stan::math::fvar<stan::math::var> result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result.val_.val());
EXPECT_FLOAT_EQ(d_dnu, result.d_.val());
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(nu.val_);
result.d_.grad(vars, grad);
EXPECT_FLOAT_EQ(d_dnu2, grad[0]);
stan::math::recover_memory();
// for (auto g : grad) {
// std::cout << "gradient = " << g << std::endl;
// }
}
TEST(inv_chi_square_ccdf, mix_3rdDeriv_1) {
stan::math::fvar<stan::math::fvar<stan::math::var>> y;
y.val_.val_ = 3.0;
y.val_.d_ = 1.0;
y.d_.val_ = 1.0;
double nu = 0.5;
stan::math::fvar<stan::math::fvar<stan::math::var>> result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result.val_.val_.val());
EXPECT_FLOAT_EQ(d_dy, result.d_.val_.val());
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(y.val_.val_);
result.val_.val_.grad(vars, grad);
// EXPECT_FLOAT_EQ(d_dnu2, grad[0]);
stan::math::recover_memory();
for (auto g : grad) {
std::cout << "gradient = " << g << std::endl;
}
}
TEST(inv_chi_square_ccdf, mix_3rdDeriv_2) {
stan::math::fvar<stan::math::fvar<stan::math::var>> y;
y.val_.val_ = 3.0;
y.val_.d_ = 1.0;
y.d_.val_ = 1.0;
double nu = 0.5;
stan::math::fvar<stan::math::fvar<stan::math::var>> result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result.val_.val_.val());
EXPECT_FLOAT_EQ(d_dy, result.d_.val_.val());
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(y.val_.val_);
result.d_.val_.grad(vars, grad);
// EXPECT_FLOAT_EQ(d_dnu2, grad[0]);
stan::math::recover_memory();
for (auto g : grad) {
std::cout << "gradient = " << g << std::endl;
}
}
TEST(inv_chi_square_ccdf, mix_3rdDeriv_3) {
stan::math::fvar<stan::math::fvar<stan::math::var>> y;
y.val_.val_ = 3.0;
y.val_.d_ = 1.0;
y.d_.val_ = 1.0;
double nu = 0.5;
stan::math::fvar<stan::math::fvar<stan::math::var>> result = stan::math::inv_chi_square_ccdf_log(y, nu);
EXPECT_FLOAT_EQ(ccdf_log, result.val_.val_.val());
EXPECT_FLOAT_EQ(d_dy, result.d_.val_.val());
std::vector<stan::math::var> vars;
std::vector<double> grad;
vars.push_back(y.val_.val_);
result.d_.d_.grad(vars, grad);
// EXPECT_FLOAT_EQ(d_dnu2, grad[0]);
stan::math::recover_memory();
for (auto g : grad) {
std::cout << "gradient = " << g << std::endl;
}
}