this is small enough to paste here. My Mac always wants ot open the wrong app for files, which is a pain.
P.S. The general recommendation is to use line comments to comment out blocks of code. The block comments are only for long doc chunks. You can do that in editors like emacs in one command.
#include <stan/math.hpp>
#include <gtest/gtest.h>
#include <stan/math/prim/mat/fun/Eigen.hpp> // only used for stack tests
#include <stan/math/rev/mat/fun/quad_form.hpp>
#include <test/unit/math/rev/mat/fun/util.hpp>
#include <string>
#include <vector>
struct AgradRev : public testing::Test {
void SetUp() {
// make sure memory's clean before starting each test
stan::math::recover_memory();
}
};
struct binary_functor {
template <typename T1, typename T2>
std::vector<typename stan::return_type<T1, T2>::type> operator()(T1& a,
T2& b) {
std::vector<typename stan::return_type<T1, T2>::type> res(2);
res[0] = a * a + b * b;
res[1] = a * a * a + b * b * b;
return res;
}
};
TEST_F(AgradRev, non_nested_jacobian) {
using stan::math::var;
using stan::math::vari;
using std::vector;
var a = 2.0;
var b = 3.0;
binary_functor f;
vector<var> res = f(a, b);
res[0].grad();
EXPECT_FLOAT_EQ(2.0 * a.val(), a.adj());
EXPECT_FLOAT_EQ(2.0 * b.val(), b.adj());
stan::math::set_zero_all_adjoints();
res[1].grad();
EXPECT_FLOAT_EQ(3.0 * a.val() * a.val(), a.adj());
EXPECT_FLOAT_EQ(3.0 * b.val() * b.val(), b.adj());
}
TEST_F(AgradRev, nested_jacobian) {
using stan::math::var;
using stan::math::vari;
using std::vector;
var a = 2.0;
var b = 3.0;
binary_functor f;
stan::math::start_nested();
vector<var> res = f(a, b);
res[0].grad();
EXPECT_FLOAT_EQ(2.0 * a.val(), a.adj());
EXPECT_FLOAT_EQ(2.0 * b.val(), b.adj());
stan::math::set_zero_all_adjoints_nested();
a.vi_->set_zero_adjoint();
b.vi_->set_zero_adjoint();
res[1].grad();
EXPECT_FLOAT_EQ(3.0 * a.val() * a.val(), a.adj());
EXPECT_FLOAT_EQ(3.0 * b.val() * b.val(), b.adj());
stan::math::recover_memory_nested();
}
TEST_F(AgradRev, double_nested_jacobian) {
using stan::math::var;
using stan::math::vari;
using std::vector;
stan::math::start_nested();
var a = 2.0;
binary_functor f;
stan::math::start_nested();
var b = 3.0;
vector<var> res = f(a, b);
res[0].grad();
EXPECT_FLOAT_EQ(2.0 * a.val(), a.adj());
EXPECT_FLOAT_EQ(2.0 * b.val(), b.adj());
stan::math::set_zero_all_adjoints_nested();
a.vi_->set_zero_adjoint();
// b.vi_->set_zero_adjoint();
res[1].grad();
EXPECT_FLOAT_EQ(3.0 * a.val() * a.val(), a.adj());
EXPECT_FLOAT_EQ(3.0 * b.val() * b.val(), b.adj());
stan::math::recover_memory_nested();
EXPECT_TRUE(!stan::math::empty_nested());
stan::math::recover_memory_nested();
EXPECT_TRUE(stan::math::empty_nested());
}
TEST_F(AgradRev, repeated_double_nested_jacobian) {
using stan::math::var;
using stan::math::vari;
using std::vector;
stan::math::start_nested();
var a = 2.0;
binary_functor f;
{
stan::math::start_nested();
var b = 3.0;
vector<var> res = f(a, b);
a.vi_->set_zero_adjoint();
res[0].grad();
EXPECT_FLOAT_EQ(2.0 * a.val(), a.adj());
EXPECT_FLOAT_EQ(2.0 * b.val(), b.adj());
stan::math::set_zero_all_adjoints_nested();
a.vi_->set_zero_adjoint();
// b.vi_->set_zero_adjoint();
res[1].grad();
EXPECT_FLOAT_EQ(3.0 * a.val() * a.val(), a.adj());
EXPECT_FLOAT_EQ(3.0 * b.val() * b.val(), b.adj());
stan::math::recover_memory_nested();
EXPECT_TRUE(!stan::math::empty_nested());
}
// repeat start
{
stan::math::start_nested();
var b = 4.0;
vector<var> res = f(a, b);
a.vi_->set_zero_adjoint();
res[0].grad();
EXPECT_FLOAT_EQ(2.0 * a.val(), a.adj());
EXPECT_FLOAT_EQ(2.0 * b.val(), b.adj());
stan::math::set_zero_all_adjoints_nested();
a.vi_->set_zero_adjoint();
// b.vi_->set_zero_adjoint();
res[1].grad();
EXPECT_FLOAT_EQ(3.0 * a.val() * a.val(), a.adj());
EXPECT_FLOAT_EQ(3.0 * b.val() * b.val(), b.adj());
stan::math::recover_memory_nested();
EXPECT_TRUE(!stan::math::empty_nested());
}
// repeat end
stan::math::recover_memory_nested();
EXPECT_TRUE(stan::math::empty_nested());
}
/*
TEST_F(AgradRev, repeated_double_nested_jacobian) {
using stan::math::var;
using stan::math::vari;
using std::vector;
var a = 2.0;
stan::math::start_nested();
var b = 3.0;
binary_functor f;
stan::math::start_nested();
vector<var> res = f(a, b);
res[0].grad();
EXPECT_FLOAT_EQ(2.0 * a.val(), a.adj());
EXPECT_FLOAT_EQ(2.0 * b.val(), b.adj());
stan::math::set_zero_all_adjoints_nested();
a.vi_->set_zero_adjoint();
b.vi_->set_zero_adjoint();
res[1].grad();
EXPECT_FLOAT_EQ(3.0 * a.val() * a.val(), a.adj());
EXPECT_FLOAT_EQ(3.0 * b.val() * b.val(), b.adj());
stan::math::recover_memory_nested();
EXPECT_TRUE(!stan::math::empty_nested());
stan::math::recover_memory_nested();
EXPECT_TRUE(stan::math::empty_nested());
}
*/