how to display my vertical matrix in an horizontal matrix? - matlab

In one file 'file.mat', I have a matrix which its size is (1,100), it is written vertically like this:
M1 =
Columns 1 through 26:
6 13 3 15 13 12 8 5 5 1 11 8 5 9 1 7 15 9 2 5 7 7 3 9 0 13
Columns 27 through 52:
4 5 7 2 6 6 2 7 12 5 5 12 0 6 11 15 1 2 12 9 13 9 7 13 2 2
Columns 53 through 78:
7 15 4 15 5 12 5 12 14 3 10 15 12 5 5 15 3 3 9 3 6 0 13 13 8 5
Columns 79 through 100:
2 10 0 8 5 5 9 8 13 14 15 14 10 6 7 8 9 10 14 5 2 5
How to change it in an horizontal Matrix?

You can use M1.' or permute(M1,[2 1]). If you want all numbers to be in one horizontal line (i.e. to be an vector) you can use reshape(M1, [1,100])

What you have is a horizontal vector, but MATLAB displays it like that so that you can easily see where each element belongs. I guess what you want is to display the vector as a horizontal vector, so that you can copy-paste it. If so:
You can use sprintf if you want to display this as a long vector.
sprintf('%i ', M)
ans =
35 3 31 8 30 4 1 32 9 28 5 36 6 7 2 33 34 29 26 21 22 17 12 13 19 23 27 10 14 18 24 25 20 15 16 11
Or if you need the brackets:
['[', sprintf('%i ', M), ']']
ans =
[35 3 31 8 30 4 1 32 9 28 5 36 6 7 2 33 34 29 26 21 22 17 12 13 19 23 27 10 14 18 24 25 20 15 16 11 ]
You can also have it tab-separated: sprintf('%i\t', M), or with commas: sprintf('%i,', M).
If you want to reshape your horizontal vector to a vertical, you can do:
M = M.';
Note that ' is NOT the transpose operator, .' is. If you have a vector, but don't know whether it's horizontal of vertical, use the following notation: M = M(:).', or reshape(M, 1, []).

Related

Extracting x rows every n rows from a table in matlab

I want to create a new table extracting x rows every n rows from my table. For example if my table is:
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22
I want something like:
1 2
3 4
11 12
13 14
21 22
Here is an easy way by using ismember and mod to categorize the rows
n = 5;
x = 2;
b = a(logical(ismember(mod(0:size(a)-1,n),0:x-1)),:);
such that
>> b
b =
1 2
3 4
11 12
13 14
21 22
Data
a = [1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
21 22];

Convert 2D into 3D using reshape subject to conditions

