On 8/8/12 5:29 PM, Marcus Brubaker wrote:
> On Wed, Aug 8, 2012 at 5:11 PM, Bob Carpenter <
ca...@alias-i.com <mailto:
ca...@alias-i.com>> wrote:
> The main reason for having these types is that we can
> infer that for
>
> row_vector * vector
>
> the result type is real.
>
>
> I know we've talked about this before but I forget the results. Couldn't we do that by making a 1x1 matrix implicitly
> convertible to a scalar and vice-versa?
I'm not saying it's impossible, but I don't see how
we could make it work. It would require a richer
type-inference scheme than what we have, which only
casts an int up to a real. Given the way code's generated,
it'd be easiest if we could do it on the C++ side.
But there are several issues (see below).
Overall, though, I prefer stricter typing with less
coercion. I think it makes the programs easier to understand
and debug.
What we've done in the probability functions is make
a vector view wrapper so that we can treat a scalar
the same way as a vector. But if we started allowing
> A bigger issue is moving the matrix sizes into
> the array declaration. What we have now is:
>
> matrix[4,5] x[3];
>
> for a 3-array of 4x5 matrices to
>
> matrix x[3,4,5]
>
> This is possible, but I worry that it won't be clear where
> the matrix is.
>
>
> I would strongly argue against this. I think it would be confusing and lead to a lot of problems. For instance, with
> the above, x[1,:,:] would be a 4x5 matrix but what would x[:,:,1] be?
Right now, x[1] is well formed, but neither x[1,,] nor x[1,:,:] nor x[:,:,1] is.
I started going down that route. It would involve either more views or
copying. Either way, it would be nice to support.
> If it's a 3x4 matrix, then it would involve a lot
> of unpleasant copying. So long as internally a matrix has to be 2D, that should be explicit to users, like it is now.
That's my preference, too.
> In a world with more hours in the day I would go and implement a multidimensional array with a Map for Eigen::Matrix to
> allow us to just do:
>
> real x[3,4];
>
> instead of
>
> matrix[3,4] x;
>
> or
>
> real[0,1] x[7,8];
>
> and be done with it :)
This isn't quite going to yield the same result because
it doesn't distinguish row vectors from column vectors.
The problem I see is with declarations
real x[5];
real y[5];
the expression (x * y) is ambiguous. If x is a row
vector and y a column vector, then (x * y) is a scalar.
If x is a column vector and y a row vector, then
(x * y) is a matrix. Or maybe we'd only promote 1D arrays
to column vectors? Then (x * y) would be undefined, but
(x' * y) and (x * y') would be well-defined.
And this isn't just a type issue of distinguishing a 1x1
matrix from a scalar -- there are different result shapes!
At the underlying storage level it would make sense
to do our own implementation rather than using std::vector.
It'd be faster and less bulky.
Then we could use as_matrix(x), as_vector(x), or
as_row_vector(x) to create a matrix view of the underlying
data wherever necessary. I don't know how hard it would be
to implement a new Eigen-like matrix wrapper (I haven't studied
how Map is implemented -- looking into Eigen always makes my
head spin).
In Stan, we could also just do the copying. So we could have:
real[,] to_array(matrix);
real[] to_array(vector);
real[] to_array(row_vector);
matrix to_matrix(real[,]);
vector to_vector(real[]);
row_vector to_row_vector(real[]);
With the way we're using Eigen on an operation-by-operation basis
(I know, Ben, this isn't optimal!), this might not make that
much of a difference performance-wise.
> At any rate, since this is all started based on a feature that's not yet implemented (vectors and matrices of bounded
> variables) and is not likely to be widely used at first I think we can let it rest for the near term. There are options
> which are consistent with the current notation (matrix<real[0,1]>[3,4] for instance) and don't cause parsing problems.
> And, since it relates to the larger issue of multidimensional arrays, it may get solved in another way at some point in
> the future.
We just need to nail down what the basic syntax is.
I guess we've found our bike-shed issue
http://en.wikipedia.org/wiki/Parkinson's_Law_of_Triviality
But then getting basic syntax right is important for
understandability of the code.
- Bob