reducing matrices under certain conditions - Part 2 - - matlab

This question is more complex than my previous question because here V is a cell
M is a matrix 4x2000000 composed of several submatrix Ai such that Ai(1:3,j) is the same vector for j = 1,...,size(Ai,2). and Ai(4,j) are values between 1 and 100.
V = {V1,V2,...,Vn} (V1 or V2 or ...Vn)
V1,V2,... and Vn have different sizes.
my goal is to eliminate all sub-matrix Ai of M, if Ai(4,:) does not contain all the values of V1 or V2 or ...Vn.
The only initial data for this problem are M and V
I wanted to use a for loop with the answer of the question here, but I noticed that the calculation time increases with the size of V.
Example:
M = [1022 3001 4451 1022 1022 3001 1022 3001 3001 1022 1055 1055 1055 1055 1055 1055;
112 45 10 112 112 45 11 45 99 112 11 11 11 11 11 11;
500 11 55 500 500 11 88 11 1 500 45 45 45 45 45 45;
2 6 3 5 71 2 2 71 5 88 8 15 21 94 10 33]
A1 = [1022 1022 1022 1022;
112 112 112 112;
500 500 500 500;
2 5 71 88]
A2 = [3001 3001 3001;
45 45 45;
11 11 11;
6 2 71]
A3 = [4451;
10;
55;
3]
A4 = [1055 1055 1055 1055 1055 1055;
11 11 11 11 11 11;
45 45 45 45 45 45;
8 15 21 94 10 33]
A5 =[3001;
99;
1;
5]
if V = {[2 71],[3],[15 94 33 10]}
The expected output (order of columns is not important):
[1022 1022 1022 1022 3001 3001 3001 4451 1055 1055 1055 1055 1055 1055;
112 112 112 112 45 45 45 10 11 11 11 11 11 11;
500 500 500 500 11 11 11 55 45 45 45 45 45 45;
2 5 71 88 6 2 71 3 8 15 21 94 10 33]

