Checking values of two vectors against eachother and then using the column location of equal entries to extract colums from a matrix in matlab - matlab

I'm doing a curve fitting problem in Matlab and so far I've set up some orthonormal polynomials along a specified range of x-values with x = (0:0.0001:40);
The polynomials themselves are each a manipulation of that x vector and are stored as a row in a matrix. I also have some have data entries in the form of two vectors - one for the data x-coords and one for the actual values. I need a way to use the x-coords of my data points to find the same values in my continuous x-vector and then take the corresponding columns from my polynomial matrix and add them to a new matrix.
EDIT: To be more clear. I have, for example:
x = [0 1 2 3 4 5]
Polynomial =
1 1 1 1 1 1
0 1 2 3 4 5
0 1 4 9 16 25
% Data values:
x-coord = [1 3 4]
values = [5 3 8]
I want to check the x-coord values against 'x' to find the corresponding columns and then pull out those columns from the polynomial matrix to get:
Polynomial =
1 1 1
1 3 4
1 9 16

If your x, Polynomial, and xcoord are the same length you could use logical indexing which is elegant; something along the lines of Polynomial(x==xcoord). But since this doesn't seem to be the case, there's a less fancy solution with a for-loop and find(xcoord(i)==x)

Related

Find two MAXIMUM values' position in 3D matrix (MATLAB)