I want to use reshape.
v=[1:20 ;2:2:40 ;3:3:60 ;4:4:80];
Using reshape(v,4,4,5) gives output:
ans(:,:,1) =
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
ans(:,:,2) =
17 2 10 18
18 4 12 20
19 6 14 22
20 8 16 24
And so on. But I desire
ans(:,:,1)=
1 2 3 4
2 4 6 8
3 6 9 12
4 8 12 16
ans(:,:,2)=
5 10 15 20
6 12 18 24
7 14 21 28
8 16 24 32
reshape(v',4,4,5) didn't work for me either
You are on the right track with the reshape function. You just need to transpose your 3D slices using permute. i.e.
permute(reshape(v,4,4,[]),[2 1 3])

How does imfilter 'replicate' in matlab work for bigger filters?

I am reading this:
https://uk.mathworks.com/help/images/imfilter-boundary-padding-options.html
And I am trying to understand how it will work for 5x5, or 7x7 kernels. Let's say in a 5x5 kernel you will have an extra row and column, on the top and right side of the kernel compared to the one in the image in the link. What value will that take ? Just the closest one it can find ? And how about diagonal values (the ones in the corners) ?
From the documentation for the 'replicate' option in imfilter,
Input array values outside the bounds of the array are assumed to equal the nearest array border value.
You can actually see the exact array that imfilter uses by calling padarray with the proper arguments. Say we have a 5x5 array:
im = reshape(1:25, 5, 5)
im =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
We can pad this array by 2 on each side (the equivalent of using a 5x5 kernel):
padarray(im, [2 2], 'replicate')
ans =
1 1 1 6 11 16 21 21 21
1 1 1 6 11 16 21 21 21
1 1 1 6 11 16 21 21 21
2 2 2 7 12 17 22 22 22
3 3 3 8 13 18 23 23 23
4 4 4 9 14 19 24 24 24
5 5 5 10 15 20 25 25 25
5 5 5 10 15 20 25 25 25
5 5 5 10 15 20 25 25 25
Spacing out the rows/columns so you can see the original array more easily:
1 1 1 6 11 16 21 21 21
1 1 1 6 11 16 21 21 21
1 1 1 6 11 16 21 21 21
2 2 2 7 12 17 22 22 22
3 3 3 8 13 18 23 23 23
4 4 4 9 14 19 24 24 24
5 5 5 10 15 20 25 25 25
5 5 5 10 15 20 25 25 25
5 5 5 10 15 20 25 25 25
You can also verify this by creating a kernel with a single 1 value in one of the corners:
im = reshape(1:25, 5, 5)
im =
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
k = zeros(5); k(1,1) = 1
k =
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
imfilter(im, k, 'replicate')
ans =
1 1 1 6 11
1 1 1 6 11
1 1 1 6 11
2 2 2 7 12
3 3 3 8 13
Naturally, this only shows the top-left 5x5 subarray of the 9x9 padded array, but by repeating the process with the 1 in different corners you can see the whole array.

Accumulate sliding blocks into a matrix

In MATLAB, we can use im2col and col2im to transform from columns to blocks and back, for example
>> A = floor(30*rand(4,6))
A =
8 5 2 13 15 11
22 11 27 13 24 24
5 18 23 9 23 15
20 23 14 15 19 10
>> B = im2col(A,[2 2],'distinct')
B =
8 5 2 23 15 23
22 20 27 14 24 19
5 18 13 9 11 15
11 23 13 15 24 10
>> col2im(B,[2 2],[4,6],'distinct')
ans =
8 5 2 13 15 11
22 11 27 13 24 24
5 18 23 9 23 15
20 23 14 15 19 10
my question is that: after using im2col with sliding mode
>> B = im2col(A,[2 2],'sliding')
B =
8 22 5 5 11 18 2 27 23 13 13 9 15 24 23
22 5 20 11 18 23 27 23 14 13 9 15 24 23 19
5 11 18 2 27 23 13 13 9 15 24 23 11 24 15
11 18 23 27 23 14 13 9 15 24 23 19 24 15 10
I wish to get a 4-by-6 matrix C from B(without knowing A) that the value at each site equals the original value multiple the times of sampling.
In other word, C(1,1)=A(1,1), C(1,2)=A(1,2)*2, C(2,2) = A(2,2)*4
Though we can easily implement with a for-loop, but the efficiency is critically low. So how to vectorize the implementation?
If I'm understanding correctly, you're desired output is
C = [ 8 10 4 26 30 11
44 44 108 52 96 48
10 72 92 36 92 30
20 46 28 30 38 10 ]
which I got by computing C = A.*S where
S = [ 1 2 2 2 2 1
2 4 4 4 4 2
2 4 4 4 4 2
1 2 2 2 2 1 ]_
The entries in S represent how many sliding blocks each entry is a member of.
I believe your question boils down to how to construct the matrix S.
Solution:
S = min(min(1:M,M:-1:1),x)'*min(min(1:N,N:-1:1),y)
C = A.*S
where A is size M-by-N, and your sliding block is size x-by-y.
Explanation:
In the given example, M=4, N=6, x=2, and y=2.
Notice the solution S can be written as the outer product of two vectors:
S = [1;2;2;1] * [1,2,2,2,2,1]
We construct each of these two vectors using the values of M,N,x,y:
min(1:M,M:-1:1)' == min(1:4,4:-1:1)'
== min([1,2,3,4], [4,3,2,1])'
== [1,2,2,1]'
== [1;2;2;1]
In this case, the extra min(...,x) does nothing since all entries are already <=x.
min(1:N,N:-1:1) == min(1:6,6:-1:1)
== min([1,2,3,4,5,6],[6,5,4,3,2,1])
== [1,2,3,3,2,1]
This time the extra min(...,y) does matter.
min(min(1:N,N:-1:1),y) == min([1,2,3,3,2,1],y)
== min([1,2,3,3,2,1],2)
== [1,2,2,2,2,1]

MATLAB:To create segments of numeric values continously ordered

A simple MATLAB-problem:
coordinates=[1 6 ;9 20];
coordinates =
1 6
9 20
What i now want to have is:
idxList=[1 2 3 4 5 6 9 10 11 12 13 14 15 16 17 18 19 20];
idxList =
1 2 3 4 5 6 9 10 11 12 13 14 15 16 17 18 19 20
How i have to make that?
Here's one way:
>> cell2mat(cellfun(#(x) x(1):x(2), num2cell(coordinates, 2), 'UniformOutput', 0)')
ans =
1 2 3 4 5 6 9 10 11 12 13 14 15 16 17 18 19 20