"Interchanging" matrices and vectors: building a matrix from transformed unit vectors?

PressRex profile image
by PressRex
"Interchanging" matrices and vectors: building a matrix from transformed unit vectors?

Current Representation

Here is my current representation of an M by N row-major Matrix

struct Matrix<T, const M: usize, const N: usize> {
    entries: Box<[[T; N]; M]>
}

I think this representation helps distinguish types very nicely, and I would like to stick with this general idea. Matrix<u32, 2, 2> is very different from Matrix<u32, 3, 2>. And this design allows for nice things like impl<..> Matrix<T, M, M> {..}–exclusive methods for square matrices like determinants without runtime checks and nasty error handling! (never seen that before). I would also like keeping the entries on the heap.

I'm similarly representing vectors like the following:

struct Vector<T, const M: usize> {
    entries: Box<[T; M]>
}

I'm using M here in the definition (and throughout) because I want these to be column vectors–normal vectors–and not row vectors with notation being consistent with the matrix struct. Also, this is not to be confused with std::collections::Vec; just making sure.

Motivating Idea: "Interchanging" Matrices and Vectors

Now, I would like to implement From<Vector<T, M>> for Matrix<T, M, N>.

Note 1. Mathematically, this is representative of being able to construct a matrix whose effect is to transform the given space such that the unit vectors go to the respective columns of the matrix. I would also like to do more "interchanging" somehow with these structs later.
Note 2. I believe From<Vector<T, M>> might not even be idiomatic. However, I think this would be an easy change from Matrix::from() to something like Matrix::from_transformed_unit_vectors(), anyway.

Attempting to do this, I can implement AsRef<[T; M]> (Numeric extends Clone and others).

impl<T, const M: usize> AsRef<[T; M]> for Vector<T, M> 
where
    T: Numeric,
{
    #[inline]
    fn as_ref(&self) -> &[T; M] {
        &self.entries
    }
}

This function returns a reference to the same heap-allocated array.

What if I want to implement a conversion the other way around? I want to take a row/column of a Matrix and treat it as a Vector (or row vector)? How would I do this other than the following, seemingly-clumsy way (which also allocates more memory–which I guess am forced to anyway):

impl<T, const M: usize> AsRef<Vector<T, M>> for [T; M]
where
    T: Numeric,
{
    fn as_ref(&self) -> &Vector<T, M> {
        &Vector::new(self.clone())
    }
}

This doesn't compile because of lifetime restrictions.

Question

I'm basically asking for an idiomatic way to implement Matrix::from_transformed_unit_vectors or a From conversion. I don't mind if the answer is to scrap my current representation of vectors and matrices (or even if the answer lies in introducing a new intermediary struct to help with the job). However, I would like keeping the strict typing of matrices of different dimensions (as well as with vectors).

Source: View source

PressRex profile image
by PressRex

Subscribe to New Posts

Lorem ultrices malesuada sapien amet pulvinar quis. Feugiat etiam ullamcorper pharetra vitae nibh enim vel.

Success! Now Check Your Email

To complete Subscribe, click the confirmation link in your inbox. If it doesn’t arrive within 3 minutes, check your spam folder.

Ok, Thanks

Read More