Finding the max element in a column of a matrix excluding certain rows - matlab

Consider I have an nxn matrix. My goal is to find the max element of the first column, swap the row containing that largest element and the first row. Next, I want to find the max element of the second column, excluding the first row, then swap the row of this new max element and the second row. Again, finding the max element of the jth column excluding rows 1:j-1, then swapping the max element row with the jth row, up until the n-1th column (as during the nth column, I would only be able to choose from the nth row).
My current setup for this is as follows
for j = 1:n-1
[~,row]=max(A(j:n,j));
temp = A(row,:);
A(row,:)=A(j,:);
A(j,:)=temp;
...
While the switching function works well enough, [~, row]=max(A(j:n,j)) is able to, and consistently does for the matrix I'm specifically working on, output row 1 during the second iteration of j. My thought process behind this was that j:n represents the rows we want to check. Noting j=2, for its second iteration, I hoped this would search row 2-to-n; however, it seems to still check every row.
While this question has been asked before, the answer, I found, was this same line of code.

You are using [~,row]=max(A(j:n,j));. Let's say you are in iteration j=2. max will only consider the input from the 2nd row on. A return value of row=1 indicates a maximum in the second row of A. The first row you put into the function. The max function has no clue that you actually input something larger. You have to correct for this.
n=5
A=magic(n); %just some input data
for j = 1:n-1
[~,row]=max(A(j:n,j));
row=row+j-1;
temp = A(row,:);
A(row,:)=A(j,:);
A(j,:)=temp;
end
by the way, matlab can do row swapping without helper variable:
for j = 1:n-1
[~,row]=max(A(j:n,j));
row=row+j-1;
A([row,j],:)=A([j,row],:);
end

Related

Creating new rows in a matrix, where the elements of these rows have to be different from previous rows(same row cannot occur twice) Matlab

I'm trying to generate a 3x2 matrix. Each row is generated using randperm(3,2). This means each row is generated as a vector with 2 unique integers with values between 1 and 3.
The problem is that I want each new row to be different than all the previous. For example, if one row is [1 3] then no other row can be:
[1 3], nor
[3 1].
I tried checking the sum AND the multiplied value of each newly created row. (Using our example 1+3=4 and 1*3=3)
My idea is that the multiplied value and the sum value of each new generated row is compared to the multiplied value and sum value of every other row that comes before it. If any of these values are the same (which means we will get a repetition), we keep generating a new row using randperm(3,2) until a completely new row is obtained.
My code checks each each row before one at a time, and "forgets" every other row that it previously checked. It does not take into consideration ALL the previous rows, instead it only iterates back one step at a time. I tried using something like parents(i:-1:1) instead of parents(i-k,1) etc but couldn't make it work.
Question: How can I do this comparison?
parents=randperm(3,2);
for i=2:3
parents=[parents; randperm(3,2)]
for k=1:i-1
while prod(parents(i,:))==prod(parents(i-k,:)) && sum(parents(i,:))==sum(parents(i-k,:))
parents(i,:)=randperm(3,2)
end
end
i=i+1;
end
Download this function, then use it as follows:
% generate all the possible permutations
p = permn(1:3,2);
% generate a random permutation of the indices and take the first three
r = randperm(size(p,1));
idx = r(1:3);
% take three random rows from the possible permutations using the indices
result = p(idx,:);
This way:
you will never obtain a row identical to another one in your result matrix
you won't be forced to use a "shuffle until condition is met" approach
you have a reusable and flexible approach

Find the largest value of each row in Matlab and divide each number in that row by the number

I have a 133120x4 matrix in Matlab.
I would like to find the largest value in each row, and divide every element in that row by that particular value.
Do I need to use some sort of loop? For example: I find the amount of rows in that matrix (133120), and iterate the loop that amount of times, then I go row by row and use the max function to return the largest value in that row, and divide each element in that row by the returned value from max.
Or is there a quicker way of doing this?
Thanks
EDIT (for clarification):
lets call my 133120x4 matrix A. I want to divide every element in a row by the largest value in that row. Since max and element-division are vectorized, would the solution simply be:
A_normal = A / max(A)
resulting in a 133120x4 matrix, but within each row, the largest value would be 1.
Is this correct? EDIT: It is not correct, and am still trying to figure out solution. Help from the community is greatly appreciated
Compute the maximum with max, repeat the result N(=4) times so there is one per each element and then element wise division
!
newMat=mat./repmat(max(mat,[],2),[1 size(mat,2)]);]
or in R2016b or newer just
newMat=mat./max(mat,[],2);

