TEST(AgradRev, falling_factorial_var_var) { AVAR a(4.0); AVAR b(4.0); AVAR f = stan::math::falling_factorial(a,b); EXPECT_FLOAT_EQ(1.0, f.val()); AVEC x = createAVEC(a,b); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(1.0 * boost::math::digamma(5), g[0]); EXPECT_FLOAT_EQ(boost::math::digamma(5) * -1.0, g[1]); }
void assert_val_grad(Eigen::Matrix<stan::agrad::var,R,C>& v) { v << -1.0, 0.0, 3.0; AVEC x = createAVEC(v(0),v(1),v(2)); AVAR f = dot_self(v); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(-2.0,g[0]); EXPECT_FLOAT_EQ(0.0,g[1]); EXPECT_FLOAT_EQ(6.0,g[2]); }
TEST(AgradRevMatrix,log_determinant_spd) { using stan::math::matrix_v; using stan::math::log_determinant_spd; matrix_v v(2,2); v << 1, 0, 0, 3; AVAR det; det = log_determinant_spd(v); EXPECT_FLOAT_EQ(std::log(3.0), det.val()); }
TEST(AgradRev,abs_var_3) { AVAR a = 0.0; AVAR f = abs(a); EXPECT_FLOAT_EQ(0.0, f.val()); AVEC x = createAVEC(a); VEC g; f.grad(x,g); EXPECT_EQ(1U,g.size()); EXPECT_FLOAT_EQ(0.0, g[0]); }
TEST(AgradRev,abs_neg_inf) { double inf = std::numeric_limits<double>::infinity(); AVAR a = -inf; AVAR f = abs(a); EXPECT_FLOAT_EQ(inf,f.val()); AVEC x = createAVEC(a); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(-1.0,g[0]); }
TEST(AgradRev,sinh_neg_inf) { double inf = std::numeric_limits<double>::infinity(); AVAR a = -inf; AVAR f = tanh(a); EXPECT_FLOAT_EQ(-1,f.val()); AVEC x = createAVEC(a); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(1.0/(cosh(-inf) * cosh(-inf)), g[0]); }
TEST(AgradRev,sqrt_zero) { double inf = std::numeric_limits<double>::infinity(); AVAR a(0.0); AVAR f = sqrt(a); EXPECT_FLOAT_EQ(0.0,f.val()); AVEC x = createAVEC(a); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(inf,g[0]); }
TEST(AgradRev,fmax_vd_3) { AVAR a = 2.0; double b = 2.0; AVAR f = fmax(a,b); EXPECT_FLOAT_EQ(2.0,f.val()); AVEC x = createAVEC(a); VEC grad_f; f.grad(x,grad_f); EXPECT_FLOAT_EQ(1.0,grad_f[0]); }
TEST(AgradRev,fmax_dv_2) { double a = 2.3; AVAR b = 2.0; AVAR f = fmax(a,b); EXPECT_FLOAT_EQ(2.3,f.val()); AVEC x = createAVEC(b); VEC grad_f; f.grad(x,grad_f); EXPECT_FLOAT_EQ(0.0,grad_f[0]); }
TEST(AgradRevMatrix,log_determinant) { using stan::agrad::matrix_v; using stan::math::log_determinant; matrix_v v(2,2); v << 0, 1, 2, 3; AVAR det; det = log_determinant(v); EXPECT_FLOAT_EQ(std::log(2.0), det.val()); }
TEST(AgradRev,a_minus_b) { AVAR a = 5.0; AVAR b = 2.0; AVAR f = a - b; EXPECT_FLOAT_EQ(3.0,f.val()); AVEC x = createAVEC(a,b); VEC dx; f.grad(x,dx); EXPECT_FLOAT_EQ(1.0,dx[0]); EXPECT_FLOAT_EQ(-1.0,dx[1]); }
TEST(AgradRev,pow_double_var) { double a = 3.0; AVAR b(4.0); AVAR f = pow(a,b); EXPECT_FLOAT_EQ(81.0,f.val()); AVEC x = createAVEC(b); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(log(3.0) * pow(3.0,4.0), g[0]); }
TEST(AgradRev,pow_var_double) { AVAR a(3.0); double b = 4.0; AVAR f = pow(a,b); EXPECT_FLOAT_EQ(81.0,f.val()); AVEC x = createAVEC(a); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(4.0 * pow(3.0,4.0-1.0), g[0]); }
TEST(AgradRev, falling_factorial_double_var) { double a(5); AVAR b(4.0); AVAR f = stan::math::falling_factorial(a,b); EXPECT_FLOAT_EQ(5.0, f.val()); AVEC x = createAVEC(a,b); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(0, g[0]); EXPECT_FLOAT_EQ(boost::math::digamma(5) * -5.0, g[1]); }
TEST(AgradRev,pow_var_var) { AVAR a(3.0); AVAR b(4.0); AVAR f = pow(a,b); EXPECT_FLOAT_EQ(81.0,f.val()); AVEC x = createAVEC(a,b); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(4.0 * pow(3.0,4.0-1.0), g[0]); EXPECT_FLOAT_EQ(log(3.0) * pow(3.0,4.0), g[1]); }
TEST(AgradRevMatrix, trace_inv_quad_form_ldlt_mat) { using stan::agrad::matrix_v; using stan::math::matrix_d; matrix_v av(4,4); matrix_d ad(4,4); matrix_d bd(4,2); matrix_v bv(4,2); AVAR res; AVEC vars; VEC grad; bd << 100, 10, 0, 1, -3, -3, 5, 2; bv << 100, 10, 0, 1, -3, -3, 5, 2; ad << 9.0, 3.0, 3.0, 3.0, 3.0, 10.0, 2.0, 2.0, 3.0, 2.0, 7.0, 1.0, 3.0, 2.0, 1.0, 112.0; av << 9.0, 3.0, 3.0, 3.0, 3.0, 10.0, 2.0, 2.0, 3.0, 2.0, 7.0, 1.0, 3.0, 2.0, 1.0, 112.0; stan::math::LDLT_factor<double,-1,-1> ldlt_ad; stan::math::LDLT_factor<stan::agrad::var,-1,-1> ldlt_av; ldlt_av.compute(av); ASSERT_TRUE(ldlt_av.success()); ldlt_ad.compute(ad); ASSERT_TRUE(ldlt_ad.success()); // double-double res = trace_inv_quad_form_ldlt(ldlt_ad,bd); EXPECT_FLOAT_EQ(1439.1061766207, res.val()); // var-double res = trace_inv_quad_form_ldlt(ldlt_av,bd); EXPECT_FLOAT_EQ(1439.1061766207, res.val()); // double-var res = trace_inv_quad_form_ldlt(ldlt_ad,bv); EXPECT_FLOAT_EQ(1439.1061766207, res.val()); // var-var res = trace_inv_quad_form_ldlt(ldlt_av,bv); EXPECT_FLOAT_EQ(1439.1061766207, res.val()); }
TEST(AgradRev,a_times_b) { AVAR a = 2.0; AVAR b = -3.0; AVAR f = a * b; EXPECT_FLOAT_EQ(-6.0,f.val()); AVEC x = createAVEC(a,b); VEC grad_f; f.grad(x,grad_f); EXPECT_FLOAT_EQ(-3.0,grad_f[0]); EXPECT_FLOAT_EQ(2.0,grad_f[1]); }
TEST(AgradRev,hypot_dv) { double a = 3.0; AVAR b = 4.0; AVAR f = hypot(a,b); EXPECT_FLOAT_EQ(5.0,f.val()); AVEC x = createAVEC(b); VEC grad_f; f.grad(x,grad_f); // arbitrary, but doc this way EXPECT_FLOAT_EQ(4.0/5.0,grad_f[0]); }
TEST(AgradRev,log_falling_factorial_var_double) { double a(1); AVAR b(4.0); AVAR f = stan::agrad::log_falling_factorial(b,a); EXPECT_FLOAT_EQ(std::log(24.0),f.val()); AVEC x = createAVEC(a,b); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(0, g[0]); EXPECT_FLOAT_EQ(boost::math::digamma(5),g[1]); }
TEST(AgradRev, rising_factorial_double_var) { using boost::math::digamma; double a(5); AVAR b(4.0); AVAR f = stan::agrad::rising_factorial(a,b); EXPECT_FLOAT_EQ(5*6*7*8, f.val()); AVEC x = createAVEC(a,b); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(0, g[0]); EXPECT_FLOAT_EQ(digamma(9) * 5*6*7*8, g[1]); }
TEST(AgradRev,abs_NaN) { AVAR a = std::numeric_limits<double>::quiet_NaN(); AVAR f = abs(a); AVEC x = createAVEC(a); VEC g; f.grad(x,g); EXPECT_TRUE(boost::math::isnan(f.val())); ASSERT_EQ(1,g.size()); EXPECT_TRUE(boost::math::isnan(g[0])); }
TEST(AgradRev, rising_factorial_var_var) { using boost::math::digamma; AVAR c(4.0); AVAR b(4.0); AVAR f = stan::agrad::rising_factorial(b,c); EXPECT_FLOAT_EQ(4*5*6*7, f.val()); AVEC x = createAVEC(b,c); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(4.0*5.0*6.0*7.0 * (digamma(8.0) - digamma(4.0)), g[0]); EXPECT_FLOAT_EQ(4.0*5.0*6.0*7.0 * digamma(8), g[1]); }
TEST(AgradRev,fma_ddv_defaultpolicy) { double a = 3.0; double b = 5.0; AVAR c = 7.0; AVAR f = fma(a,b,c); EXPECT_FLOAT_EQ(3.0 * 5.0 + 7.0, f.val()); AVEC x = createAVEC(c); VEC grad_f; f.grad(x,grad_f); EXPECT_FLOAT_EQ(1.0,grad_f[0]); }
TEST(AgradRev,fmod_var_var) { AVAR a = 2.7; AVAR b = 1.3; AVAR f = fmod(a,b); EXPECT_FLOAT_EQ(std::fmod(2.7,1.3),f.val()); AVEC x = createAVEC(a,b); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(1.0,g[0]); EXPECT_FLOAT_EQ(-2.0,g[1]); // (int)(2.7/1.3) = 2 }
TEST(AgradRev,fmin_vv) { AVAR a = 1.3; AVAR b = 2.0; AVAR f = fmin(a,b); EXPECT_FLOAT_EQ(1.3,f.val()); AVEC x = createAVEC(a,b); VEC grad_f; f.grad(x,grad_f); EXPECT_FLOAT_EQ(1.0,grad_f[0]); EXPECT_FLOAT_EQ(0.0,grad_f[1]); }
TEST(AgradRev,fmin_dv_3) { double a = 2.0; AVAR b = 2.0; AVAR f = fmin(a,b); EXPECT_FLOAT_EQ(2.0,f.val()); AVEC x = createAVEC(b); VEC grad_f; f.grad(x,grad_f); // arbitrary, but doc this way EXPECT_FLOAT_EQ(1.0,grad_f[0]); }
TEST(AgradRev,rising_factorial_var_double) { using boost::math::digamma; double a(1); AVAR b(4.0); AVAR f = stan::agrad::rising_factorial(b,a); EXPECT_FLOAT_EQ(4,f.val()); AVEC x = createAVEC(a,b); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(0, g[0]); EXPECT_FLOAT_EQ((digamma(5.0) - digamma(4.0)) * 4.0,g[1]); }
TEST(AgradRev,fma_vvd_defaultpolicy) { AVAR a = 3.0; AVAR b = 5.0; double c = 7.0; AVAR f = fma(a,b,c); EXPECT_FLOAT_EQ(3.0 * 5.0 + 7.0, f.val()); AVEC x = createAVEC(a,b); VEC grad_f; f.grad(x,grad_f); EXPECT_FLOAT_EQ(5.0,grad_f[0]); EXPECT_FLOAT_EQ(3.0,grad_f[1]); }
TEST(AgradRev,fmin_vv_3) { AVAR a = 2.0; AVAR b = 2.0; AVAR f = fmin(a,b); EXPECT_FLOAT_EQ(2.0,f.val()); AVEC x = createAVEC(a,b); VEC grad_f; f.grad(x,grad_f); // arbitrary, but documented this way EXPECT_FLOAT_EQ(0.0,grad_f[0]); EXPECT_FLOAT_EQ(1.0,grad_f[1]); }
TEST(AgradRev,a_pluseq_b) { AVAR a(5.0); AVAR b(-1.0); AVEC x = createAVEC(a,b); AVAR f = (a += b); EXPECT_FLOAT_EQ(4.0,f.val()); EXPECT_FLOAT_EQ(4.0,a.val()); EXPECT_FLOAT_EQ(-1.0,b.val()); VEC g; f.grad(x,g); EXPECT_FLOAT_EQ(1.0,g[0]); EXPECT_FLOAT_EQ(1.0,g[1]); }