-
-
Notifications
You must be signed in to change notification settings - Fork 484
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No obvious way to concatenate vectors and matricies #446
Comments
This is not supported yet but could be added. |
Considering that there are already I think it would also be nice to have methods to extend a matrix with a matrix or vector at the end rather than inserting them. For the record my workaround was to create a // Stride the range of included sets in this dataset
for s in sets {
// Load the images from the set which correspond to the training set
for i in range.clone() {
if let Ok(img) = image::open(format!("{}/s{}/{}.pgm", path, s, i)) {
bounds = img.dimensions();
images.push(image_vector(img));
} else {
return Err(format!("Failed to open image s{}/{}.pgm", s, i));
}
}
} |
I think that specifically for the @sebcrozet What do you think about this? Should this be a new issue? |
Extends a `Vector` with new rows populated from an iterator. Inspired by dimforge#446 (comment)
@blankenshipz Yes this would be useful! As you suggested this should be on a new issue. |
Extends a `Vector` with new rows populated from an iterator. Inspired by #446 (comment)
I would like to bump this issue : there is now Extend for |
So at one point I actually hacked together a prototype for a fairly generic solution to concatenating matrices and vectors. The tricky part is to make it work properly with static dimensions. I solved this by introducing a new trait The example above shows how you can do things like: let a = Matrix2::new(0, 0, 0, 0);
let b = Matrix2::new(1, 1, 1, 1);
let c = Matrix4::new(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);
let result: Matrix6x4<_> = bcat![a, b;
c];
println!("{}", result); which outputs
I think it can be extended to support any number of desirable features. (Note that the playground link might not work in the future if there are more breaking changes in |
Since another user asked for concatenation on Discord, I wanted to add some points about my previous suggestion. It is built around a trait Block<T> {
type Rows: Dim;
type Cols: Dim;
fn shape(&self) -> (Self::Rows, Self::Cols);
fn populate<S>(&self, output: &mut Matrix<T, Self::Rows, Self::Cols, S>)
where
T: Scalar,
S: StorageMut<T, Self::Rows, Self::Cols>;
} Matrix types have a trivial struct Horizontal<X>(pub X);
struct Vertical<X>(pub X);
struct Diagonal<X>(pub X);
impl<T, B: Block<T>> Block<T> for Horizontal<(B,)> { /* impl */ }
impl<T, B1: Block<T>, B2: Block<T>> Block<T> for Horizontal<(B1, B2)> { /* impl */ }
// and so on for higher-arity tuples, plus a slice impl:
impl<'a, T, B: Block<T>> Block<T> for Horizontal<&'a [B]> { /* impl */ }
// Analogous impls for `Vertical` and `Diagonal` The macro bcat![a, b;
c, d] translates to allocating storage and populating the recursive block defined by Vertical( (
Horizontal((a, b)),
Horizontal((c, d))
) ) These traits work across static and dynamic dimensions and mixes thereof by leveraging the support for dimension "algebra" already present in bcat![Diagonal((a, b))]
// equivalent in output to
bcat![ a, zero_1;
zero_2, b];
// with zero_1 and zero_2 appropriately sized matrices filled with zeros But it doesn't stop there, we can mix and match these qualifiers almost arbitrarily. For example, say we want to construct the matrix
where bcat![
Diagonal((a, c)), Vertical((b, d));
Horizontal((e, f)), g
] The good news is that all of this happens with a single allocation: the output matrix is allocated once and each block is filled in recursively. Finally, we can also do all this with slices (so a dynamic number of matrices): // Dynamic number of column entries
bcat![&[a, b];
&[c, d]]
// Dynamic number of rows
bcat![Vertical(&[a, b, c])]
// Dynamic number of diagonal blocks
bcat![Diagonal(&[a, b, c])]
// Mix and match (matrices must be dimensionally compatible of course)
bcat![a, Diagonal(&[a, b, c]);
d, &[e, f]]; Undoubtedly there would be some details to work out, but at the surface, it seems this API would be remarkably powerful given its simplicity. Unfortunately I don't foresee having time to look at this in the very near future, but I might be able to squeeze in a little bit of time soem time in the next few months? Alternatively I'd be happy to mentor someone who would like to give an implementation a try. |
This looks like a great idea @Andlon. Could we perhaps avoid having to write the bcat![
Diagonal((a, c)), Vertical((b, d));
Horizontal((e, f)), g
] could the macro directly understand this: bcat![
a, 0, b;
0, c, d;
e, f, g;
] where the macro would automatically understand that each |
That's an interesting proposition @sebcrozet! I've been thinking about this over the weekend, but I have not yet reached a clear conclusion. I'll outline my thoughts below. OK, so the first challenge is to distinguish The second - and much more significant - challenge, is how to actually accomplish this. For example, it is tempting to think of something like a bcat![ a, Zero, b,
Zero, c, d,
e, f, g] Unfortunately, this would not work with the recursive Next, we could imagine parametrizing The reason e.g. I think something in this direction can be done, however, and we can use a similar structure as our current API proposal, although I think we might have to sacrifice some of our perfectly well-defined recursive structure to accomplish this. I don't have more time to go into details right now, but I'll think about this and hopefully get back to it later. However, we can outline the main subproblems that need to be solved:
Food for thought... |
Just want to chime in. I'm playing with some LTI systems, where cascading systems is most easily done by matrix concatenation. I would hope to concatenate some SMatrix instences into larger SMatrices. But I cannot work out how to do that with DimSum etc. Even implementing a simple function Having a |
For anyone following this issue, there is now a complete |
When using a dynamic matrix, there is no clear way to extend a matrix not with copies of a single element, but with a vector (like with
insert_row
orinsert_column
) or with a matrix (counterpart toinsert_rows
orinsert_columns
). In fact judging by the names, I thought that they used a vector and matrix respectively and not a single value.This isn't mentioned at all in the reference and I haven't found anything in the API. Is there any reason that concatenation isn't supported when
insert_row
andinsert_column
exist? My current solution is to create avec
of vectors and use thefrom_columns
constructor.The text was updated successfully, but these errors were encountered: