# More views: concatenation, index lists, repeats of whole matrices, columns or rows

Issue #44 resolved
Marcin Junczys-Dowmunt created an issue

Hi again, Another few things that would be immensely useful:

1. A view that allows to subselect rows/columns based on a vector of indeces, possible with repetitions, permutations.
2. A view that allows for the concatenation of two or more matrices along specified dimensions.
3. Somewhat similar to the two above: A view that allows for the repetition of a whole matrix along a specified axis n times.
4. A view that allow for the repetition of all rows/columns n-times (the repeated rows would appear after one another).

I guess 2-4 could actually be implemented based on 1. alone.

Sorry, for spamming your issues lists.

Hi Marcin!

Thanks for all the good ideas. They will keep us busy for a while ;-)

Best regards,

Klaus!

1. reporter

Oooh, one more!

A reshaping view, like numpy's reshape operation.

Where in your code would I look for inspirations if I wanted to take a jab at some of those ideas myself? I will be happy to contribute back if something comes out of it.

It seems that you can already reshape dense matrices, using `CustomMatrix`.

Here's an example that a colleague and I came up with today:

```        blaze::DynamicVector<double> v{1,2,3,-1,-2,-3};
blaze::DynamicVector<double> u{0,0,0,0,0,0};
blaze::DynamicMatrix<double> space_matrix{{1,3},{4,7}};
ujs = space_matrix * vit;

std::cout << ujs << '\n';
std::cout << u << std::endl;
```

which correctly spits out

```(           -2           -4           -6 )
(           -3           -6           -9 )

(          -2 )
(          -4 )
(          -6 )
(          -3 )
(          -6 )
(          -9 )
```

I don't know if similar tricks will work on sparse types.

Hi Evan!

Thanks a lot for sharing this solution. It's great to see that the available features already provide such flexibility. Unfortunately this trick does not work on sparse matrices, as `CustomMatrix` only works on arrays and always represents a dense matrix. However, in just a few weeks we will release row and column selection views, which will enable (almost) all of the features requested above. If you are interested, check out issue #48, which we are currently working on. It is already possible to select specific elements from a dense or sparse vector, the selection of rows and columns from dense and sparse matrices will be available soon.

Thanks again,

Best regards,

Klaus!

Hi Klaus,

My comment was only responding to @emjotde's request for numpy-like `reshape`, which lets you take a matrix (or vector) and reinterpret it as any matrix (or vector) with the same number of elements (but with a different shape). eg. a 6-element vector can be seen as a 2*3 matrix (as in my example above).

Honestly, I couldn't believe it when the code above worked---it seems kind of magical. I hope this surprise functionality is protected by some unit tests :D

• changed status to open
2. ## Summary

With the introduction of element selections, row selections, and column selections (see issue #48) it is now possible to ...

• ... subselect vector elements based on a vector of indices, including repetitions and permutations;
• ... subselect rows/columns based on a vector of indices, including repetitions and permutations.

The features have been implemented, tested, optimized, and documented as required. They are immediately available via cloning the Blaze repository and will be officially released in Blaze 3.3.

## Examples

#### Repeating a Matrix Row-Wise

```blaze::DynamicMatrix<int> A
{ { 1, 0, 2, 0 }
, { 0, 3, 0, 4 }
, { 5, 0, 6, 0 } };

DynamicMatrix<int> B;

B = rows<0,1,2,0,1,2>( A );
```
```    ( 1, 0, 2, 0 )
( 0, 3, 0, 4 )
B = ( 5, 0, 6, 0 )
( 1, 0, 2, 0 )
( 0, 3, 0, 4 )
( 5, 0, 6, 0 )
```

#### Repeating a Matrix Column-Wise

```blaze::DynamicMatrix<int> A
{ { 1, 0, 2, 0 }
, { 0, 3, 0, 4 }
, { 5, 0, 6, 0 } };

DynamicMatrix<int> B;

B = columns<0,1,2,3,0,1,2,3>( A );
```
```    ( 1, 0, 2, 0, 1, 0, 2, 0 )
B = ( 0, 3, 0, 4, 0, 3, 0, 4 )
( 5, 0, 6, 0, 5, 0, 6, 0 )
```

#### Repeating Each Row of a Matrix

```blaze::DynamicMatrix<int> A
{ { 1, 0, 2, 0 }
, { 0, 3, 0, 4 }
, { 5, 0, 6, 0 } };

DynamicMatrix<int> B;

B = rows<0,0,1,1,2,2>( A );
```
```    ( 1, 0, 2, 0 )
( 1, 0, 2, 0 )
B = ( 0, 3, 0, 4 )
( 0, 3, 0, 4 )
( 5, 0, 6, 0 )
( 5, 0, 6, 0 )
```

#### Reversing the Columns of a Matrix

```blaze::DynamicMatrix<int> A
{ { 1, 0, 2, 0 }
, { 0, 3, 0, 4 }
, { 5, 0, 6, 0 } };

DynamicMatrix<int> B;

B = columns<3,2,1,0>( A );
```
```    ( 0, 2, 0, 1 )
B = ( 4, 0, 3, 0 )
( 0, 6, 0, 5 )
```

I’m having the same issue, I wonder what is the latest solution of `reshape` on DynamicMatrix now?

For example, I want to flatten a (10,5) matrix into a (1, 50) matrix before feeding it to an NN layer. So a typical `reshape` would be helpful here.

Hi @Ecolss Logan !

Blaze doesn’t provide a `reshape()` operation for two reasons:

1. Blaze uses padding to speed up performance. Therefore you cannot expect that a 10x5 matrix consists of exactly 50 contiguous elements. Since padding can make a big difference in terms of performance (e.g. factor 4-5 for the matrix/matrix multiplication of 3x3 matrices), we deem the performance win more important than the `reshape()` operation.
2. It is semantically not clear whether the flattening should result in a matrix or a vector. You would expect a 1x50 matrix, but other users expect a vector with 50 elements. We cannot express this runtime decision with types, since Blaze distinguishes between vectors and matrices. We would need a generalized tensor implementation for that (see issue #53).

The best approach to approximate this operation is explicitly deactivate padding (see Padding) and to build on `CustomVector` and `CustomMatrix`:

```using namespace blaze;