stan-dev / math

The Stan Math Library is a C++ template library for automatic differentiation of any order using forward, reverse, and mixed modes. It includes a range of built-in functions for probabilistic modeling, linear algebra, and equation solving.
https://mc-stan.org
BSD 3-Clause "New" or "Revised" License
744 stars 187 forks source link

matrix to array-of-vectors and vice-versa #669

Open bob-carpenter opened 6 years ago

bob-carpenter commented 6 years ago

Summary:

Implement functions that will look like this in Stan:

// to_matrix(rv)[i, j] = rv[i, j]
matrix to_matrix(row_vector[] rv);  

// to_matrix(v)[i, j] = v[j, i]
matrix to_matrix(vector[] x);

// array_of_rows(y)[i, j] = y[i, j]
row_vector[] array_of_rows(matrix y);

// array_of_columns(y)[i, j] = y[j, i]
vector[] array_of_columns(matrix y);

Additional Info

Also need to add mc-stan/stan.

Current Version:

v2.17.0

wds15 commented 6 years ago

would these functions work row / column wise?

so array_of_columns would take the matrix, then slice it by column and make them an array?

... and yes, these functions would be very useful...

bob-carpenter commented 6 years ago

This is the problem with these definition---not clear what they mean by just looking at them. I'll edit to make the intention clear.

Inferrator commented 4 years ago

In the context of using map_rect this is actually quite relevant. In plain c++, I would be able to create pointers, i.e. create an Eigen or Armadillo vector/matrix based on an array of reals or whatever.

bob-carpenter commented 4 years ago

@Inferrator: Thanks for commenting. map_rect is one of the main applications, as are simple things like multivariate distributions where you often want to access the data by column or by row.

Internally, we can wrap the data pointer of a std::vector to create an Eigen::Map<VectorXd>, for example, but Stan works by copy, not by reference sharing, so we'll have to copy anyway. It's not so easy to do the other way because we haven't customized std::vector allocators yet.

The bigger question is whether we can do things like program analysis in the compiler to figure out when we can get by without copying. But that's for the stanc3 repo...

Inferrator commented 4 years ago

Bob: thanks for clearing this up, that is very helpful. Copies do become an issue when you have to pass on covariance matrices of dim 20 or above - it's a lot of copying.

bob-carpenter commented 4 years ago

Copying in Eigen or std::vector hits the C++ heap using malloc. It doesn't hit autodiff memory. That's good in that it doesn't increase memory headroom requirements, but bad in that it uses malloc, which is expensive.

The copying is often dominated by something like a matrix solve or matrix multiply (cubic), or even a matrix-vector multiply (quadratic, but with autodiff).

We're trying to reduce that on the inside by passing expression templates further along and inside the GPU by merging kernels.

On Feb 25, 2020, at 10:05 PM, Inferrator notifications@github.com wrote:

Bob: thanks for clearing this up, that is very helpful. Copies do become an issue when you have to pass on covariance matrices of dim 20 or above - it's a lot of copying.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

spinkney commented 3 years ago

This is also useful for the hmm_marginal() function. Where one will have an array of simplexes that need to be converted to a matrix. (I guess hmm_marginal()could have an additional signature for this case though)

SteveBronder commented 3 years ago

^for hmm marginal one thing I've been thinking about is adding row/column simplex matrices to the language