If I follow you correctly, I would say the chain()
method I wrote doesn’t act on the vari
. Rather it acts on one of the arguments of chain()
, namely parms
. So I suppose it makes sense to have stacked == false
. I’ll dig into the autodiff paper to check if my intuition is right.
I pasted the chain method below:
inline void chain(const F1& f1,
const Eigen::Matrix<double,
Eigen::Dynamic, 1>& x,
Eigen::Matrix<var, Eigen::Dynamic, 1>& parms,
const std::vector<double>& dat,
const std::vector<int>& dat_int,
const Eigen::Matrix<double,
Eigen::Dynamic, 1>& adjTheta) {
// find roots of the equation
Eigen::Matrix<double, Eigen::Dynamic, 1>
parms_val = value(parms);
hybrj_functor_solver<F1, double, double>
functor(f1, x, parms_val, dat, dat_int, "theta");
Eigen::HybridNonLinearSolver<hybrj_functor_solver<F1, double, double> >
solver(functor);
Eigen::Matrix<double, Eigen::Dynamic, 1> theta = x;
solver.solve(theta);
// compute Jacobian
Eigen::MatrixXd Jf_x = functor.get_jacobian(theta);
stan::math::hybrj_functor_solver<F1, double, double>
functor_parm(f1, theta, parms_val, dat, dat_int, "parms");
Eigen::MatrixXd Jf_p = functor_parm.get_jacobian(parms_val);
Eigen::MatrixXd Jx_p = - inverse(Jf_x) * Jf_p;
for (int i = 0; i < adjTheta.rows(); i++)
for (int j = 0; j < parms.rows(); j++)
parms(j).vi_->adj_ += adjTheta(i) * Jx_p(i, j);
}