Matlab, select "line" range from matrix, not "square" [duplicate] - matlab

Say I have a matrix
A = [1, 2, 3; 4 5 6; 7 8 9]
If I want to choose say (1,2), (2,3)
I could not say A(1:2,2:3) otherwise it will return a 2*2 matrix, what should I do it for only one time...

Use sub2ind to linearly index (to avoid creating a matrix) using the given row and column numbers -
ind = [1,2;2,3]
A(sub2ind(size(A),ind(:,1),ind(:,2)))

Related

Matlab- How to find the neighbouring elements of a number in a matrix?

For example, if i have a matrix:
A=[1 2 3 4; 5 6 7 8; 9 10 11 12]
and if i select number 6, then it should return a matrix:
B=[1 2 3; 5 6 7; 9 10 11]
Implementing gutzcha's answer as a function with a bit more flexibility:
function mat_out = surround(mat_in, number, dis)
%mat_in: input matrix containing number
%number: number around which to build the output matrix
%dis: distance around searched number to crop in_matrix
%If dis is such that you would need to access values outside
%matrix, you will end up getting a non square matrix.
%find first position containing number in matrix:
[i, j] = find(mat_in==number, 1);
[len_row, len_col] = size(mat_in);
%make sure that I'm not accessing elements outside matrix
col = max((j-dis), 1):min((j+dis), len_col);
row = max((i-dis), 1):min((i+dis), len_col);
mat_out = mat_in(row, col);
then to get what you need, you would do
B = surround(A, 6, 1)
to get the 3x3 matrix contained in A that has 6 in the center. With this implementation you can also get the 5x5 matrix (if A was bigger) with the same characteristic using the variable dis. To avoid collisions, I wrote it so that you will find the first occurrance of number, but you can modify it.
Note that if number is less than dis numbers away from the end of the matrix, like the number 2 in your A, you will get the biggest matrix possible:
C = surround(A, 2, 1);
you will have
C = [1, 2, 3; 5, 6, 7]
You could modify the code to pad with zeros or whatever you like, so that you get
C = [0, 0, 0; 1, 2, 3; 5, 6, 7]
Here you go:
A = [1 2 3 4; 5 6 7 8; 9 10 11 12];
num=6;
[i,j]=find(A==num);
[len_row,len_col]=size(A);
cols=(j-1):(j+1);
cols(cols<1)=[]; %to avoid trying to access values outside matrix
cols(cols>len_col); %to avoid trying to access values outside matrix
row=(i-1):(i+1);
row(row<1)=[]; %to avoid trying to access values outside matrix
row(row>len_row)=[]; %to avoid trying to access values outside matrix
new_mat=A(row,cols);

Append vector to 3d matrix in Matlab

I wish to append a row-vector (and later, also a column vector) to an existing x by y by z matrix. So basically "Add a new row (at the "bottom") for each z in the original 3d matrix. Consider the following short Matlab program
appendVector = [1 2 3 4 5]; % Small matrix for brevity. Actual matrices used are much larger.
origMatrix = ones(5,5,3);
appendMatrix = [origMatrix( ... ); appendVector];
My question is: How do I adress (using Matlab-style matrix adressing, not a "manual" C-like loop) origMatrix( ... ) in order to append the vector above? Feel free to also include a suggestion on how to do the same operation for a column-vector (I am thinking that the correct way to do the latter is to simply use the '-operator in Matlab).
A "row" in a 3D matrix is actually a multi-dimensional array.
size(origMatrix(1,:,:))
% 5 3
So to append a row, you would need to append a 5 x 3 array.
toAppend = rand(5, 3);
appendMatrix = cat(1, origMatrix, toAppend);
You could append just a 5 element vector and specify an index for the third dimension. In this case, the value for the "row" for all other indices in the third dimension would be filled with zeros.
appendVector = [1 2 3 4 5];
origMatrix = ones(5,5,3);
appendMatrix = origMatrix;
appendMatrix(end+1, :, 1) = appendVector;
If instead, you want to append the same vector along the third dimension, you could use repmat to turn your vector into a 1 x 5 x 3 array and then append that.
appendVector = repmat([1 2 3 4 5], 1, 1, size(origMatrix, 3));
appendMatrix = cat(1, origMatrix, appendVector);

find max and its column and row in 2D matrix

Suppose I have matrix like this:
a = [ 2 5 4 7; 1 2 5 8; 2 3 4 5; 4 3 1 5]
what is the function to return the maximum and its column and row's index ?
For example, in my case that function should return maximum is 8, and column index is 4, and row index is 2
You can do it by using max twice:
[m irows]=max(a)
[mm icol]=max(m)
irow=irows(icol)
a(irow,icol)
Another solution is to unroll a to be a vector with a(:), use max, which will give you a single index that you then need to convert to row and column. you can easily figure out how it works by printing b(:) with b=[1,3;2,4] for instance.
Following on from #yoh.lej, you can use ind2sub to convert the output from find into co-ordinates:
m = magic(5);
[y, i] = max(m(:));
[r, c] = ind2sub(size(m), i)

Choose multiple values from multiple rows and columns from matrix in matlab

Say I have a matrix
A = [1, 2, 3; 4 5 6; 7 8 9]
If I want to choose say (1,2), (2,3)
I could not say A(1:2,2:3) otherwise it will return a 2*2 matrix, what should I do it for only one time...
Use sub2ind to linearly index (to avoid creating a matrix) using the given row and column numbers -
ind = [1,2;2,3]
A(sub2ind(size(A),ind(:,1),ind(:,2)))

Mapping values of matrix in MATLAB

Assume I have a matrix called A.
The values of the matrix represent coordinates,
so row 2 and column 3 is the coordinate (2,3) in the 2D plan.
How can I map all the values of the matrix to different indices so that (0,0) would get the mapping value of 0 etc.?
(0,0) -> 0
(0,1) -> 1
(0,2) ->2
..
..
and so on.
Thanks.
Assuming that you are okay with the MATLAB indexing that starts with 1, this would work -
A1 = reshape([1:numel(A)],size(A,1),[])'
If you would like to start the mapping from 0, just subtract 1 -
A1 = reshape([1:numel(A)],size(A,1),[])' -1
"The sub2ind command determines the equivalent single index corresponding to a set of subscript values."
For example, if
i = sub2ind(size(A), 2, 3);
then
A(2,3) and A(i) refer to the same element in a matrix A.
In MATLAB you can index matrices linearly. Suppose you have the matrix:
a =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
Now, you can access the element in position (3,2) either using normal subscripts, or using the linear equivalent.
a(3,2)
ans = 7
a(7)
ans = 7
Assuming you have your indices as a list from 1 to numel(a) and don't really need a link between (3,2) and (7), this would be the simplest way to do it.
As you state, you want the element in position (0,0) to have index (0). Since MATLAB indexing starts at 1 you have two alternatives:
If you get a list (for instance from another program) where elements are listed from zero to (numel(a) - 1), such as ind = [0, 3, 6, 8], my suggestion is you simply do ind = ind + 1 (or ind_1 = ind + 1 if you don't want to overwrite the original vector.
Otherwise you can add one every time this way: x = a(ind + 1);.
However, if you really want a link between (3,2) and (7), I believe sub2ind is the way to go.