Finding elements in an array other than given indices - matlab

I want to find the elements in an array which are not the given index elements. For example, given an array A = [1 5 7 8], and index ind = [2 3], the operation should return elements [1 8].

Use a direct index vector:
B = A(setdiff(1:numel(A),ind));
Or throw away unneeded elements:
B = A;
B(ind) = [];
Or use logical indexing:
% either
B = A(~any(bsxfun(#eq,ind(:),1:numel(A)),1));
% or
B = A(all(bsxfun(#ne,ind(:),1:numel(A)),1));

Related

How to get all unique values in a cell array of matrices?

I want to get all unique values in A, where A is a cell array of matrices of different shapes and sizes:
A = {[], 1, [2 3], [4 5; 6 7]};
U = [];
for ii = 1: numel(A)
a = A{ii};
U = [U; a(:)];
end
U = unique(U);
That returns:
U =
1 2 3 4 5 6 7
If all elements in A where row vectors, I could use [A{:}] like:
U = unique([A{1:3}]);
That returns:
U =
1 2 3
But in my case it throws an exception:
Error using horzcat
Dimensions of matrices being concatenated are not
consistent.
So how can I avoid that for-loop?
You can use cellfun to reshape all elements in the cell.
U = unique(cell2mat(cellfun(#(x)reshape(x,1,numel(x)),A, 'UniformOutput', false)));
or avoiding the reshapewith
U = unique(cell2mat(cellfun(#(x)x(:).',A, 'UniformOutput', false)));
We can go this way:
A = {[], 1, [2 3], [2 0; 4 5; 6 7]};
AA = cellfun( #(x) unique(x(:)), A, 'UniformOutput' , false)
res = unique(cat(1, AA{:}))
First of all create unique array for each cell - it let us avoid converting all the cells to numeric just only unique values.
Lets convert cell array to one numeric array - cat(1, AA{:}) .
Find unique values through this resulting array.

Array from vector on the basis of a second array

I have a vector v. I need to form an array a containing elements specified according to another array b. Each row in a (let's denote it by r) should contain all elements from v, with starting and ending indices corresponding to the first and last elements given in the matching column in b. For instance:
A(1, :) = v(b(1, 1):b(2, 1));
A(2, :) = v(b(1, 2):b(2, 2));
A(3, :) = v(b(1, 3):b(2, 3));
and so on. Obviously b(2,:) = b(1,:) + constant.
Can I do this without a loop in MATLAB?
Try this:
N=8; P=3; M=5;
v = rand(N,1);
b = zeros(2,M);
b(1,:) = [1 2 4 5 6];
b(2,:) = b(1,:) + P - 1;
A = cell2mat(arrayfun(#(i0,i1) v(i0:i1),b(1,:),b(2,:),'UniformOutput',false))'
You can use linear indexing and bsxfun to directly access the elements:
A = v(bsxfun(#plus, b(1,:).', 0:b(2,1)-b(1,1)));

Selecting an element from a matrix in a cell

Good day,
I have got something similar as:
A = [1 2; 3 4];
B = [2 3; 4 5; 6 7];
C{1} = A;
C{2} = B;
clear A;
clear B;
Now I would like to select element (2,1) from matrix B, that is, element (2,1) from C{2}. However, matrix B itself does not exist any more.
One possibility is:
B = C{2};
B(2,1)
However, is there a more direct way to access elements from matrices which are stored in a cell?
Cells allow you to chain subscripts in the following manner
>> C{2}(2, 1)
ans =
4

Octave appending in a 2D cell array

I'm trying to append an element at the end of a 2D cell array row. My code is:
b = cell(5, 0)
b(1) = {b(1, :), 2} % Trying to append at the end of the first row
This gives me the error: error: A(I) = X: X must have the same size as I
I've also tried various other forms, such as:
b = cell(5, 0)
b(1, end+1) = 2 % Ok, inserts 2 at [1,1]
b(2, end+1) = 3 % No, inserts 3 at [2,2] instead of [2, 1]
It seems that you are confused with cell array indexing.
If you want to append elements at the end of a row in a matrix (in your case, a cell array), you must still make sure that all rows are of the same size after the assignment, otherwise you'll trigger an error about mismatching dimensions.
Instead of b(1) = {b(1, :), 2}, the following should work:
b(1, end + 1) = 2
Alternatively, if you want to append an entire column array of cells to b, use horizontal concatenation, for example:
b = [b, {2; 3; 4; 5; 6}];
This should append a single cell at the end of each row of b.
The reason the element gets inserted at [2, 2] and not [1, 1] is that by the time you try to insert the second element, the value denoted by end has increased from 0 to 1.
The following should do what you need:
>> b = cell(5, 0)
b =
Empty cell array: 5-by-0
>> b(1,1) = {2}
b =
[2]
[]
[]
[]
[]
>> b(2,1) = {3}
b =
[2]
[3]
[]
[]
[]
>>

How to get a linear array when indexing 3rd or higher dimensions in multidimensional arrays

Consider having the following multidimensional array:
A = [1 2;3 4];
B = [5 6;7 8];
C = cat(3, A, B);
Well it is like a cube, I want to slice the first row, slice the first column and that's it.
When I do:
C(1,1,:)
I get two separate answers:
C(1,1,1) = 1
C(1,1,2) = 5
And if I do
D = C(1,1,:)
I get D to be a multidimensional.
I want this
D = [1 5];
That's it, how to do this?
Use the squeeze() function to drop the extra dimensions:
>> squeeze(C(1,1,:))'
ans =
1 5