# Multivariate Function with Known Gradients - RStan

Hi,

As in the issue Custom Function with Known Gradients, I got a function to work which maps `double -> double`. Eventually I want to use a function that maps `vector -> vector`, but for now I have difficulties to implement a function that maps `vector -> double` and is callable from a Stan file.

The function is declared as

``````namespace tests {

double vecToDouble(const std::vector<double>& x)
{
double res = 0;
for (int i=0; i<x.size(); ++i) res += x[i] * x[i];
return res;
}

{
std::vector<double> res;
for (int i=0; i<x.size(); ++i) res.push_back(2 * x[i]);
return res;
}
}
``````

and for the Stan interface I currently have

``````namespace stan {
namespace math {

double vecToDouble(const std::vector<double>& x) {
return tests::vecToDouble(x);
}

var vecToDouble(const Eigen::Matrix<var, Eigen::Dynamic, 1>& x) {
std::vector<var> b(x.data(), x.data() + x.rows() * x.cols());

std::vector<double> a = value_of(b);
double fa  = tests::vecToDouble(a);

}

}
}
``````

It works in pure C++ as in

``````int main() {

int N = 3;

Eigen::Matrix<stan::math::var, Eigen::Dynamic, 1> x(N);
std::vector<double> xx;
for (int i=0; i<N; ++i)
{
stan::math::var xi = (double) i;
x(i, 0)  = xi;
xx.push_back((double) i);
}

printf("function value: %.2f\n", stan::math::vecToDouble(xx));

stan::math::var y = stan::math::vecToDouble(x);
printf("vecToDouble(x) = %.2f\n", y.val());

std::vector<double> g;
std::vector<stan::math::var> in(x.data(), x.data() + x.rows() * x.cols());
for (int i=0; i<g.size(); ++i)
{
printf("g[%d] = %.2f\n", i, g[i]);
}

return 0;
}
``````

However, once I want to call it from Stan it leads to this error

…/Library/R/3.4/library/RcppEigen/include/Eigen/src/Core/functors/AssignmentFunctors.h:24:104: error: assigning to ‘double’ from incompatible type 'const stan::math::var’
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }

and a couple of errors follow after that which seem to be related to this error.

As a side note, I first declared the Stan interface as described in https://github.com/stan-dev/math/wiki/Adding-a-new-function-with-known-gradients like:

``````namespace stan {
namespace math {

double vecToDouble(const std::vector<double>& x);

var vecToDouble(const std::vector<var>& x);

}
}
``````

But this lead to an error saying that the function `vecToDouble` wasn’t declared. I could see in the generated Cpp file that the variable passed into the function is declared as `Eigen::Matrix<stan::math::var, Eigen::Dynamic, 1>`, so I changed the types and the function can apparently be found.

Any help will be greatly appreciated!

Regards,
Jonas

Operating System: OS X 10.12
Interface Version: RStan 2.16.2
Compiler/Toolkit: clang-900.0.38

The solution to this issue is quite simple as I got know in the thread Barriers to New Developers. Basically, one should not expose a vector-valued function based on `std::vector`, but always based on `Eigen::Matrix`. Additionally, there always has to be an overloaded function definition for both `double` and `var`.

``````namespace stan {
namespace math {

inline double
vecToDoubleTwo(const Eigen::Matrix<double, Eigen::Dynamic, 1>& m) {

double val = 0;
for (int i=0; i<m.size(); ++i) val += m(i) * m(i);

return val;
}

inline var
vecToDoubleTwo(const Eigen::Matrix<var, Eigen::Dynamic, 1>& m) {
using Eigen::Matrix;

Matrix<double, Eigen::Dynamic, 1> m_d(m.rows());
for (int i = 0; i < m.size(); ++i)
m_d(i) = m(i).val();

double val = stan::math::vecToDouble(m_d);

vari** varis
= ChainableStack::memalloc_.alloc_array<vari*>(m.size());
for (int i = 0; i < m.size(); ++i)
varis[i] = m(i).vi_;

= ChainableStack::memalloc_.alloc_array<double>(m.size());
for (int i = 0; i < m.size(); ++i)