0

I have a vector with lots of consecutive values, I want to write these values in to a matrix (to do something row-wise later) but I can't quite see how to do this. For example:

x = [1,2,4,5,7,8,9,11,12,13,14,15]

needs to become

y = [1,2;4,5;7,8,9;11,12,13,14,15]

I've seen a few similar posts that just check if the values are consecutive, but I can't see how to go from those posts to writing the matrix I want.

Edit: This is actually impossible as matrices need to be the same dimensions, (like I can't randomly have some rows longer than others) but I still can't see how to divide the vector up in to smaller sections of consecutive numbers.

user2587726
  • 169
  • 2
  • 11
  • There are many options of doing it (like a struct or if this pattern continues a lower triangular matrix), it depends also on what you are planing to do later with it. – Irreducible May 04 '23 at 05:19
  • 1
    The array `y` you want to create in not valid in MatLab; Dimensions of arrays being concatenated are not consistent – il_raffa May 04 '23 at 06:37
  • 1
    What you're looking for is often called a "ragged" or "jagged" array. Matlab's default arrays (matrices) don't support this. But you may still be able to accomplish what you need with cell arrays (see [this question/answers](https://stackoverflow.com/questions/22460845/matlab-2d-array-rows-different-lengths)) or by padding unused rows/columns with a value like `NaN`, or via `sparse` arrays. – horchler May 04 '23 at 14:07
  • @il_raffa I know I said that in the question? – user2587726 May 09 '23 at 06:10
  • @Irreducible sounds grand, can you suggest a few of the options? I want to do some more maths with the output, ideally take the RMS of the consecutive values. – user2587726 May 09 '23 at 06:14

1 Answers1

0

You can generate a cell array by using accumarray to apply an anonymous function to groups of inputs defined by the condition that the consecutive increments within each group are 1. Note that this works because the group labels are sorted. See also diff and cumsum to understand what the code is doing.

x = [1,2,4,5,7,8,9,11,12,13,14,15];
ind = cumsum([true; diff(x(:))~=1]); % generate group labels
y = accumarray(ind, x(:), [], @(x){x.'}) % collect values based on group labels

In the example, the code gives

>> celldisp(y)
y{1} =
     1     2
y{2} =
     4     5
y{3} =
     7     8     9
y{4} =
    11    12    13    14    15
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • Looking good but I always get muddled up with cell arrays - once I've split it up like this, is there a way of calculating the RMS of the values? Like for i = 1:length(y) z = rms(y(i)) end – user2587726 May 09 '23 at 06:12
  • The simplest way is `cellfun(@rms, y)`. Or, using your approach: `for i = 1:length(y), z = rms(y{i}), end` – Luis Mendo May 09 '23 at 11:35