This question already has answers here:
Sorting entire matrix according to one column in matlab
(2 answers)
Closed 4 years ago.
I'm trying to get the smallest value in the 2D array but keep the order of the 2D array, for example:
If I had the array
7 | 7
2 | 3
8 | 0
3 | 7
5 | 5
I want to order it so it displays
2 | 3
8 | 0
3 | 7
5 | 5
7 | 7
I've looked at mink and sortrows but none seem to give the output I need.
Any help with this would be much appreciated!
You can use circshift to change the order of the elements in the way you need. First find the index to the minimal element, then shift so that the element is at the top:
M = [7,7 % example data from OP
2,3
8,0
3,7
5,5];
[~,ind] = min(M(:,1));
M = circshift(M,1-ind,1);
For the updated question, you first need to identify the row that you want to be moved to the top of the matrix. Once you know this you can simply rearrange the matrix so that this row, and all that occur after it, are placed first.
A = [7 7
2 3
8 0
3 7
5 5]
[~,index] = min(A(:,1)); % Identify row which should occur first
A = A([index:end,1:(index-1)], :) % Rearrange rows
A =
2 3
8 0
3 7
5 5
7 7
Related
I am trying to smooth the temporal history of each pixel in my matrix- in other words, trying to smooth each pixel through both 'space' (mxn) and 'time'(third dimension). I am using the function movmean to create an average of each pixel in time of a 1000x1000x8 matrix.
I am currently using the following code to take an average, using a window size of 5, operating along the third dimension:
av_matrix = movmean(my_matrix,5,3)
This is creating an average as expected, but I'm wondering if the window is just operating in the mxn direction and not taking the average along the third dimension as well.
To compute a moving average along the n dimensions of an n-dimensional array (the "window" is an n-dimensional rectangle), the simplest way is to use convolution (see convn).
You need to be careful with edge effects, that is, when the convolution kernel (or n-dimensional window) partially slides out of the data. What movmean does is average over the actual data points only. To achieve that behaviour you can
compute the sum over the kernel via convolution with the 'same' option; and then
divide each entry by the number of actual data points from which it was computed. This number can also be obtaind via convolution, namely, applying the kernel to an array of ones.
So, all you need is:
my_matrix = randi(9,5,5,3); % example 3D array
sz = [3 3 2]; % 3D window size
av_matrix = convn(my_matrix, ones(sz), 'same') ... % step 1
./convn(ones(size(my_matrix)), ones(sz), 'same'); % step 2
Check:
The following examples use
>> my_matrix
my_matrix(:,:,1) =
6 8 2 1 8
4 6 7 9 8
4 5 1 4 3
5 5 8 7 9
3 6 6 4 9
my_matrix(:,:,2) =
8 8 5 3 6
8 9 6 9 1
9 5 6 2 2
1 7 4 1 2
5 4 7 4 9
my_matrix(:,:,3) =
6 5 8 6 6
1 6 8 6 1
5 5 1 6 7
1 1 2 9 8
1 2 6 1 2
With edge effects:
>> mean(mean(mean(my_matrix(1:2,1:2,1:2))))
ans =
7.125000000000000
>> av_matrix(1,1,1)
ans =
7.125000000000000
Without edge effects:
>> mean(mean(mean(my_matrix(1:3,1:3,1:2))))
ans =
5.944444444444445
>> av_matrix(2,2,1)
ans =
5.944444444444445
If I have an array
>> c = 1:10
c =
1 2 3 4 5 6 7 8 9 10
How do I reverse the last five elements, so that my new array is
c =
1 2 3 4 5 10 9 8 7 6
Thank you,
Need to use array merge and flip for subarray
A = 1:10
A = [A(1:5),fliplr(A(6:10))]
You can try the following code, it uses the increment index :
d = [c(1:5), c(10:-1:6)]
An array is given and it can be of four types :
increasing
decreasing
first increasing then decreasing
first decreasing then increasing
Without traversing the array we need to tell its type.
Example:
a. increasing. eg 1 2 3 4 5 6 7 8 9
b. decreasing. eg 9 8 7 6 5 4 3 2 1
c. incr-decr. eg 1 2 3 4 9 8 7 6 5
d. decr-inc. eg 9 8 7 6 1 2 3 4 5
First, for the third and fourth cases, there must be at least three array elements in order to have an increase followed by a decrease, or vice-versa.
Assuming three or more elements, you can answer the question by doing the following two checks:
compare the first and second element (Comparison 1)
compare the second to last and last element (Comparison 2)
Here is a table showing how the results of these two comparisons can be used to determine the array type:
Comparison 1 | Comparison 2 | Type
< | < | increasing
> | > | decreasing
< | > | increasing then decreasing
> | < | decreasing then increasing
This question already has answers here:
Octave / Matlab: Extend a vector making it repeat itself?
(3 answers)
Closed 6 years ago.
I'm trying to take:
a = [1 2 3]
and repeat it 5 times to get:
b = [1 2 3 1 2 3 1 2 3 1 2 3 1 2 3]
but when I try:
b = repmat(a, 5, 1)
instead I get:
b =
1 2 3
1 2 3
1 2 3
1 2 3
1 2 3
I could probably do it with a for loop but I'd like to do it correctly if possible. Any suggestions? Thanks in advance
Use the following code:
b = repmat(a,1,5)
The numbers '1' and '5' refer to the amount of rows and columns that you want to repeat the matrix a. The order is important.
This question already has an answer here:
MATLAB: Duplicate each element of a vector? [closed]
(1 answer)
Closed 8 years ago.
It's hard to explain so I will show an example of what I would like to do:
x = [1 2 3 4 5]
I would like the outcome to be:
x = [1 1 2 2 3 3 4 4 5 5]
Preferably without the use of a for loop, but either method would be appreciative.
Thanks.
You can also use the Kronecker tensor product (kron function) which is pretty neat:
x = kron(x,ones(1,2))
x =
1 1 2 2 3 3 4 4 5 5
If you want it sorted as you have here, you could do:
y = sort([x x]);
alternatively if the order matters:
y = reshape([x;x],[1,2*length(x)])