Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indexing of 2D array in matlab

I have a 6X4 matrix M1 containing only zeros. I also have two 1D arrays Y1 and Y2 each with length 4.The two arrays contain the desired index values. Now, I want to set(convert to 1) the elements of matrix M1 such that M1(Y1:Y2) is equal to 1

for ex: Y1=[1 2 2 1] and Y2=[3 4 5 3]
then, M1 should be

 1 0 0 1
 1 1 1 1 
 1 1 1 1
 0 1 1 0
 0 0 1 0
 0 0 0 0

I can do this using for loop. But is there any optimised way to do it? (I intend to use much bigger matrices)

like image 916
user2378404 Avatar asked Jun 19 '13 07:06

user2378404


People also ask

How do you find the index of a 2D array?

Two-dimensional (2D) arrays are indexed by two subscripts, one for the row and one for the column. Each element in the 2D array must by the same type, either a primitive type or object type.

What is an indexing array in MATLAB?

Array indexingIndices are provided as (row, column). So the index (5, 6) selects the element on the fifth row and sixth column. An index like (5, 6) selects a single element of an array, but we can also access sections of the matrix, or slices.

Does MATLAB use 0 or 1 indexing?

In most programming languages, the first element of an array is element 0. In MATLAB, indexes start at 1.

What is indexing in MATLAB?

Indexing into a matrix is a means of selecting a subset of elements from the matrix. MATLAB® has several indexing styles that are not only powerful and flexible, but also readable and expressive. Indexing is a key to the effectiveness of MATLAB at capturing matrix-oriented ideas in understandable computer programs.


2 Answers

use cumsum!

>> szM = size(M1);
>> M1( sub2ind( szM, Y1, 1:szM(2) ) ) = 1
M1 =
 1     0     0     1
 0     1     1     0
 0     0     0     0
 0     0     0     0
 0     0     0     0
 0     0     0     0
>> M1( sub2ind( szM, Y2+1, 1:szM(2) ) ) = -1
M1 =
 1     0     0     1
 0     1     1     0
 0     0     0     0
-1     0     0    -1
 0    -1     0     0
 0     0    -1     0
>> M = cumsum(M,1)
M =
 1     0     0     1
 1     1     1     1
 1     1     1     1
 0     1     1     0
 0     0     1     0
 0     0     0     0

A pitfall: If any of Y2 equals 6 than setting Y2+1 to -1 will exceed matrix dimension.
To fix this you can add two lines before setting to -1 the elements of M:

>> cols = 1:szM(2);
>> sel = Y2 < szM(1);
>> M1( sub2ind( szM, Y2(sel)+1, cols(sel) ) ) = -1

A spin-off for Pavan Yalamanchili's answer using bsxfun: (hover to see:)

using bsxfun without offsets:
M1 = bsxfun( @ge, (1:size(M1,1))', Y1 ) & bsxfun( @le, (1:size(M1,1))', Y2 );

like image 124
Shai Avatar answered Nov 02 '22 22:11

Shai


There may be other techniques, but this uses element wise operations which are insanely parallel.

A very simple solution. Thanks @Shai

>> [rows, cols] = size(M);
>> Y1=[1 2 2 1]; Y2=[3 4 5 3]; 
>> M = bsxfun(@ge, (1:rows)', Y1) & bsxfun(@le, (1:rows)', Y2)
M =
     1     0     0     1
     1     1     1     1
     1     1     1     1
     0     1     1     0
     0     0     1     0
     0     0     0     0

Unnecessarily complicated code

[rows, cols] = size(M);
offsets = ((1 : cols) - 1) * rows
Y1 = offsets + Y1;
Y2 = offsets + Y2;

M = reshape(1:numel(M), rows, cols);
M = bsxfun(@ge, M, Y1) & bsxfun(@le, M, Y2);
like image 26
Pavan Yalamanchili Avatar answered Nov 03 '22 00:11

Pavan Yalamanchili