MATLAB:To create segments of numeric values continously ordered - matlab

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

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 to display my vertical matrix in an horizontal matrix?

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, []).

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]

How to Store Matrix/Vector and values in Matlab

I am trying to store vectors. When I run the program in the loop I see all the values, but when referred outside the loop only the last vector is evaluated and stored (the one that ends with prime number 953, see below). Any calculations done with the PVX vector are done only with the last entry. I want PVX to do calculations with all the results not just the last entry. How can I store these results to do calculations with?
This is the code:
PV=[2 3 5 7 11 13 17 19 23 29];
for numba=2:n
if mod(numba,PV)~=0;
xp=numba;
PVX=[2 3 5 7 11 13 17 19 23 29 xp]
end
end
The first few results looks like this:
PVX: Prime Vectors (Result)
PVX =
2 3 5 7 11 13 17 19 23 29 31
PVX =
2 3 5 7 11 13 17 19 23 29 37
PVX =
2 3 5 7 11 13 17 19 23 29 41
PVX =
2 3 5 7 11 13 17 19 23 29 43
PVX = ...........................................................
PVX =
2 3 5 7 11 13 17 19 23 29 953
If you want to store all PVX values, use a different row for each:
PV = [2 3 5 7 11 13 17 19 23 29];
PVX = [];
for numba=2:n
if mod(numba,PV)~=0;
xp = numba;
PVX = [PVX; 2 3 5 7 11 13 17 19 23 29 xp];
end
end
Of course if would be better to initiallize the PVX matrix to the appropriate size, but the number of rows is hard to predict.
Alternatively, build the PVX without loops:
xp = setdiff(primes(n), primes(29)).'; %'// all primes > 29 and <= n
PVX = [ repmat([2 3 5 7 11 13 17 19 23 29], numel(xp), 1) xp ];
As an example, for n=100, either of the above approaches gives
PVX =
2 3 5 7 11 13 17 19 23 29 31
2 3 5 7 11 13 17 19 23 29 37
2 3 5 7 11 13 17 19 23 29 41
2 3 5 7 11 13 17 19 23 29 43
2 3 5 7 11 13 17 19 23 29 47
2 3 5 7 11 13 17 19 23 29 53
2 3 5 7 11 13 17 19 23 29 59
2 3 5 7 11 13 17 19 23 29 61
2 3 5 7 11 13 17 19 23 29 67
2 3 5 7 11 13 17 19 23 29 71
2 3 5 7 11 13 17 19 23 29 73
2 3 5 7 11 13 17 19 23 29 79
2 3 5 7 11 13 17 19 23 29 83
2 3 5 7 11 13 17 19 23 29 89
2 3 5 7 11 13 17 19 23 29 97
I'm assuming you were going for this:
PVX=[2 3 5 7 11 13 17 19 23 29];
for numba=2:n
if mod(numba,PVX)~=0;
xp=numba;
PVX(end+1) = xp;
%// Or alternatively PVX = [PVX, xp];
end
end
but if you could get an estimate of how large PVX will be in the end, you should pre-allocate the array first for a significant speed up.
So, looks like you need all prime till n
As Dan said use this :
PVX=[2 3 5 7 11 13 17 19 23 29 ];
for numba=2:n
if mod(numba,PVX)~=0
xp=numba;
PVX=[ PVX xp];
end
end
Or why not simply use primes function ?
PVX = primes( n ) ;