Indexing matrices with four indices in MATLAB - matlab

The usual way to index elements in a matrix (in MATLAB, at least) is to use two variables (i and j), so a general element matrix can be adressed by M_{i,j}. How can I do the same indexing in a matrix that has four indices, like M_{ij,kl}?
EDIT
The elements of a usual matrix A can be viewed as:
So a general element is extracted, in MATLAB, using A(n,m).
What I want to do is write a matrix that has elements that are indexed like this:
matrix2 http://bit.ly/1gHRZrR
Is there any way to do this without using cells/arrays, as pointed out in the comments of the question?

From your comment I assume you would like to extract elements with multiple (two) row and column indices. Given a matrix M = magic(5);, e.g.
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
you can indeed index M with multiple row and column indices as in M([3,4], [1,5]) which would yield a two by two matrix:
4 22
10 3

Related

Generate a matrix containing all possible numbers

I am trying to achieve multiple matrices that will cover the full set of numbers. For example say I want to generate 5 matrices of length 10 that cover all the numbers from 1-20.
So matrix one will contain half the numbers say
m1 = [1 2 3 4 5 6 7 8 9 10];
while matrix two contains
m2 = [11 12 13 14 15 16 17 18 19 20];
Although this satisfies my condition with only two matrices not 5, I preferably need to generate all matrices randomly. Other than randomly generating the matrices and checking all values are generated is there a more efficient way to do this?
You can do it like that:
>> l=[1:20,randi(20,1,30)];
>> vec=l(randperm(length(l)));
>> v=reshape(vec,5,10);
The first line generates an array of 50 numbers from 1 to 20. It guarantees that each such number appears at least once. The second line randomizes the order of the numbers. The third line reshapes the vector into an array of arrays (that is, a 2D matrix, where each row is one of the arrays).

reshape four dimensional matrix

I have some problems using reshape. I want to reshape a 4-dimensional matrix, and the fourth dimension has to become a column.
so if I have:
A(:,:,1,1) =
1 4
2 5
A(:,:,2,1) =
2 5
3 6
A(:,:,1,2) =
10 14
12 15
A(:,:,2,2) =
12 15
13 16
My reshape should be:
Columns 1 through 5
1 4 2 5 2
10 14 12 15 12
Columns 6 through 8
5 3 6
15 13 16
This should work:
reshape(permute(A,[1 4 2 3]),[2 8])
To understand this, you can go step by step. First do the following:
reshape(A,[2 8])
ans =
1 2 2 3 10 12 12 13
4 5 5 6 14 15 15 16
You observe that the columns of the reshaped matrix are taken by sliding across the second dimension in the original matrix. After second dimension is over, you slide over to third dimension and the re-iterate over second dimension (here first dimension is rows, second is column, so on...).
What you want to do is, iterate over 4th dimension (as if its a second dimension). You also want (4,14) after (1,10). You can see that corresponding elements vary across second dimension (but reshape is going to slide over third dimension, no matter what. So swap 2nd and 3rd dimensions).
Finally, you get, reshape(permute(A,[1 4 2 3]),[2 8]).
I have always had a hard time explaining permute to somebody. I hope I didn't confuse you more.
You're going to have to do a permutation first to put the dimensions in the appropriate order. Try this:
reshape(permute(A,[4,2,1,3]),[2,8])
or break it up into two separate permutations, one to switch dimensions 1 and 2 in the original array, then reshape to 8x2, then take the transpose:
reshape(permute(A,[2,1,3,4]),[8,2])'

How Matlab extract a subset of a bigger matrix by specifying the indices?

I have a matrix A
A =
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
i have another matrix to specify the indices
index =
1 2
3 4
Now, i have got third matrix C from A
C = A(index)
C =
1 6
11 16
Problem: I am unable to understand how come i have received such a matrixC. I mean, what is logi behind it?
The logic behind it is linear indexing: When you provide a single index, Matlab moves along columns first, then along rows, then along further dimensions (according to their order).
So in your case (4 x 5 matrix) the entries of A are being accessed in the following order (each number here represents order, not the value of the entry):
1 5 9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20
Once you get used to it, you'll see linear indexing is a very powerful tool.
As an example: to obtain the maximum value in A you could just use max(A(1:20)). This could be further simplified to max(A(1:end)) or max(A(:)). Note that "A(:)" is a common Matlab idiom, used to turn any array into a column vector; which is sometimes called linearizing the array.
See also ind2sub and sub2ind, which are used to convert from linear index to standard indices and vice versa.

Matlab general matrix indexing for accesing several rows

