Calculate distance vector and distance matrix

Hi Everyone,

Since I am working on spatial analysis, it is common to calculate distances between locations and generate distance vector and matrix. I am just wondering how one would calculate the Euclidian distance (or any type of distance) when writing code for Stan? Is that okay to write functions which may only be used in one model? Or should I write a class and include all specific functions instead of writing different functions in different .hpp?


Lu Zhang

It is fine to write functions that are only used (at the moment) in one model (that we know of). Although, in this case, there are already a bunch of functions related to distance

StanFunction Arguments ReturnType Page
118 distance (row_vector x, row_vector y) real 418
119 distance (row_vector x, vector y) real 418
120 distance (vector x, row_vector y) real 418
121 distance (vector x, vector y) real 418
561 squared_distance (row_vector x, row_vector y[]) real 418
562 squared_distance (row_vector x, vector y[]) real 418
563 squared_distance (vector x, row_vector y[]) real 418
564 squared_distance (vector x, vector y) real 418

But we rely on their being one function per .hpp file where the function name is the name of the .hpp file.

1 Like

Thank you very much! I will check these distance functions.

There’s distance and squared_distance in the language and the math library. Do you need more than that?

Hi Daniel,

Thanks, I tried the function stan::math::distance, but it seems to me that all stan function do not accept block of Matrix as inputs.
For example: if I use this line:
dist_v[j] = stan::math::distance(coords.row(i), coords.row(j));
I will get the following error message:
../../../../.././stan/math/prim/mat/fun/distance.hpp:24:5: note: candidate template ignored: could not match 'Matrix' against 'Block' distance(const Eigen::Matrix<T1, R1, C1>& v1

If I want to use the function distance, I have to create two local variables in type Eigen::Matrix, copy the coordinates, and then call the function distance.

I got a similar error message when I tried to apply function sort_indices_asc to the first column of a matrix. My code was:
vector<int> sortind = stan::math::sort_indices_asc(coords.col(0));
The error message was:
../../../../.././stan/math/prim/mat/fun/sort_indices.hpp:63:41: error: no type named 'type' in 'stan::math::index_type<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true> >' typedef typename index_type<C>::type idx_t; ~~~~~~~~~~~~~~~~~~~~~~~~^~~~ ../../../../.././stan/math/prim/mat/fun/sort_indices_asc.hpp:25:14: note: in instantiation of function template specialization 'stan::math::(anonymous namespace)::sort_indices<true, Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1>, -1, 1, true> >' requested here return sort_indices<true>(xs);

Is there any way to directly apply these function over a row of a matrix?

Yes, just pull the matrix row out, which will be
RowVectorXd. You can then have a loop if you want over
rows. You can do same with columns, which will be faster,
because Eigen stores in column-major order. Sometimes
transposing in one go then using columns is faster than
pulling out all the rows.

  • Bob

Okay, I will try. Thanks!