How to find minimum value in a particular row in Matlab? - matlab

I have a matrix that looks like this:
M = [2 3 4; 2 4 6; 1 5 3]
How do I find the minimum value in each row? For example, I would first want to find the minimum value of the first row? Thanks!

Use min
>> M = [2 3 4; 2 4 6; 1 5 3];
>> X=min(M')
X =
2 2 1 % row-wise
OR
>> [E,I] = min(M,[],2) ; % E- Elements, I- Index

You also can try
M = min(A(n,:)); %where n is the row you want to look at

Related

Median of the row of an array Matlab

I'm looking to find the median of just a specific row of an m x n array. I couldn't find anything useful in the Matlab help section. E.g. if I had a small array
[1 2 4; 2 3 4; 6 2 8]
how would I find the median of row 2? Many thanks.
Search for median in google or matlab (doc median) and you will find the median function.
If you want to find the median of row 2, just use row,column indexing syntax, where : means all entries:
A = [1 2 4; 2 3 4; 6 2 8];
median(A(2,:))
You could try to use:
A = [1 2 4; 2 3 4; 6 2 8];
medianRows = median(A, 2); % to find every rows' median
medianRows(2)
Or:
medianRow2 = median(A(2, :)); % every column of 2nd row

shifting versions of a matrix

I have a m-by-n matrix and I want to shift each row elements k no. of times (" one resultant matrix for each one shift so a total of k matrices corresponding to each row shifts ")(k can be different for different rows and 0<=k<=n) and want to index all the resultant matrices corresponding to each individual shift.
Eg: I have the matrix: [1 2 3 4; 5 6 7 8; 2 3 4 5]. Now, say, I want to shift row1 by 2 times (i.e. k=2 for row1) and row2 by 3times (i.e. k=3 for row2) and want to index all the shifted versions of matrices (It is similar to combinatorics of rows but with limited and diffeent no. of shifts to each row).
Can someone help to write up the code? (please help to write the general code but not for the example I mentioned here)
I found the following question useful to some extent, but it won't solve my problem as my problem looks like a special case of this problem:
Matlab: How to get all the possible different matrices by shifting it's rows (Update: each row has a different step)
See if this works for you -
%// Input m-by-n matrix
A = rand(2,5) %// Edit this to your data
%// Initialize shifts, k for each row. The number of elements would be m.
sr = [2 3]; %// Edit this to your data
[m,n] = size(A); %// Get size
%// Get all the shits in one go
sr_ind = arrayfun(#(x) 0:x,sr,'un',0); %//'
shifts = allcomb(sr_ind{:},'matlab')'; %//'
for k1 = 1:size(shifts,2)
%// Get shift to be used for each row for each iteration
shift1 = shifts(:,k1);
%// Get circularly shifted column indices
t2 = mod(bsxfun(#minus,1:n,shift1),n);
t2(t2==0) = n;
%// Get the linear indices and use them to index into input to get the output
ind = bsxfun(#plus,[1:m]',(t2-1)*m); %//'
all_matrices = A(ind) %// outputs
end
Please note that this code uses MATLAB file-exchange code allcomb.
If your problem in reality is not more complex than what you showed us, it can be done by a double loop. However, i don't like my solution, because you would need another nested loop for each row you want to shift. Also it generates all shift-combinations from your given k-numbers, so it has alot of overhead. But this can be a start:
% input
m = [1 2 3 4; 5 6 7 8; 2 3 4 5];
shift_times = {0:2, 0:3}; % 2 times for row 1, 3 times for row 2
% desird results
desired_matrices{1} = [4 1 2 3; 5 6 7 8; 2 3 4 5];
desired_matrices{2} = [3 4 1 2; 5 6 7 8; 2 3 4 5];
desired_matrices{3} = [1 2 3 4; 8 5 6 7; 2 3 4 5];
desired_matrices{4} = [4 1 2 3; 8 5 6 7; 2 3 4 5];
desired_matrices{5} = [3 4 1 2; 8 5 6 7; 2 3 4 5];
% info needed:
[rows, cols] = size(m);
count = 0;
% make all shift combinations
for shift1 = shift_times{1}
% shift row 1
m_shifted = m;
idx_shifted = [circshift([1:cols]',shift1)]';
m_shifted(1, :) = m_shifted(1, idx_shifted);
for shift2 = shift_times{2}
% shift row 2
idx_shifted = [circshift([1:cols]',shift2)]';
m_shifted(2, :) = m_shifted(r_s, idx_shifted);
% store them
store{shift1+1, shift2+1} = m_shifted;
end
end
% store{i+1, j+1} stores row 1 shifted by i and row 2 shifted by j
% example
all(all(store{2,1} == desired_matrices{1})) % row1: 1, row2: 0
all(all(store{2,2} == desired_matrices{4})) % row1: 1, row2: 1
all(all(store{3,2} == desired_matrices{5})) % row1: 2, row2: 1

How to use find function for different value at each row of a matrix?

suppose I have values need_find = [1 3 4] and a matrix A in the size of 3xK. I want to find the values of need_find on its corresponding row of A. How can I apply vectorized solution in matlab instead of iterate over each row?
For detailed example as expected;
A = [1 3 4; 1 3 5; 3 4 5];
my_method_do_what_I_want(A,need_find);
The method returns
ans = [1;2;2]
% so I find the index of each element of need_find at corresponding row at A
Long story short :seach 1 at row 1, search 3 at row2, search 4 at row3
Here's one way:
A = [1 3 4; 1 3 5; 3 4 5];
need_find = [1 3 4]
[~,idx] = find(bsxfun(#eq,A,need_find(:)))
which returns
idx =
1
2
2
This simple one-liner won't work if you have repeated values in the rows of A or if there are no matches at all, but I can only go by your example...

average 3rd column when 1st and 2nd column have same numbers

just lets make it simple, assume that I have a 10x3 matrix in matlab. The numbers in the first two columns in each row represent the x and y (position) and the number in 3rd columns show the corresponding value. For instance, [1 4 12] shows that the value of function in x=1 and y=4 is equal to 12. I also have same x, and y in different rows, and I want to average the values with same x,y. and replace all of them with averaged one.
For example :
A = [1 4 12
1 4 14
1 4 10
1 5 5
1 5 7];
I want to have
B = [1 4 12
1 5 6]
I really appreciate your help
Thanks
Ali
Like this?
A = [1 4 12;1 4 14;1 4 10; 1 5 5;1 5 7];
[x,y] = consolidator(A(:,1:2),A(:,3),#mean);
B = [x,y]
B =
1 4 12
1 5 6
Consolidator is on the File Exchange.
Using built-in functions:
sparsemean = accumarray(A(:,1:2), A(:,3).', [], #mean, 0, true);
[i,j,v] = find(sparsemean);
B = [i.' j.' v.'];
A = [1 4 12;1 4 14;1 4 10; 1 5 5;1 5 7]; %your example data
B = unique(A(:, 1:2), 'rows'); %find the unique xy pairs
C = nan(length(B), 1);
% calculate means
for ii = 1:length(B)
C(ii) = mean(A(A(:, 1) == B(ii, 1) & A(:, 2) == B(ii, 2), 3));
end
C =
12
6
The step inside the for loop uses logical indexing to find the mean of rows that match the current xy pair in the loop.
Use unique to get the unique rows and use the returned indexing array to find the ones that should be averaged and ask accumarray to do the averaging part:
[C,~,J]=unique(A(:,1:2), 'rows');
B=[C, accumarray(J,A(:,3),[],#mean)];
For your example
>> [C,~,J]=unique(A(:,1:2), 'rows')
C =
1 4
1 5
J =
1
1
1
2
2
C contains the unique rows and J shows which rows in the original matrix correspond to the rows in C then
>> accumarray(J,A(:,3),[],#mean)
ans =
12
6
returns the desired averages and
>> B=[C, accumarray(J,A(:,3),[],#mean)]
B =
1 4 12
1 5 6
is the answer.

Randomly replace percentage of elements in matrix per existing values

is there a sensible way to replace x% of each value in matrix/vector with a new value, and have the the element(s) to be changed be selected randomly? That is, in A, if I wanted to change 20% of the values (1 element per existing value) to the value 5, how do I make sure that each of the 5 elements per existing value in A has an equal probability of changing to the new value (e.g. 5)? I would appreciate some guidance on a method to complete the task described above.
Thank you kindly.
% Example Matrix
% M = 5;
% N = 5;
% A = zeros(M, N);
A = [0 0 0 0 0;
1 1 1 1 1;
2 2 2 2 2;
3 3 3 3 3;
4 4 4 4 4];
% Example Matrix with 20% of elements per value replaced with the value '5'
A = [0 0 5 0 0;
1 5 1 1 1;
2 5 2 2 2;
3 3 3 3 5;
4 4 5 4 4];
Try using logical arrays and a random number generated, like this:
vals_to_change=rand(size(A,1),size(A,2))<p;
A(vals_to_change)=rand(sum(vals_to_change),1);
Using information from here and here I was able to achieve my objective. The code below will replace x% of each value in matrix with a new value and then randomize its location within that value in the matrix.
M = 5;
N = 5;
A = zeros(M, N);
PC = 20; % percent to change
nCells = round(100/PC); % # of cells to replace with new value
A = [0 0 0 0 0;
1 1 1 1 1;
2 2 2 2 2;
3 3 3 3 3;
4 4 4 4 4];
A2 = A+1; % Pad the cell values for calculations (bc of zero)
newvalue = 6;
a=hist(A2(:),5);% determine qty of each value
for i=1:5
% find 1st instance of each value and convert to newvalue
A2(find(A2==i,round(a(i)/nCells)))=newvalue;
end;
out = A2-1; % remove padding
[~,idx] = sort(rand(M,N),2); % convert column indices into linear indices
idx = (idx-1)*M + ndgrid(1:M,1:N); %rearrange each newvalue to be random
A = out;
A(:) = A(idx);