Can I do max filter on a sub_blocks with matlab - matlab

For example, I have a 4x4 matrix, I want to split the max into 2x2 sub_regions. and do max on the sub_region.
1, 2, 3, 4
5, 6, 7, 8
9, 10, 11, 12
13, 14, 15, 16
\|/
6, 6, 8, 8
6, 6, 8, 8
14, 14, 16, 16
14, 14, 16, 16

Does this suit your need?
(Assuming your data is in a matrix called M)
>> cellfun(#(x) max(x(:)), mat2cell(M, [2 2], [2 2]))
ans =
6 8
14 16
EDIT:
You could also include kron to achieve your desired output:
>> kron(cellfun(#(x) max(x(:)), mat2cell(M, [2 2], [2 2])), ones(2))
ans =
6 6 8 8
6 6 8 8
14 14 16 16
14 14 16 16

colfilt will get the job done:
>> M = 2; N = 2;
>> B = colfilt(A,[M N],'distinct',#(x)repmat(max(x),[M*N 1]))
B =
6 6 8 8
6 6 8 8
14 14 16 16
14 14 16 16
The key is to use the 'distinct' block type option. Test data: A = reshape(1:16,4,4).'.
You can also use blockproc if you prefer:
B = blockproc(A,[M N],#(b) repmat(max(b.data(:)),[M N]))
OR
B = kron(blockproc(A,[M N],#(b) max(b.data(:))),ones(M,N))
Note: Image Processing Toolbox required for both.

Related

how do I concatenate the results of a concatenated array?

I have two matrices (dfs):
A = [1 2 3 4
5 6 7 8
9 10 11 12]
and B = [1, 2, 3]
and I want matrix C to be repeating each row in A, B times. for example, first row, 1,2,3,4 needs to be repeated once, second row: 5,6,7,8 twice and last row three times:
C = [1 2 3 4
5 6 7 8
5 6 7 8
9 10 11 12
9 10 11 12
9 10 11 12]
my code
for i in range(0,2401):
g = pd.concat([df1.iloc[[i]]]*z[i], ignore_index=True)
partially does this, except only gives me the 3 times last row part, I need to concatenate each concatenation.
below gives me what I want but its not clean, i.e. indices are not ignored and messy.
result = []
for i in range(0,2401):
g = pd.concat([df1.iloc[[i]]]*z[i], ignore_index=True)
result.append(g)
If you write your matrices like:
A = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
B = [1, 2, 3]
C = []
You can iterate through B and add to C like:
for i in range(len(B)):
index = 0
while index < B[i]:
C.append(A[i])
index += 1
Which has an output:
[[1, 2, 3, 4],
[5, 6, 7, 8],
[5, 6, 7, 8],
[9, 10, 11, 12],
[9, 10, 11, 12],
[9, 10, 11, 12]]
I hope this helps!

Matlab: Cut Vector at missing values and create new vectors

I want to write a Matlab script.
In my example I have a vector A=[1 3 4 5 7 8 9 10 11 13 14 15 16 17 19 20 21]
Now I want to cut the vector automatically at the points where a number is missing(here the numbers 2, 6, 12, 18 are missing).
As a result I want to have the vectors [1] and [3 4 5] and [7 8 9 10 11] and [13 14 15 16 17] and [19 20 21]. So as you can see the new vectors have different lenghts.
I thought about using a for loop, but I am not sure how to write these new vectors.
Thank you for your help :)
One liner with diff, cumsum & accumarray -
out = accumarray(cumsum([0 ; diff(A(:))~=1])+1,A(:),[],#(x) {x})
Sample run -
>> A
A =
1 3 4 5 7 8 9 10 ...
11 13 14 15 16 17 19 20 21
>> celldisp(out)
out{1} =
1
out{2} =
3
4
5
out{3} =
7
8
9
10
11
out{4} =
13
14
15
16
17
out{5} =
19
20
21
This is one approach:
s = [find(diff(A(:).')>1) numel(A)]; %'// detect where consecutive difference exceeds 1
s = [s(1) diff(s)]; %// sizes of groups
result = mat2cell(A(:).', 1, s); %'// split into cells according to those sizes
In your example, this gives
>> celldisp(result)
result{1} =
1
result{2} =
3 4 5
result{3} =
7 8 9 10 11
result{4} =
13 14 15 16 17
result{5} =
19 20 21
Another approach (computes group sizes differently):
s = diff([0 sum(bsxfun(#lt, A(:), setdiff(1:max(A(:).'), A(:).')), 1) numel(A)]);
result = mat2cell(A(:).', 1, s);

Extract elements from matrix

How can I extract the elements: [1,2,5,6], [3,4,7,8], [9,10,13,14], [11,12,15,16] ?
A = [1, 2, 3, 4;
5, 6, 7, 8;
9, 10, 11, 12;
13, 14, 15, 16;];
I'm using octave.
Best regards, Chris.
If you need four matrices then use
out = mat2cell(A,[2 2], [2 2]);
If you need four vectors with values , then use
out = cellfun(#(x)(reshape(x,1,[])),mat2cell(A,[2 2], [2 2]),'UniformOutput',0);
output will be
out{:,:}
ans =
1 5 2 6
ans =
9 13 10 14
ans =
3 7 4 8
ans =
11 15 12 16
Thanks, to Joe Serrano ,If you need the value in each of the four vectors in same order use,
out = cellfun(#(x)(reshape(x',1,[])),mat2cell(A,[2 2], [2 2]),'UniformOutput',0);
output will be
out{:,:}
ans =
1 2 5 6
ans =
9 10 13 14
ans =
3 4 7 8
ans =
11 12 15 16

How can I generate the following Matrices in Matlab - fast method?

I have two input variables:
N=10;
M=4;
Using Matlab, I want to generate the following matrices - without using for loops, for any M and N:
%N = 1 2 3 4 5 6 7 8 9
Mat1 = [2, 3, 4, 5, 6, 7, 8, 9, 10; %M=1 -> Mat1(1, i) = N(i)+1
3, 6, 9, 12, 15, 18, 21, 27, 30; %M=2 -> Mat1(2, i) = N(i)+N(i)*2
4, 8, 12, 16, 20, 24, 28, 32, 36; %M=3 -> Mat1(2, i) = N(i)+N(i)*3
5, 10, 15, 20, 25, 30, 35, 40, 45] %M=4 -> Mat1(2, i) = N(i)+N(i)*4
%N = 1 2 3 4 5 6 7 8 9
Mat2 = [1, 2, 3, 4, 5, 6, 7, 8, 9; %M=1 -> Mat2(2, i) = N(i)
1, 4, 7, 10, 13, 16, 19, 25, 28; %M=2 -> Mat2(2, i) = N(i)+N(i)*2-2
1, 5, 9, 13, 17, 21, 25, 29, 33; %M=3 -> Mat2(2, i) = N(i)+N(i)*3-3
1, 6, 11, 16, 21, 26, 31, 36, 41] %M=4 -> Mat2(2, i) = N(i)+N(i)*4-4
General description:
% i=1:N
%Mat1(M, i) = N(i)+N(i)*M , if M>1
% N(i)+1 , if M=1
%Mat2(M, i) = N(i)+N(i)*M-M , if M>1
% N(i) , if M=1
I wrote a code with two for loops, but I would like to ask if there is any method to get these results, without using loops. I tried with bsxfun and arrayfun, but I did not manage to get the right result:
clear Mat1 Mat2
N=10;
M=9;
Mat1 = ones(M, N);
Mat2 = ones(M, N);
for i=1:M
for j=1:N
if i==1
Mat1(i, j) = j+1;
Mat2(i, j) = j;
elseif j ==1
Mat1(i, j) = j+j*i;
elseif i~=1 && j~=1
Mat1(i, j) = j+j*i;
Mat2(i, j) = j+j*i-i;
end
end
end
Thank you
My try:
N=10;
M=4;
mat1 = bsxfun(#(x,y) x*(y.*(y>1)+1)+(y==1), 1:N,(1:M)')
mat2 = bsxfun(#(x,y) x*(y.*(y>1)+1)-(y>1).*y, 1:N,(1:M)')
I think this might do what you are looking for:
First matrix:
Mat1 = (2:N+1)'*(1:N);
Mat1 = Mat1(1:M,:);
Mat1(1,:) = 2:N+1;
This gives (N=10, M=4):
Mat1 =
2 3 4 5 6 7 8 9 10 11
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
Second matrix:
tmp = (0:N-2)'*(1:N-1);
Mat2 = repmat((4:3:3*N),M-1,1) + tmp(1:M-1,:);
Mat2 = [ones(M,1), [2:N; Mat2]];
Which gives:
Mat2 =
1 2 3 4 5 6 7 8 9 10
1 4 7 10 13 16 19 22 25 28
1 5 9 13 17 21 25 29 33 37
1 6 11 16 21 26 31 36 41 46
It was a bit of a puzzle, as it is not all too clear what exactly are the rules to build these matrices. But if it is just these matrices you want, this should be a fast way to get them.
For all N and M these lines of code produce the same matrices as you code with for loops does.
Meanwhile I learned how to use bsxfun and repmat. I got a compact code for both Mat1 and Mat2 generators:
N=10;
M=4;
Mat1 = bsxfun(#times, (1:M)', (1:N)) +...
[ones(1, N) ; horzcat( ones(M-1,1) , repmat(2:N,M-1,1) ) ];
Mat2 = [ones(M,1), [(2:N); bsxfun(#plus, (2:M)',(2:N)) +...
horzcat( zeros(M-1,1), bsxfun(#times, (2:M)',(1:N-2)) ) ] ];
Mat1 =
2 3 4 5 6 7 8 9 10 11
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
Mat2 =
1 2 3 4 5 6 7 8 9 10
1 4 7 10 13 16 19 22 25 28
1 5 9 13 17 21 25 29 33 37
1 6 11 16 21 26 31 36 41 46
I haven't tried these for every test case so I am not sure if it's totally general. I think you should be able to investigate what I used to do this and arrive at a solution for the first matrix as well. I think you might have some typos in your sample matrices above, hopefully this will get you on the right track
M=4;
N=10;
Mat2=repmat([1:N],M,1);
Mat2(2:M,:)=Mat2(2:M,:)+bsxfun(#times, Mat2(2:M,:), [2:M]');
Mat2(2:M,:)=bsxfun(#minus, Mat2(2:M,:), [2:M]');
gives us:
Mat2 =
1 2 3 4 5 6 7 8 9 10
1 4 7 10 13 16 19 22 25 28
1 5 9 13 17 21 25 29 33 37
1 6 11 16 21 26 31 36 41 46
with M=5 and N=10
Mat2 =
1 2 3 4 5 6 7 8 9 10
1 4 7 10 13 16 19 22 25 28
1 5 9 13 17 21 25 29 33 37
1 6 11 16 21 26 31 36 41 46
1 7 13 19 25 31 37 43 49 55
and I think this is Mat1:
Mat1=repmat([1:N],M,1);
Mat1(2:M,:)=Mat1(2:M,:)+bsxfun(#times, Mat1(2:M,:), [2:M]');
Mat1(1,:)=Mat1(1,:)+1;
Mat1 =
2 3 4 5 6 7 8 9 10 11
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50

export Matrix with this format MATLAB

How to export any size matrix like
A=
1 2 3 4 5 6 ....9
3 6 7 8 9 9 ....4
...
6 7 7 4 4 5 ... 2
To a file that will contain that matrix where each value is separated by ',':
1, 2, 3, 4, 5, 6, ....,9
3, 6, 7, 8, 9, 9, ....,4
...
6, 7, 7, 4, 4, 5, ... ,2
Use DLMWRITE. Doing this:
>> A = [1 2 3 4; 5 6 7 8];
>> dlmwrite('file.csv', A);
writes a file with this:
1,2,3,4
5,6,7,8