6

I have a vector CD1 (120-by-1) and I separate CD1 into 6 parts. For example, the first part is extracted from row 1 to row 20 in CD1, and second part is extracted from row 21 to row 40 in CD1, etc. For each part, I need to compute the means of the absolute values of second differences of the data.

for PartNo = 1:6   

    % extract data                
    Y(PartNo) = CD1(1 + 20*(PartNo-1):20*(PartNo),:); 

    % find the second difference  
    Z(PartNo) = Y(PartNo)(3:end) - Y(PartNo)(1:end-2);  

    % mean of absolute value
    MEAN_ABS_2ND_DIFF_RESULT(PartNo) = mean(abs(Z));    

end

However, the commands above produce the error:

()-indexing must appear last in an index expression for Line:2

Any ideas to change the code to have it do what I want?

user123456
  • 364
  • 1
  • 3
  • 16
Tony YEe
  • 235
  • 1
  • 3
  • 13
  • Isn't `Y(PartNo)` a scalar? And the rhs a vector? – Xyand Nov 29 '12 at 14:45
  • So what is meaning of writing something like that: `Y(1) = [1 2 3]` ? And later `Y(1)(3:end)` - scalar indexing? – Xyand Nov 29 '12 at 14:57
  • Wait...I fear I've misunderstood your question. Forget my answer, go with @dustincarr's solution in stead :) – Rody Oldenhuis Nov 29 '12 at 15:30
  • Just a general remark: whitespace is FREE! There's no paper to save in a computer editor, and denser code doesn't make it any faster, so...open it up a bit, it's better on the eyes :) – Rody Oldenhuis Nov 29 '12 at 15:31
  • @RodyOldenhuis, you actually answered the specific question much better than I did, since the questions was specifically about the error message. – dustincarr Nov 29 '12 at 16:36
  • @dustincarr: Ah, but it wasn't complete to the extent that the error message also occurs when doing `a(2)(3)`, with a an ordinary matrix. But I'll un-delete my question, see what the OP thinks. – Rody Oldenhuis Nov 29 '12 at 16:41
  • Intersting to know that Octave support multiple indexing. `x = 1:3` then `x(1:2)(2)` is supported – obchardon Mar 27 '19 at 09:26

3 Answers3

9

This error is often encountered when Y is a cell-array. For cell arrays,

Y{1}(1:3) 

is legal. Curly braces ({}) mean data extraction, so this means you are extracting the array stored in location 1 in the cell array, and then referencing the elements 1 through 3 of that array.

The notation

Y(1)(1:3)

is different in that it does not extract data, but it references the cell's location 1. This means the first part (Y(1)) returns a cell-array which, in your case, contains a single array. So you won't have direct access to the regular array as before.

It is an infamous limitation in Matlab that you cannot do indirect or double-referencing, which is in effect what you are doing here.

Hence the error.

Now, to resolve: I suspect replacing a few normal braces with curly ones will do the trick:

Y{PartNo} = CD1(1+20*(PartNo-1):20*PartNo,:);   % extract data
Z{PartNo} = Y{PartNo}(3:end)-Y{PartNo}(1:end-2);  % find the second difference
MEAN_ABS_2ND_DIFF_RESULT{PartNo} = mean(abs(Z{PartNo}));  % mean of absolute value
Rody Oldenhuis
  • 37,726
  • 7
  • 50
  • 96
3

I might suggest a different approach

Y = reshape(CD1, 20, 6);
Z = diff(y(1:2:end,:));
MEAN_ABS_2ND_DIFF_RESULT = mean(abs(Z));
dustincarr
  • 1,365
  • 1
  • 9
  • 14
3

This is not a valid statement in matlab:

Y(PartNo)(3:end)

You should either make Y two-dimensional and use this indexing

Y(PartNo, 3:end)

or extract vector parts and use them directly, if you use a loop like you have shown

for PartNo = 1:6   

    % extract data                
    Y = CD1(1 + 20*(PartNo-1):20*(PartNo),:); 

    % find the second difference  
    Z = Y(3:end) - Y(1:end-2);  

    % mean of absolute value
    MEAN_ABS_2ND_DIFF_RESULT(PartNo) = mean(abs(Z));    
end

Also, since CD1 is a vector, you do not need to index the second dimension. Drop the :

Y = CD1(1 + 20*(PartNo-1):20*(PartNo));

Finally, you do not need a loop. You can reshape the CD1 vector to a two-dimensional array Y of size 20x6, in which the columns are your parts, and work directly on the resulting matrix:

Y = reshape(CD1, 20, 6);
Z = Y(3:end,:)-Y(1:end-1,:);
MEAN_ABS_2ND_DIFF_RESULT = mean(abs(Z));
angainor
  • 11,760
  • 2
  • 36
  • 56