Why does this technique not work?
137 views (last 30 days)
Show older comments
Sadiq Akbar
on 1 Aug 2024 at 7:16
Commented: Torsten
on 2 Aug 2024 at 12:57
I have a mat file which has a row vector u and a matrix temp_gbo. The size of this matrix is 100 x 4. I want the following:
Each row of the matrix temp_gbo must have the same arrangment of elements as is in u.The mat file and the script "swapping" are attached but the script doesn't fulfill my requirement. How should I modify this code?
clear;clc
load 2F_and_1J_Noise0
temp_gbo
u
% Create an index mapping based on the ordering in u
[~, idx] = sort(u)
% Rearrange each row of temp_gbo to match the order in u
sorted_temp_gbo = arrayfun(@(i) temp_gbo(i, idx), 1:size(temp_gbo, 1), 'UniformOutput', false);
% Convert cell array back to matrix
sorted_temp_gbo = cell2mat(sorted_temp_gbo');
% Display results
disp('Rearranged temp_gbo:');
disp(sorted_temp_gbo);
0 Comments
Accepted Answer
Torsten
on 1 Aug 2024 at 10:30
Edited: Torsten
on 1 Aug 2024 at 11:01
I already gave you the code how to order a vector according to the ordering of "u". Why don't you use it ?
Your method is wrong. You get the order of the elements of u from the command
[~, idx] = sort(u)
as
[4 1 2 3]
Now if you order the elements of temp_gbo according to temp_gbo(i,idx), you put the element in column 4 in column 1, the element of column 1 in column 2, the element of column 2 in column 3 and the element of column 3 in column 4. But why should this reflect the ordering of u ? You don't use the ordering of the ith row of temp_gbo in any way.
6 Comments
Torsten
on 2 Aug 2024 at 12:37
Edited: Torsten
on 2 Aug 2024 at 12:39
So can you modify my "arrafun" so that it does the same as does yours.
I don't use "arrayfun", I use a loop. And I don't think that "arrayfun" is applicable in this corrected version of your code for the reason already mentionned.
load 2F_and_1J_Noise0;
u
temp_gbo
[~, iu] = sort(u);
sorted_temp_gbo = zeros(size(temp_gbo));
for i = 1:size(temp_gbo, 1)
[~,itemp(iu)] = sort(temp_gbo(i,:));
sorted_temp_gbo(i,:) = temp_gbo(i,itemp);
end
sorted_temp_gbo
More Answers (2)
Abhas
on 1 Aug 2024 at 7:52
Hi Sadiq,
To achieve the specified order based on the relative magnitudes within each row of "temp_gbo", you need to sort each row and then rearrange the elements according to the specified positions.
Here's the MATLAB code to perform the required steps:
clear; clc;
load 2F_and_1J_Noise0;
% Define the new order based on the relative magnitudes
new_order = [2, 3, 4, 1]; % 2nd lowest, 3rd lowest, 4th lowest, lowest
% Preallocate the sorted matrix
sorted_temp_gbo = zeros(size(temp_gbo));
% Rearrange each row of temp_gbo to match the specified order
for i = 1:size(temp_gbo, 1)
[~, sort_idx] = sort(temp_gbo(i, :)); % Get the indices of the sorted elements
sorted_temp_gbo(i, :) = temp_gbo(i, sort_idx(new_order)); % Rearrange according to new_order
end
% Display results
disp('Rearranged temp_gbo:');
disp(sorted_temp_gbo);
Output:
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1744556/image.png)
You may refer to the following MathWorks documentation link to have a better understanding on array indexing: https://www.mathworks.com/help/matlab/math/matrix-indexing.html
4 Comments
Abhas
on 1 Aug 2024 at 11:12
- Determine the new positions of each element in u after sorting, and use this order to rearrange the elements in each row of temp_gbo.
- The command you used only provides the order of the elements in u, but it does not specify how to rearrange the elements in temp_gbo accordingly. In my code it specifies the order in which the smallest, second smallest, third smallest and largest element should be placed at.
Steven Lord
on 1 Aug 2024 at 15:11
Setup
Let's generate a collection of possible rows.
u = randi(10, 6, 3);
Let's ensure that no row in u has the exact same values as another row, though perhaps in a different order.
s = sort(u, 2);
while height(unique(s, 'rows')) < height(u)
u = randi(10, 6, 3);
s = sort(u, 2);
end
u
Now create the matrix and reorder each row in A arbitrarily.
whichrow = randi(height(u), 8, 1);
A = u(whichrow, :);
for therow = 1:height(A)
A(therow, :) = A(therow, randperm(width(A)));
end
A
The algorithm
We can use ismember (or you may want to use ismembertol if your data is not integer valued) to determine which row in u was used to generate each shuffled row in A. First we sort the rows in u and A then we ask whether each row in Asorted is present in s (we know that it is, so I can ignore that output) and which row of s the corresponding row of Asorted is.
s = sort(u, 2);
Asorted = sort(A, 2);
[~, ind] = ismember(Asorted, s, 'rows');
Trust but verify
To check, does this match the contents of whichrow, which is the variable we used to construct A in the first place?
[ind, whichrow]
Looks good to me.
2 Comments
Torsten
on 2 Aug 2024 at 12:57
Since i remember the previous question @Sadiq Akbar asked, his aim is to find code for the following problem:
Given two vectors u and v of length n, find the ordered vector v_ordered of length n such that if u(i) is the j-th biggest element of u, then v_ordered(i) is the j-th biggest element of v for 1 <= i <= n.
See Also
Categories
Find more on Shifting and Sorting Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!