See if this works for you -
%// ID columns of M based on the uniquenes of the first thre rows
[~,~,idx] = unique(M(1:3,:).','rows') %//'
%// Lengths of each V cell
lens = cellfun('length',V)
%// Setup ID array for use with ACCUMARRAY later on
id = zeros(1,sum(lens))
id(cumsum(lens(1:end-1))+1) = 1
id = cumsum(id)+1
%// Collect all cells of V as a 1D numeric array
Vn = [V{:}]
%// Counts of number of elements for each cell/groups of V
counts_V = histc(id,1:numel(V))
%// Function handle to detect for if the input would satisfy the crietria
%// of all its values belong to either V1 or V2 or ...Vn
func1 = #(x) any(counts_V == histc(id(ismember(Vn,x)),1:numel(V)))
%// For each ID in "idx", see if it satisfies the above mentioned criteria
matches = accumarray(idx(:),M(4,:)',[], func1 ) %//'
%// Use the "detections" for selecting the valid columns from M
out = M(:,ismember(idx,find(matches)))

Related

Using regress function on two dependent variables - Matlab

I having trying to run linear regression and plot the results on the below data.
x1 = [40 45 38 50 48 55 53 55 58 40 55 48 45 55 60 60 60 65 50 58];
x2 = [25 20 30 30 28 30 34 36 32 34 38 28 30 36 34 38 42 38 34 38];
y = [1 2 1 3 2 3 3 4 4 3 5 3 3 2 4 5 5 5 4 3];
I have attempted it with this code
X = [ones(size(x1)) x1 x2 (x1.*x2)];
b = regress(y, X);
scatter3(x1,x2,y,'filled')
I am getting this error
Error using regress
Y must be a vector and must have the same number of rows as X.
Both y and X have one row each so I am unsure how to go about this regression.
Any help is appreciated.

reducing matrices under certain conditions

M is a matrix 4x2000000 composed of several submatrix Ai such that Ai(1:3,j) is the same vector for j = 1,...,size(Ai,2). and Ai(4,j) are values between 1 and 100.
V = [2 15 21 43]
my goal is to eliminate all sub-matrix Ai of M, if Ai(4,:) does not contain all the values of V.
The only initial data for this problem are M and V
Example:
M = [1022 3001 4451 1022 1022 3001 1022 3001 3001 1022;
112 45 10 112 112 45 11 45 99 112;
500 11 55 500 500 11 88 11 1 500;
2 6 3 5 71 2 2 71 5 88]
A1 = [1022 1022 1022 1022;
112 112 112 112;
500 500 500 500;
2 5 71 88]
A2 = [3001 3001 3001;
45 45 45;
11 11 11;
6 2 71]
A3 = [4451;
10;
55;
3]
A4 = [1022;
11;
88;
2]
A5 =[3001;
99;
1;
5]
if V = [2 71]
The expected output (order of columns is not important):
[1022 1022 1022 1022 3001 3001 3001;
112 112 112 112 45 45 45;
500 500 500 500 11 11 11;
2 5 71 88 6 2 71]
One approach -
[~,~,idx] = unique(M(1:3,:)','rows') %//'
valid = ismember(M(4,:),V)
valid_idx = accumarray(idx(valid),M(4,valid).',[],#(x) ...
numel(unique(x)))>=numel(V) %//'
out = M(:,ismember(idx,find(valid_idx)))

Matlab: extract submatrix with selecting some values from the last line

20 4 4 74 20 20 74 85 85 85
A = 36 1 1 11 36 36 11 66 66 66
77 1 1 15 77 77 15 11 11 11
3 4 2 6 7 8 10 10 15 17
how from the matrix A, I can extract the submatrix whose fourth line (end line) contains only the values ​​[3 6 10]?
for a single value, I do:
B=A(:,A(4,:)==10)
but I do not know how to do this for several values.
Use ismember -
search_array = [3 6 10]
subA = A(:,ismember(A(end,:),search_array))
Or bsxfun -
subA = A(:,any(bsxfun(#eq,A(end,:),search_array(:)),1))

sum over a matrix with condition in matlab

assume I have a 10x10 matrix M
M=[64 36 50 87 22 45 37 23 68 88;
33 23 87 49 54 25 35 98 78 52;
12 54 76 43 24 87 54 98 45 34;
77 87 23 45 34 65 23 76 12 76;
12 34 55 44 76 98 93 23 54 67;
22 55 78 90 88 56 34 23 12 76;
99 23 67 89 34 23 12 87 45 23;
22 54 76 89 65 23 45 12 93 12;
44 56 23 88 67 14 15 67 34 12;
11 44 77 99 34 23 78 34 12 79];
I want to first find out the local maximum in the matrix
and then according to the maximum position do a sum over a 3x3 region over M
For the first step, the code I used is local_max=imregionalmax(M). to find out the local maximum position, but how can I go further to use this coordination to sum over a 3x3 matrix over M?
Thanks for the help.
You can calculate the sum for the whole matrix and then only keep the values that you're interested in. This should work:
local_max=imregionalmax(M)
sums = imfilter(M, ones(3));
local_max_sums = sums(local_max);
And if what you want is a matrix with non-zero entries where the local maxima are located:
local_max_sums = sums .* local_max;
You seem to be looking for the matrix subset functionality of Matlab.
Basically, for
M = [ 1 2 3 4 5 6;
4 5 6 7 8 9;
7 8 9 0 1 2;
0 1 2 3 4 5;
3 4 5 6 7 8;
6 7 8 9 0 1];
If you have a max at (3,3), you can use M(2:4, 2:4) to get
N = [ 5 6 7;
8 9 0;
1 2 3];
Summing that matrix is all that remains - as simple as
total = sum(N(:));
This is kind of brute force for Matlab, but I think it works.
bw = imregionalmax(M);
[x,y] = find(bw);
s = [];
for i = 1:length(x)
startX = x(i)-2;
if(startX < 1)
startX = 1;
end
endX = x(i)+2;
if endX > 10
endX = 10;
end
startY = y(i)-2;
if startY < 1
startY = 1;
end
endY = y(i)+2;
if endY > 10
endY = 10;
end
s(i) = sum2(M(startX:endX, startY:endY));
end

I am trying to extract the rows with the same x values from two different files in matlab, how can I do it?

To be more clear, what I want is to generate file3 from file1 but with the x values in file 2.
Example:
file 1:
x1=[1 2 3 4 5 6 7 8 9 10]'
y1=[11 22 33 44 55 66 77 88 99 00]'
file 2:
x2=[3 4 5 8 9]'
y2=[333 444 555 888 999]'
file 3:
x2=[3 4 5 8 9]'
y2=[33 44 55 88 99]'
Use ISMEMBER to find which values of x1 are in x2, and where they're located.
x1=[1 2 3 4 5 6 7 8 9 10]'
y1=[11 22 33 44 55 66 77 88 99 00]'
x2=[3 4 5 8 9]'
y2=[333 444 555 888 999]'
x3 = x2;
y3 = y1(ismember(x1,x2))
y3 =
33
44
55
88
99