How can I find each max element of three matrices as new matrix? - matlab

Maybe the question is a little bit confused, I'll make an example below.
Let's say I have a 3 matrices a, b, c with same size.
a = [2, 5; 6, 9];
b = [3, 3; 8, 1];
c = [5, 5; 2, 7];
How can I get the new matrix max with each max element in all three matrices?
max = [5, 5; 8, 9]
I know I could create logical matrix like a>b and then do the math, calc it out, is there any other more efficient way to do it?

You can concatenate the matrices into one 2x2x3 matrix using
d=cat(3,a,b,c)
and then use max-function to get your desired output:
maxValues=max(d,[],3)
The 3rd input to max defines along which dimension of the first input you want to find the maximum value.

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);

Repeating rows of matrix in MATLAB

I have a question that is related to this post: "Cloning" row or column vectors. I tried to work around the answers posted there, yet failed to apply them to my problem.
In my case, I'd like to "clone" each row row of a matrix by converting a matrix like
A = [1,2; 3, 4; 5, 6]
into the matrix
B = [1, 2
1, 2
3, 4
3, 4
5, 6
5, 6]
by repeating each row of A a number of times.
So far, I was able to work with repmat for a single row like
A = [1, 2];
B = repmat(A, 2, 1)
>> B = [1, 2
1, 2]
I was trying to build a loop using that formula, in order to obtain the matrix wanted. The loop looked like
T = 3; N = 2;
for t = 1:T
for I = 1:N
B = repmat(C, 21, 1)
end
end
Has anyone an idea how to correctly write the loop, or a better way to do this?
kron
There are a few ways you can do this. The shortest way would be to use the kron function as suggested by Adiel in the comments.
A = [1,2; 3, 4; 5, 6];
B = kron(A, [1;1]);
Note that the number of elements in the ones vector controls how many times each row is duplicated. For n times, use kron(A, ones(n,1)).
kron calculates the kronecker tensor product, which is not necessarily a fast process, nor is it intuitive to understand, but it does give the right result!
reshape and repmat
A more understandable process might involve a combination of reshape and repmat. The aim is to reshape the matrix into a row vector, repeat it the desired number of times, then reshape it again to regain the two-column matrix.
B = reshape(repmat(reshape(A, 1, []), 2, 1), [], 2);
Note that the 2 within the repmat function controls how many times each row is duplicated. For n times, use reshape(repmat(reshape(A, 1, []), n, 1), [], 2).
Speed
A quick benchmark can be written:
% Setup, using a large A
A = rand(1e5, 2);
f = #() kron(A, [1;1]);
g = #() reshape(repmat(reshape(A, 1, []), 2, 1), [], 2);
% timing
timeit(f);
timeit(g);
Output:
kron option: 0.0016622 secs
repmat/reshape option: 0.0012831 secs
Extended benchmark over different sizes:
Summary:
the reshape option is quicker (~25%) for just duplicating the rows once each, so you should go for this option if you want to end up with 2 of each row for a large matrix.
the reshape option appears to have complexity O(n) for the number of row repetitions. kron has some initial overhead, but is much quicker when you want many repetitions and hardly slows down because of them! Go for the kron method if you are doing more than a few repetitions.

Matlab find the maximum and minimum value for each point of series of arrays (with negative values)

lets say that we have the next series of arrays:
A = [1, 2, -2, -24];
B = [1, 4, -7, -2];
C = [3, 1, -7, -14];
D = [11, 4, -7, -1];
E = [1, 2, -3, -4];
F = [5, 14, -17, -12];
I would like to create two arrays,
the first will be the maximum of each column for all arrays,
i.e.
Maxi = [11,14,-2 -1];
the second will be the minimum of each column for all arrays
i.e.
Mini= [1,1,-17 -24];
I am trying all day, using loops, with max, and abs but I cant make it work
in my problem have a matrix (100,200), so with the above example i am trying to easily approach the problem. The ultimate goal is to get a kinda fitting of the 100 y_lines of 200 x_points. The idea is to calculate two lines (i.e. max,min), that will be the "visual" boarders of all lines (maximum and minimum values for each x). The next step will be to calculate an array of the average of these two arrays, so in the end will be a line between all lines.
any help is more than welcome!
How about this?
Suppose you stack all the row vectors , namely A,B...,F as
arr=[A;B;C;D;E;F];% stack the vectors
And then use the max(), min() and mean() functions provided by Matlab. That is,
Maxi = max(arr); % Maxi is a row vector carrying the max of each column of arr
Mini = min(arr);
Meani = mean(arr);
You just have to stack them as shown above. But if you have 100s of row vectors, use a loop to stack them into array arr as shown above.

How to find all index pairs of unequal elements in vector (Matlab)

Lets say I have the following vector in Matlab:
V = [4, 5, 5, 7];
How can I list (in a n-by-2 matrix for example) all the index pairs corresponding to unequal elements in the vector. For example for this particular vector the index pairs would be:
index pairs (1, 2) and (1, 3) corresponding to element pair (4,5)
index pair (1, 4) corresponding to element pair (4,7)
index pairs (2, 4) and (3, 4) corresponding to element pair (5,7)
The reason I need this is because I have a cost-function which takes a vector such as V as input and produces a cost-value.
I want to see how does the random swapping of two differing elements in the vector affect the cost value (using this for steepest descent hill climbing).
The order of the index pairs doesn't also matter. For my purposes (1,2) is the same as (2,1).
For example if my cost-function was evalCost(), then I could have V = [4, 5, 5, 7] and
evalCost(V) = 14
whereas for W = [4, 7, 5, 5] the cost could be:
evalCost(W) = 10
How to get the list of "swapping" pair indexes in Matlab. Hope my question is clear =)
I don't understand the cost function part, but the first part is simple:
[a,b]=unique(V)
C = combnk(b,2)
C contains the indices, and V(C) the values:
C = combnk(b,2)
C =
1 2
1 4
2 4
V(C)
ans =
4 5
4 7
5 7
Use bsxfun and then the two-ouput version of find to get the pairs. triu is applied to the output of bsxfun to consider only one of the two possible orders.
[ii jj] = find(triu(bsxfun(#ne, V, V.')));
pairs = [ii jj];

MATLAB addressing different matrix elments with an index?

How can I create an index-matrix that specifies which elements of a matrix to address?
So for example I have a matrix A which is 80 by 50. I know that A(1:5,:) addresses only the first 5 elements, but what if I want to multiply A with another matrix which also changes the elements to be addressed? So I want to multiply B(1,:) with A(1:5,:), and B(2,:) with A(10:15,:) and so on. Is there a smart way to specify this index-matrix where the information (1:5; 10:15, etc.) is stored?
Yes you can certainly define indices into a matrix using another matrix. Here is a simple example using a cell array to store the index list:
X =[1,2,3,4,5,6]
Idx = { [1, 2, 3], [4, 5, 6] }
Y = X( Idx{1} ) .* X( {Idx{2} )
Y = [ 4, 10, 18]