# Why can't I reshape to any dimensions?

Bug introduced in 11.0 and fixed in 11.3.0

I am trying to reshape a $2 \times 2 \times 2$ array into a $n \times m$ array. It seems that if the matrix is defined via SparseArray, the ArrayReshape command doesn't care what $n$ and $m$ I choose, it always reshapes it to a $4 \times 2$ array.

In this code I try to reshape to $1 \times 8$:

Clear["Global*"]
m = SparseArray[{i_, i_, i_} -> 1., {2, 2, 2}];
mt = ArrayReshape[m, {1, 8}];
MatrixForm[mt]


$\begin{pmatrix}1.&0.\\ 0.&0.\\0.&0.\\0.&1.\end{pmatrix}$

Why does it work like that? Am I doing something wrong?

• Seems to have something to do with SparseArray, despite what the docs say. Dimensions@ArrayReshape[m, {1, 8}] gives {4, 2}, but Dimensions@ArrayReshape[Normal@m, {1, 8}] gives {1, 8}. Oct 28, 2017 at 12:42
• In Mathematica 11 Miguels code produces a list with 8 entries ({1,8} dimensional) Oct 28, 2017 at 14:51
• Mi edition is 11.2 ... Oct 28, 2017 at 15:59
• bug introduced in 11.2? Oct 28, 2017 at 16:37

ArrayReshape[SparseArraySparseArrayFlatten[m], {1, 8}]
(* or ArrayReshape[Flatten[m], {1, 8}] *)


SparseArray[<2>,{1,8}]

Normal @ %


{{1, 0, 0, 0, 0, 0, 0, 1}}

For the special case where the desired shape is a list with Length equal to Times@@Dimensions[m], you can also use SparseArraySparseArrayFlatten:

SparseArraySparseArrayFlatten[m]


SparseArray[<2>,{8}]

Normal @ %


{1, 0, 0, 0, 0, 0, 0, 1}

• That's right @kglr but my aim is not a $1 \times 8$ array, but any $n \times m$ array. The $1 \times 8$ in the code was just an example. Oct 28, 2017 at 16:01
• @Miguel, this approach works for any n and m. For example, ArrayReshape[SparseArraySparseArrayFlatten[m], {5, 3}, x] gives SparseArray[<9>,{5,3}]  as it should
– kglr
Oct 28, 2017 at 16:29
• Sorry, you're right. Thank you @kglr Oct 29, 2017 at 2:07
• @MiguelBolín, my pleasure. Thank you for the accept. And welcome to mma.se.
– kglr
Oct 29, 2017 at 2:08

It seems one have to make SparseArray to Normal first to reshape it.

m=SparseArray[{i_,i_,i_}->1,{2,2,2}];
ArrayReshape[m,{1,8}]//Normal


But now

ArrayReshape[Normal@m,{1,8}]


Not sure if this is by design or not.

• Okay but then I loose the computation saving of SparseArray, right? When you make it Normal it adds all the zeros and you carry them along Oct 28, 2017 at 13:29
• @MiguelBolín that is right. THat was the only way I could find to get it to work. I suggest you use Kglr solution using SparseArraySparseArrayFlatten which I did not know about. Oct 28, 2017 at 15:21
• mt = SparseArray@ArrayReshape[Normal@m, {1, 8}][[1]] Oct 28, 2017 at 15:22
• Or just mt = SparseArray@ArrayReshape[Normal@m, {1, 8}] for the 1 x 8 Oct 28, 2017 at 15:37
• I guess that has the same problem as Nasser's, right @BobHanlon ? You are adding the zeros and carrying them along. Oct 28, 2017 at 16:04

Comparing the timings for the approaches proposed by kglr and Nasser (modified):

\$HistoryLength = 0;

m = SparseArray[{i_, i_, i_} -> 1., {16, 16, 16}];

(kglr = ArrayReshape[SparseArraySparseArrayFlatten[m], #] & /@ {{1,
16^3}, {16^3, 1}, {128, 32}, {32, 128}}) // RepeatedTiming


(nasser = SparseArray@ArrayReshape[Normal@m, #] & /@ {{1, 16^3}, {16^3,
1}, {128, 32}, {32, 128}}) // RepeatedTiming


Verifying their equivalence

kglr === nasser

True
`