Edit for clarity:
I have two matrices, p.valor 2x1000 and p.clase 1x1000. p.valor consists of random numbers spanning from -6 to 6. p.clase contains, in order, 200 1:s, 200 2:s and 600 3:s. What I wan´t to do is
Print p.valor using a diferent color/prompt for each clase determined in p.clase, as in following figure.
I first wrote this, in order to find out which locations in p.valor represented where the 1,2 respective 3 where in p.clase
%identify the locations of all 1,2 respective 3 in p.clase
f1=find(p.clase==1);
f2=find(p.clase==2);
f3=find(p.clase==3);
%define vectors in p.valor representing the locations of 1,2,3 in p.clase
x1=p.valor(f1);
x2=p.valor(f2);
x3=p.valor(f3);
There is 200 ones (1) in p.valor, thus, is x1=(1:200). The problem is that each number one(1) (and, respectively 2 and 3) represents TWO elements in p.valor, since p.valor has 2 rows. So even though p.clase and thus x1 now only have one row, I need to include the elements in the same colums as all locations in f1.
So the different alternatives I have tried have not yet been succesfull. Examples:
plot(x1(:,1), x1(:,2),'ro')
hold on
plot(x2(:,1),x2(:,2),'k.')
hold on
plot(x3(:,1),x3(:,2),'b+')
and
y1=p.valor(201:400);
y2=p.valor(601:800);
y3=p.valor(1401:2000);
scatter(x1,y1,'k+')
hold on
scatter(x2,y1,'b.')
hold on
scatter(x3,y1,'ro')
and
y1=p.valor(201:400);
y2=p.valor(601:800);
y3=p.valor(1401:2000);
plot(x1,y1,'k+')
hold on
plot(x2,y2,'b.')
hold on
plot(x3,y3,'ro')
My figures have the axisies right, but the plotted values does not match the correct figure provided (see top of the question).
Ergo, my question is: how do I include tha values on the second row in p.valor in my plotted figure?
I hope this is clearer!
Values from both rows simultaneously can be accessed using this syntax:
X=p.value(:,findX)
In this case, resulting X matrix will be a matrix having 2 rows and length(findX) columns.
M = magic(5)
M =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
M2 = M(1:2, :)
M2 =
17 24 1 8 15
23 5 7 14 16
Matlab uses column major indexing. So to get to the next row, you actually just have to add 1. Adding 2 to an index on M2 here gets you to the next column, or adding 5 to an index on M
e.g. M2(3) is 24. To get to the next row you just add one i.e. M2(4) returns 5.To get to the next column add the number of rows so M2(2 + 2) gets you 1. If you add the number of columns like you suggested you just get gibberish.
So your method is very wrong. Freude's method is 100% correct, it's much easier to use subscript indexing than linear indexing for this. But I just wanted to explain why what you were trying doesn't work in Matlab. (aside from the fact that X=p.value(findX findX+1000) gives you a syntax error, I assume you meant X=p.value([findX findX+1000]))

Finding matching rows from original dataset in an slightly reduced version of itself

I have two datasets, the original have all the labels and description of each variable, but the second is a reduced version of this dataset, used for specifics experiments, but don't have any of the information about the variables, contained in the original. So, I'm trying to match both datasets.
My question here is how can I find if a row from the original dataset is present in the new dataset, if a slight data reduction have been performed in both matrix dimensions?
Being more specific, the original dataset is a 24481 x 117 matrix and the new one is a 24188 x 97 matrix. However, the problem here is that I have no information of which rows or columns were or were not included in the new dataset
what you can do is zero pad the matrix with less number of elements so that it matches the size of the original data. then use
find(A==B)
A and B are the matrices
Using intersect function worked for me. Since a data reduction have been performed in both dimensions, first I look for the intersection of the first two columns vectors in the matrices (assuming that at least the columns order have been preserved in the reduction).
>> M = magic(5)
M =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>> X = M([2,3,5], [1,2,4,5])
X =
23 5 14 16
4 6 20 22
11 18 2 9
>> [c,xi, mi]=intersect(X(:,1),M(:,1))
mi is the column index vector of all rows from the original matrix M present in the reduced matrix X.
Doing the same for the two first rows in the matrices gave me a row index vector for all columns selected from the original matrix M.
>> [c,xi, mi]=intersect(X(1,:),M(1,:))
This solution has a drawback is that when the first row or column of the original matrix was not selected in the new set, then there you go moving the index of the compared vector from the original matrix, luckily not too much ;).
>> [c,xi, mi]=intersect(X(1,:),M(2,:))