MATLAB: compare elements in arrays - arrays

suppose there are arrays A and B, both of which can have any arbitrary numbers and size. for example
A=[1 2 3]
B=[4 8 52 7 10]
i was wondering if there was any way to check if any of the elements in A are contained in B without using a loop? Once again, the numbers and size of the array will be arbitrary so i can't hard code it. Any help and input would be appreciated. Thanks!

You mean like this:
A=[1 2 3]; B=[4 8 52 7 10]
ismember(A,B)
ans =
0 0 0

Add to #NasserM.Abbasi: ismember will work regardless shapes and sizes, it is always element-wise. So if you have A=[1 2; 3 4] and B=[1 3; 4 2; 1 2],
then ismember will return :
ismember(A,B); % -> [1 1; 1 1] due to element-wise membership check
ismember(A,B, 'rows'); % -> [1 0] since it checks row-wise.
use ismember carefully according to the possible shapes in A and B.

Related

How to reset the 'lower triangle' of a 3 dimentional matrix

I need to reset the 'lower triangle' of a 3 dimentional matrix.
This means, that if the original matrix is:
C(:,:,1) = [1 2 3 ; 2 4 6 ; 3 6 9]
C(:,:,2) = [2 4 6 ; 4 8 12 ; 6 12 18]
C(:,:,3) = [3 6 9 ; 6 12 18 ; 9 18 27]
Then the resulting matrix should be:
C(:,:,1) = [1 2 3 ; 2 4 6 ; 3 6 9]
C(:,:,2) = [0 0 0 ; 4 8 12 ; 6 12 18]
C(:,:,3) = [0 0 0 ; 0 0 0 ; 9 18 27]
Any idea how such a thing csn be done?
(My original 3 dim matrix is large)
Thanks!
The built-in triu can't deal with this 3D array but you could do it in a simple loop.
for k = 2:size(C, 3)
C(1:k-1,:,k) = 0;
end
You can generate a 2D mask, permute its dimensions, and multiply with singleton expansion using bsxfun:
result = bsxfun(#times, C, permute((1:size(C,1)).'>=(1:size(C,2)), [1 3 2]));
Or, from version R2016b onwards, you can remove bsxfun thanks to automatic singleton expansion:
result = C .* permute((1:size(C,1)).'>=(1:size(C,2)), [1 3 2]);
Assuming you have a "square" 3-D matrix (i.e. NxNxN as you had it in your original post 3x3x3) you could also use reshaping and repmating:
Edit: since repmat is too slow, I swapped it for a bsxfun implementation.
[a,b,c] = size(C)
D = reshape(tril(ones(a)),[a,1,a]);
F = ones(1,size(E,1));
D = bsxfun(#times,D,F);
C(~D)=0;
I also did a quick comparison of the three proposed solutions. #LuisMendo's solution wouldn't work for me, there is a matrix dimension error in the >= comparison (sizes [1 N] and [N 1] are compared).
Between my and #Suever's solution, his is significantly faster:
Comparing the three methods with variable size Cs:
Suever's version (for loop):
Took 0.3529s to compute.
Took 0.0002s to compute size 3x3x3.
Took 0.0008s to compute size 10x10x10.
Took 0.0008s to compute size 50x50x50.
Took 0.0455s to compute size 250x250x250.
Took 0.3055s to compute size 500x500x500.
My version (reshape/repmat):
Took 0.9086s to compute.
Took 0.0522s to compute size 3x3x3.
Took 0.0042s to compute size 10x10x10.
Took 0.0017s to compute size 50x50x50.
Took 0.1060s to compute size 250x250x250.
Took 0.7445s to compute size 500x500x500.

MATLAB - Get every N elements in a vector

I have an array
a = [1 2 3 4 5 6 7 8]
I want to get every group of 4
so the result is as such
[1 2 3 4]
[5 6 7 8]
I do not know how many elements there will be but I know it is divisible by 4
so something like a(1:4) and a(5:8) wont work, I can use a loop, but is there a way to not use a loop?
For an unknown number of elements in a you can use reshape you just need to figure out how many rows you will have in the final matrix or (better for your case) the number of columns.
a = 1:4*10;
a2 = reshape(a, 4, []).';
If you went the rows routine you would do this.
a = 1:4*10;
a2 = reshape(a, [], numel(a) / 4).';
You just need to be sure that a has the proper number of elements. numel simply tells you the total element count.

Generate vectors from single values in Matlab

I have vector c:
c = [2 5 3];
I want to generate vectors with their lengths equal to each value in c in a consecutive order. So, I should obtain 3 vectors:
c1 = [1 2];
c2 = [3 4 5 6 7];
c3 = [8 9 10];
Next, I want to align these vectors in a 1x3 cell array:
out = {c1 c2 c3};
This may seem straightforward, but I can't figure how to do it automatically. Any ideas?
You could use mat2cell to accomplish this. We first create an array from 1 to sum(c) and then use mat2cell to group the array into pieces where each piece is the size of each element of c.
out = mat2cell(1:sum(c), 1, c);
This reduces the need for intermediate variables and gives you your cell array directly.
out{1} =
1 2
out{2} =
3 4 5 6 7
out{3} =
8 9 10

Trying to compare elements of on array with every element of another array in matlab

I'm using Matlab, and I'm trying to come up with a vectorized solution for comparing the elements of one array to every element of another array. Specifically I want to find the difference and see if this difference is below a certain threshold.
Ex: a = [1 5 10 15] and b=[12 13 14 15], threshold = 6
so the elements in a that would satisfy the threshold would be 10 and 15 since each value comes within 6 of any of the values in b while 1 and 5 do not. Currently I have a for loop going through the elements of a and subtracting an equivalently sized matrix from b (for 5 it would be a = [5 5 5 5]). This obviously takes a long time so I'm trying to find a vectorized solution. Additionally, the current format I have my data in is actually cells where each cell element has size [1 2], and I have been using the cellfun function to perform my subtraction. I'm not sure if this complicates the solution of each [1 2] block with the [1 2] block of the second cell. A vectorized solution response is fine, there is no need to do the threshold analysis. I just added it in for a little more background.
Thanks in advance,
Manwei Chan
Use bsxfun:
>> ind = any(abs(bsxfun(#minus,a(:).',b(:)))<threshold)
ind =
0 0 1 1
>> a(ind)
ans =
10 15

Merge arrays with unequal number of columns

I have around 100 1D arrays I'd like to merge to a matrix.
The arrays have 140 to 180 columns.
Is it possible to merge these 1 x (140-180) arrays to a matrix with a dimension of 100 (amount of arrays) x 180 ?
All the arrays contain numbers. I want to expand the 1x140 array to a 1x180 array by means of interpolation.
In a simplified form, it should be something like this:
A = [1 5 7 8 3]
B = [1 3 5]
result=
[1 5 7 8 3
1 2 3 4 5]
The array B (1x3) is expanded to an 1x5 matrix. And the values in between are interpolated.
Basically, I thought of using "vertcat" after all arrays are expanded by a same amount of columns.
Thanks in advance,
Koen
How about this?
array = {[1 5 7 8 3],[1 3 5]}; % example data
N = 5; % desired length (180 in your case)
aux = cellfun(#(v) interp1(linspace(0,1,length(v)),v,linspace(0,1,N)), array, 'uni', false);
result = cat(1,aux{:});
It uses linear interpolation. For your example, this gives
>> result
result =
1 5 7 8 3
1 2 3 4 5
Note that linear interpolation modifies all values of the vector except first and last, in general. For example, with N=5 the vector [1 3 4 5] would get interpolated to [1 2.5 3.5 4.25 5]. You could use other forms of interpolation by passing an extra argument to interp1, see help interp1.

Resources