1

MATLAB allows to index arrays with other arrays.

Usually the result has the same size, but apparently this is not always the case.

It must have to do with "column priority" in MATLAB.

QUESTION:

I am wondering how to find a consistent solution on how to get [1 1] in

size(index_array)==size(array(index_array)) for ALL sizes of index_array.

To be specific I post a sample script:

baseAlt = [ 0, 11000, 20000, 32000, 47000, 51000, 71000 ];

xRow = 10000*[ 1, 2, 3, 4, 5];
xCol = 10000*[ 1; 2; 3; 4; 5];
 xSq = 20000* rand(5);

reg = arrayfun( @(alt) sum(alt>=baseAlt), xRow);
ans1 = baseAlt(reg);
disp(all(size(baseAlt(reg))==size(reg))); %ans=2

reg = arrayfun( @(alt) sum(alt>=baseAlt), xSq);
ans2 = baseAlt(reg);
disp(all(size(baseAlt(reg))==size(reg))); % ans=2

%BUUUUT
reg = arrayfun( @(alt) sum(alt>=baseAlt), xCol);
ans3 = baseAlt(reg);
disp(all(size(baseAlt(reg))==size(reg)));       % row, instead of column
                                                % zero when comparing size
%MOREOVER
reg = arrayfun( @(alt) sum(alt>=baseAlt), xCol);
ans4 = baseAlt([reg,reg]);
disp(all(size(baseAlt([reg,reg]))==size([reg,reg])));  % we get true here

As you can see, all the matrices retain the shape of the indexing matrices, APART from the case when a ROW gets indexed by a COL. Could anyone shed light on this please?

EDIT 1: Used "all" instead of "sum", which, as Dani pointed out, is much more elengant here.

Przemek M
  • 55
  • 6

1 Answers1

0

I was not aware indexing worked in the way you showed (the Matrix indexing a vector especially). Neither did I find this in the Matlab documentation on a first look.

The reason why your 3rd example does not work is because Matlab interprets the index vector as a linear index (whether it is a row- or column vector is inconsequential).

You can easily implement your desired behavior by using this small anonymous function:

arrayIndexing = @(ar, ind)arrayfun(@(x)ar(x),ind);

With your example code (for quick testing):

baseAlt = [ 0, 11000, 20000, 32000, 47000, 51000, 71000 ];
xRow = 10000*[ 1, 2, 3, 4, 5];
xCol = 10000*[ 1; 2; 3; 4; 5];
xSq = 20000* rand(5);
arrayIndexing = @(ar, ind)arrayfun(@(x)ar(x),ind);
reg = arrayfun( @(alt) sum(alt>=baseAlt), xSq);
result = arrayIndexing(baseAlt,reg);
disp(all(size(result)==size(reg))); % ans=1
reg = arrayfun( @(alt) sum(alt>=baseAlt), xCol);
result = arrayIndexing(baseAlt,reg);
disp(all(size(result)==size(reg)));  % ans=1

This will work for any format of the indexing vector/array.

Note the usage of all instead of sum, I think it is the more fitting function here.

Dani Gehtdichnixan
  • 1,265
  • 1
  • 11
  • 21
  • I am aware of arrayfun, it is, as any "type-independent" function, slow. The topic of whether to use "for", or "arrayfun" or vectorisation is BEAUTIFULLY discussed here: http://stackoverflow.com/questions/12522888/arrayfun-can-be-significantly-slower-than-an-explicit-loop-in-matlab-why That is why I wanted to avoid using "arrafuns", mostly nested in other "arrayfuns", which is the case when you have more matrices to work on. To sum up--I'd like to use MATLAB's flexible indexing framework. – Przemek M May 15 '14 at 11:03
  • And ofc "all" is the much more fitting function! – Przemek M May 15 '14 at 11:05
  • Okay, if speed is of the essence, arrayfuns are not the way to go, thats true. But I don't think you will get around the whole 'index vector'=>'linear index' issue. All I can think of is writing a function that basically does the indexing as you described, then checks if the index is a column vector and if so transposes the output. Not pretty but I think that's the most straight-forward way - AFAIK. – Dani Gehtdichnixan May 15 '14 at 11:08
  • That is the way I do it now, as the ONLY case in which my fast approach goes wrong is when a row meets a col. So I do an if with a size check that would eventually transpose 'baseAlt'. As a purist, I do not like it... hence my Q. – Przemek M May 15 '14 at 11:14
  • REMARK: But maybe others will prove, that using 'isrow/isvector' is in fact the cleanest way out of linear indexing, rearranging etc. business. – Przemek M May 15 '14 at 11:17