0

I would like to extract a sub cell-array from a cell array, but for some reason, the indexing rules for cell arrays don't work as they do for regular arrays.

For example,

T = cell(4,4);
for i = 1:4
    for j = 1:4
        T{i,j} = [(j-1)*4 + i];
    end    
end

which produces

T =

  4×4 cell array

    [1]    [5]    [ 9]    [13]
    [2]    [6]    [10]    [14]
    [3]    [7]    [11]    [15]
    [4]    [8]    [12]    [16]

But when I extract a 2x2 subarray from the upper left corner, I get

{T{1:2,1:2}}

ans =

  1×4 cell array

    [1]    [2]    [5]    [6]    

Why don't I get a 2x2 cell array?

I can reshape the array to get

reshape({T{1:2,1:2}},2,2)

ans =

  2×2 cell array

    [1]    [5]
    [2]    [6]

but it isn't obvious why I should need to do this. Unless I am missing something, I don't see any ambiguity in applying indexing rules to cell-arrays in the same way they are used for regular arrays.

Ultimately, I would like to be able to rearrange blocks to create a new cell array, i.e.

S = {T{[1 3 4],[1 3 4]}}

Is there a better way to do this other than using reshape?

Note : It was pointed out this question is a duplicate of this question. I didn't see those original posts. And perhaps, had I only had one dimensional cell arrays, I would have never come across the problem I had above. For example, if I had had

P = {[1],[2],[3],[4]}

then

{P{1:2}}

and

P(1:2)

both produce

1×2 cell array

    [1]    [2]

Using my T from above, though, the following are different :

{T{1:2,1:2}}

ans =

  1×4 cell array

    [1]    [2]    [5]    [6]

T(1:2,1:2)

ans =

  2×2 cell array

    [1]    [5]
    [2]    [6]

I may be dragging out this point, but I do think it is very odd that Matlab unravels 2d cell arrays when using {}, but not when using (). I know that {} can sometimes mean a "list" rather than a structured array (possibly for use as an argument list?) but then it is possible to construct structured arrays using {} (.e.g. {[1],[2]; [3],[4]}, so odd that they can't be indexed in a reciprocal manner.

Donna
  • 1,390
  • 1
  • 14
  • 30
  • 3
    You should use `T(1:2,1:2)`. – m7913d Sep 25 '17 at 15:02
  • 3
    Short answer: Use `{}` when you want to extract cell *contents*. Use `()` to extract cells: `T(1:2, 1:2)` See the linked duplicate for more detail and links. – gnovice Sep 25 '17 at 15:02
  • 1
    Regarding your note: what exactly is a "block matrix"? Your examples are just 2D cell arrays. And once you understand the difference between `()` and `{}` indexing, the extension to multiple dimensions is pretty simple (and well described by the documentation links). I just don't see how this question is unique. – gnovice Sep 26 '17 at 00:23
  • 2
    Possible duplicate of [How do concatenation and indexing differ for cells and arrays in MATLAB?](https://stackoverflow.com/questions/2662964/how-do-concatenation-and-indexing-differ-for-cells-and-arrays-in-matlab) – Andras Deak -- Слава Україні Sep 26 '17 at 09:41
  • @AndrasDeak While I appreciate constructive feedback, the means [by which you elected to police the review queue](https://stackoverflow.com/questions/46413036/how-worked-visibilitychange/46414039?noredirect=1#comment79786051_46414039) is, in my estimation, quite unnecessary. – msanford Sep 26 '17 at 13:00
  • @msanford I chose the only means available. I could either go to meta to open the umpteenth duplicate about "oh my reviewers should skip more", or get in touch with the reviewers asking them to pay more attention. Considering how I'm a hopeless optimist, I chose to get in touch, even though I know this is mostly annoying noise to the people involved. But hey, at least I'm not the only one who's annoyed at the end of the day;) – Andras Deak -- Слава Україні Sep 26 '17 at 13:51
  • 1
    @Donnna What do you want from your last example that `S = {T([1 3 4],[1 3 4])}` doesn't give you? If you could show us the input and desired output for your actual data it would probably help. – beaker Sep 26 '17 at 15:05
  • @m7913d Thank you for the short and concise answer! That was exactly what I needed - I hadn't thought to just use () for cell arrays. – Donna Sep 28 '17 at 00:39
  • @beaker My "real" problem involves block matrices, which I later simplified for this post. I'll edit my original post. – Donna Sep 28 '17 at 00:42
  • 2
    Yes, the way cell arrays are handled is rather odd, but I guess they were just running out of characters to use for brackets. Square brackets are used for creating arrays, curly brackets for creating cell arrays, and parentheses for indexing. For accessing the elements of a cell array as a comma-separated list, they were kinda stuck, so they re-used the curly brackets. – beaker Sep 28 '17 at 13:57
  • 2
    As for unraveling the cell array, as mentioned in some of the answers of the marked duplicates, what `T{1:2,1:2}` actually gives you is a comma-separated list `1,2,5,6`. When you put curly brackets around that, You get a *new* cell array `{1,2,5,6}`. If you had put square brackets around that instead (assuming equal-sized elements) you would get a new array `[1,2,5,6]`. – beaker Sep 28 '17 at 13:59
  • @beaker One point of confusion I had in reading the duplicate post is in the distinction between the "contents" of a cell and the cell itself. In my example above, I guess I'd have to do `cell2mat(T(1:2,1:2))` to really get the block sub matrix. Again, in my real example, each cell is itself a matrix. – Donna Sep 28 '17 at 17:11
  • 2
    Exactly. `cell2mat` will preserve the relative positions of the elements in the index list when creating the matrix (assuming the contents are the appropriate dimensions and all the same type). – beaker Sep 28 '17 at 17:34

0 Answers0