How can i change indices of a matrix in Matlab?

My problem is i want to assign some numbers to indices of a matrix. For example if I remove first row and first column of a matrix, then in remaining matrix 3th row and 4 column would actually be 4th row and 5th column in the first place.
I can do it with Array1(Array2) , however my code will have many seperate recursions so it is frustrating to keep track of everything. So, is there an once and for all way to map original 1..n indices to remaining matrix even after I remove rows and columnsth
Thanks in advance
You can do something like this as per beaker's suggestion
originalMatrix = magic(4)
dimension = size(originalMatrix)
indexMatrix = zeros(dimension(1), dimension(2))
for i = 1:numel(indexMatrix)
indexMatrix(i) = i
end
and remove the required row and column from indexMatrix.

MATLAB Extracting Column Number

My goal is to create a random, 20 by 5 array of integers, sort them by increasing order from top to bottom and from left to right, and then calculate the mean in each of the resulting 20 rows. This gives me a 1 by 20 array of the means. I then have to find the column whose mean is closest to 0. Here is my code so far:
RandomArray= randi([-100 100],20,5);
NewArray=reshape(sort(RandomArray(:)),20,5);
MeanArray= mean(transpose(NewArray(:,:)))
X=min(abs(x-0))
How can I store the column number whose mean is closest to 0 into a variable? I'm only about a month into coding so this probably seems like a very simple problem. Thanks
You're almost there. All you need is a find:
RandomArray= randi([-100 100],20,5);
NewArray=reshape(sort(RandomArray(:)),20,5);
% MeanArray= mean(transpose(NewArray(:,:))) %// gives means per row, not column
ColNum = find(abs(mean(NewArray,1))==min(abs(mean(NewArray,1)))); %// gives you the column number of the minimum
MeanColumn = RandomArray(:,ColNum);
find will give you the index of the entry where abs(mean(NewArray)), i.e. the absolute values of the mean per column equals the minimum of that same array, thus the index where the mean of the column is closest to 0.
Note that you don't need your MeanArray, as it transposes (which can be done by NewArray.', and then gives the mean per column, i.e. your old rows. I chucked everything in the find statement.
As suggested in the comment by Matthias W. it's faster to use the second output of min directly instead of a find:
RandomArray= randi([-100 100],20,5);
NewArray=reshape(sort(RandomArray(:)),20,5);
% MeanArray= mean(transpose(NewArray(:,:))) %// gives means per row, not column
[~,ColNum] = min(abs(mean(NewArray,1)));
MeanColumn = RandomArray(:,ColNum);

Selecting cells in a table using for-loop

I need to obtain individual values from cells incrementally.
For example in a table called "T":
Can Matlab create a loop to yield the following?:
T(1,1)
T(1,2)
T(1,3)
T(1,4)
and so forth.
First of all the first parameter in MATLAB equals the row, the second the column. So following your picture you would want to extract a complete column. Then you have to loop over your first parameter and keep the 2nd constant.
So not sure if this is really what you want but:
for k = 1:size(T,1)
T(k,1)
end
would write all elements in column 1 row after row. This is because size(T,1) returns the No. of rows in your Table. So by looping over all rows you return one column. Easier with the same result would be:
T(:,1)
which would return the whole first column.
If you don't want them to be displayed but to use them as entries for another variable use:
new_T = T(:,1);
The ; makes sure that the command isn't displayed on the console. And the new_T would have all entries from column 1.
Another example:
new_T2 = T(1:500, 4);
This would result in the first 500 elements from column 4.
Hopefully this solves your question, if not please explain your question more detailed.