I have been having problem with identifying two maximum values' position in 3D matrix (MATLAB). Say I have matrix A output as follows:
A(:,:,1) =
5 3 5
0 1 0
A(:,:,2) =
0 2 0
8 0 8
A(:,:,3) =
3 0 0
0 7 7
A(:,:,4) =
6 6 0
4 0 0
For the first A(:,:,1), I want to identify that the first row have the highest value (A=5). But I need the two index position, which in this case, 1 and 3. And this is the same as the other A(:,:,:).
I have searched through SO but since I am bad in MATLAB, I couldn't find way to work this through.
Please do help me on this. It would be better if I don't need to use for loop to get the desired output.
Shot #1 Finding the indices for maximum values across each 3D slice -
%// Reshape A into a 2D matrix
A_2d = reshape(A,[],size(A,3))
%// Find linear indices of maximum numbers for each 3D slice
idx = find(reshape(bsxfun(#eq,A_2d,max(A_2d,[],1)),size(A)))
%// Convert those linear indices to dim1, dim2,dim3 indices and
%// present the final output as a Nx3 array
[dim1_idx,dim2_idx,dim3_idx] = ind2sub(size(A),idx)
out_idx_triplet = [dim1_idx dim2_idx dim3_idx]
Sample run -
>> A
A(:,:,1) =
5 3 5
0 1 0
A(:,:,2) =
0 2 0
8 0 8
A(:,:,3) =
3 0 0
0 7 7
A(:,:,4) =
6 6 0
4 0 0
out_idx_triplet =
1 1 1
1 3 1
2 1 2
2 3 2
2 2 3
2 3 3
1 1 4
1 2 4
out_idx_triplet(:,2) is what you are looking for!
Shot #2 Finding the indices for highest two numbers across each 3D slice -
%// Get size of A
[m,n,r] = size(A)
%// Reshape A into a 2D matrix
A_2d = reshape(A,[],r)
%// Find linear indices of highest two numbers for each 3D slice
[~,sorted_idx] = sort(A_2d,1,'descend')
idx = bsxfun(#plus,sorted_idx(1:2,:),[0:r-1]*m*n)
%// Convert those linear indices to dim1, dim2,dim3 indices
[dim1_idx,dim2_idx,dim3_idx] = ind2sub(size(A),idx(:))
%// Present the final output as a Nx3 array
out_idx_triplet = [dim1_idx dim2_idx dim3_idx]
out_idx_triplet(:,2) is what you are looking for!
The following code gives you the column and row of the respective maximum.
The first step will obtain the maximum of each sub-matrix containing the first and second dimension. Since max works per default with the first dimension, the matrix is reshaped to combine the original first and second dimension.
max_vals = max(reshape(A,size(A,1)*size(A,2),size(A,3)));
max_vals =
5 8 7 6
In the second step, the index of elements equal to the respective max_vals of each sub-matrix is obtained using arrayfun over the third dimension. Since the output of arrayfun are cells, cell2mat is used to transform the output into a matrix. As a last step, the linear index from find is transformed into sub-indices by ind2sub.
[i,j] = ind2sub(size(A(:,:,1)),cell2mat(arrayfun(#(i)find(A(:,:,i)==max_vals(i)),1:size(A,3),'UniformOutput',false)))
i =
1 2 2 1
1 2 2 1
j =
1 1 2 1
3 3 3 2
Hence, the values in j are the ones you want to have.

matlab: how to compare two matrices to get the indeces of the elements that differs from one to another

I'm using Matlab with very big multidimensional similar matrices and I'd like to find the differences of between them.
The two matrices have the same size.
Here is an example:
A(:,:,1) =
1 1 1
1 1 1
1 1 1
A(:,:,2) =
1 1 1
1 1 1
1 1 1
A(:,:,3) =
1 1 1
1 1 1
1 1 1
B(:,:,1) =
1 1 99
1 1 99
1 1 1
B(:,:,2) =
1 1 1
1 1 1
1 1 1
B(:,:,3) =
1 1 99
1 1 1
1 1 1
I need a function that give me the indeces of the values that differs, in this example this would be :
output =
1 3 1
1 3 3
2 3 1
I know that I can use functions like find(B~=A) or find(~ismember(B, A)) I don't know how to change their output to the indeces I want.
Thank you all!
You almost have it correct! Remember that find finds column major indices of where in your matrix (or vector) the Boolean condition you want to check for is being satisfied. If you want the actual row/column/slice locations, you need to use ind2sub. You would call it this way:
%// To reproduce your problem
A = ones(3,3,3);
B = ones(3,3,3);
B(7:8) = 99;
B(25) = 99;
%// This is what you call
[row,col,dim] = ind2sub(size(A), find(A ~= B));
The first parameter to ind2sub is the matrix size of where you're searching. Since the dimensions of A are equal to B, we can choose either A or B for the first input, and we use size to help us determine the size of the matrix. The second input are the column major indices that we want to access the matrix. These are simply the result of find.
row, col, and dim will give you the rows, columns and slices of which elements in your 3D matrix were not equal. Also note that these will be column vectors, as the output of find will produce a column vector of column-major indices. As such, we can concatenate each of the column vectors into a single matrix and display your information. Therefore:
locations = [row col dim];
disp(locations);
1 3 1
2 3 1
1 3 3
As such, the first column of this matrix tells you the row locations of where the matrix values are unequal, the second column of this matrix tells you the column locations of where the matrix values are unequal, and finally the third column tells you the slices of where the matrix values are unequal. Therefore, we have three points in this matrix that are unequal, which are located at (1,3,1), (2,3,1) and (1,3,3) respectively. Note that this is unsorted due to the nature of find as it searches amongst the columns of your matrix first. If you want to have this sorted like you have in your example output, use sortrows. If we do this, we get:
sortrows(locations)
ans =
1 3 1
1 3 3
2 3 1

Find the indices of a specific element in a 2D matrix

I want to find a specific value's indices in a 2D matrix. For example there is a matrix such as:
A =
0 0 8 8 1
0 6 7 1 1
5 1 1 1 1
Here, I want to get the indices of "0". So, there should be an array like:
indices = [(1,1) (1,2) (2,1)]
How can I do that? I tried to use find() function but it just returns one coordinate. However, I want to get all coordinates of "0".
You need to use two outputs for find:
[row,col] = find(A==0)
The single output you got was the linear index. This is the element number by counting down the columns e.g. for your matrix these are the linear indices:
1 4 7 10
2 5 8 11
3 6 9 12
which you could also use to locate an element in a matrix (so for your example the zeros are at linear index 1, 2 and 4). But what you're asking for is the subscript index, for that you need to provide find with 2 output variables.
but if you want to get a matrix exactly like your indices you need to concatenate my row and col matrices:
indices = [row, col]

In a 100 X 2 matrix, how do divide each element in column 2 by a constant?

I have a 100 by 2 matrix. And I'm trying to figure out how to divide all terms in the second column by a constant.
For example, let's say I have this matrix.
[1 2;
3 4;
5 6]
I want to divide the 2nd column by 2.
[1 2/2;
3 4/2;
5 6/2]
So my final matrix will be.
[1 1;
3 2;
5 3]
Thank you.
If your matrix is M then:
M(:,2)=M(:,2)./2;
will divide all terms in the second column by a constant (2). By the way, because the value you divide with is a constant you can also write / instead of ./
If you'd like to assemble a new matrix and not overwrite the first one just write something like this:
A=[M(:,1) M(:,2)./2]
I'm not sure how natan 's equations should be read, but I'd multiply the first matrix
1 2
3 4
5 6
by the matrix
1 0
0 .5
The resulting matrix is
1 1
3 2
5 3

How to combine vectors of different length in a cell array into matrix in MATLAB

How to efficiently combined cell array vectors with different length into a matrix, filling the vectors to max length with 0s or NaNs? It would be a nice option for cell2mat().
For example, if I have
C = {1:3; 1:5; 1:4};
I'd like to get either
M = [1 2 3 0 0
1 2 3 4 5
1 2 3 4 0];
or
M = [1 2 3 NaN NaN
1 2 3 4 5
1 2 3 4 NaN];
EDIT:
For a cell of row vectors as in your case, this will pad vectors with zeros to form a matrix
out=cell2mat(cellfun(#(x)cat(2,x,zeros(1,maxLength-length(x))),C,'UniformOutput',false))
out =
1 2 3 0 0
1 2 3 4 5
1 2 3 4 0
A similar question was asked earlier today, and although the question was worded slightly differently, my answer basically does what you want.
Copying the relevant parts here, a cell of uneven column vectors can be zero padded into a matrix as:
out=cell2mat(cellfun(#(x)cat(1,x,zeros(maxLength-length(x),1)),C,'UniformOutput',false));
where maxLength is assumed to be known. In your case, you have row vectors, which is just a slight modification from this.
If maxLength is not known, you can get it as
maxLength=max(cellfun(#(x)numel(x),C));