Hello I'm trying to do the following:
This is my table :
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
and I have a matrix [25,1].
I want to do the following: if the values in first and last columns match the numbers in the matrix, change the value to "99".
So the output should be this:
99
2
3
4
99
99
7
8
9
99
99
12
13
14
99
99
17
18
19
99
99
22
23
24
99
This is my attempt:
NT = zeros (x*y:1);
NT(:,1) = 1:x*y;
for i = 1:x*y
for j = 1
if NT(i,j) == x1(i,j)
NT(i,j) = 99;
end
end
end
This can be done very easily with ismember. Let
A = [1 2 3 4 5; 6 7 8 9 10; 11 12 13 14 15; 16 17 18 19 20; 21 22 23 24 25];
B = (1:25).';
new_value = 99;
Then
B(ismember(B, A(:, [1 end]))) = new_value;
gives
B =
99
2
3
4
99
99
7
8
9
99
99
12
13
14
99
99
17
18
19
99
99
22
23
24
99
Related
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]
I have a 100x200 matrix and I would like to show this matrix as a density plot. Here is a 8x10 sample.
X = [104 122 138 159 149 167 184 164 190 158; ...
54 42 55 55 63 75 72 73 66 76; ...
15 22 28 21 23 28 32 47 32 40; ...
18 12 20 22 28 17 30 17 22 18; ...
10 7 14 10 14 11 14 20 16 10; ...
5 6 3 3 6 12 6 2 8 9; ...
4 8 9 2 5 3 3 12 7 7; ...
6 6 2 3 10 1 9 8 11 8]
I have tried to use functions like bar3, surf, hist and so on but they don't have the end result I am after.
I would also like to represent the y axis on the new successful plot to be on a log axis. So similar to having semilogy(x,y,'rx') for example.
Are there any other methods I could use?
How about "surf" it like a spectrogram?
XX = log([104 122 138 159 149 167 184 164 190 158;
54 42 55 55 63 75 72 73 66 76;
15 22 28 21 23 28 32 47 32 40;
18 12 20 22 28 17 30 17 22 18;
10 7 14 10 14 11 14 20 16 10;
5 6 3 3 6 12 6 2 8 9;
4 8 9 2 5 3 3 12 7 7;
6 6 2 3 10 1 9 8 11 8]
figure
surf(XX, 'edgecolor', 'none'); view(0,90); axis tight;
xlabel ('x')
ylabel ('y')
NOTE:The first row represent the first row (104,122,138...)
and row 8 represent row 8 (6,7,2....)
Dark red = high value
light blue = low value
Matlab also provides a heatmap function.
>> X = [104 122 138 159 149 167 184 164 190 158; ...
54 42 55 55 63 75 72 73 66 76; ...
15 22 28 21 23 28 32 47 32 40; ...
18 12 20 22 28 17 30 17 22 18; ...
10 7 14 10 14 11 14 20 16 10; ...
5 6 3 3 6 12 6 2 8 9; ...
4 8 9 2 5 3 3 12 7 7; ...
6 6 2 3 10 1 9 8 11 8];
>> heatmap(X)
ans =
HeatmapChart with properties:
ColorData: [8×10 double]
Show all properties
The following plot appears:
I'm using MESH2D in Matlab in order to mesh ROI (Region Of Interest) from images. Now I would like to make binary masks from these triangular meshes. The outputs from [p,t] = mesh2d(node) are:
p = Nx2 array of nodal XY co-ordinates.
t = Mx3 array of triangles as indicies into P, defined with a counter-clockwise node ordering.
Example of an initial code (feel free to improve it!):
mask= logical([0 0 0 0 0; 0 1 1 0 0; 0 1 1 1 1; 0 1 1 0 0]) %let's say this is my ROI
figure, imagesc(mask)
lol=regionprops(mask,'all')
[p,t] = mesh2d(lol.ConvexHull); %it should mesh the ROI
How to make masks from this triangular mesh?
Thank you in advance!
This is p:
1,50000000000000 2
1,50000000000000 2,50000000000000
1,50000000000000 3
1,50000000000000 3,50000000000000
1,50000000000000 4
1,93703949778653 2,56171771423604
1,96936200278303 3,98632617574682
2 1,50000000000000
2 4,50000000000000
2,00975325040940 3,53647067507122
2,01137717786904 2,05700769275495
2,05400996239344 3,03376821385856
2,41193753423879 2,49774899749798
2,45957145752038 3,46313210038859
2,50000000000000 1,50000000000000
2,50000000000000 4,50000000000000
2,51246316199066 3,99053096338726
2,56500321259084 1,97186739050944
2,64423955240966 2,98576823004855
3 1,50000000000000
3 4,50000000000000
3,00248771086621 2,47385860181019
3,01650848812758 3,52665319517610
3,08981230082503 3,98949609178151
3,12731558449295 2,02370031640169
3,36937385842331 2,99811446160210
3,50000000000000 1,75000000000000
3,50000000000000 4,25000000000000
3,85193739480358 3,46578962137238
3,85353024582881 2,53499308989903
4 2
4 4
4,42246720814684 3,00037409439956
4,50000000000000 2,25000000000000
4,50000000000000 3,75000000000000
4,97304775909580 2,99999314296989
5 2,50000000000000
5 3,50000000000000
5,50000000000000 3
and t:
9 5 7
20 18 15
1 8 11
8 15 11
11 15 18
11 2 1
6 2 11
20 27 25
25 18 20
27 30 25
17 10 14
7 10 17
24 21 17
9 7 17
29 35 32
26 30 29
23 19 26
14 19 23
26 29 23
23 29 24
23 17 14
24 17 23
6 11 13
13 11 18
34 30 31
31 30 27
3 2 6
12 19 14
14 10 12
6 13 12
12 13 19
12 3 6
28 21 24
28 29 32
24 29 28
9 17 16
16 17 21
38 35 33
35 29 33
33 29 30
34 37 33
33 30 34
19 13 22
26 19 22
18 25 22
22 13 18
22 30 26
22 25 30
4 7 5
4 10 7
4 12 10
3 12 4
38 33 36
36 33 37
39 38 36
36 37 39
To get the mask for the ix-th triangle, use:
poly2mask(p(t(ix,:),1),p(t(ix,:),2),width,height)
t is used to index n to get the data for one triangle.
I am trying to get the intersection between two vectors but the index in both vectors should be the same. For example:
x = [1 2 3 4 5 6 7 80 9 100 11 12 103 14 150 16 170 18 20 19]
y = [22 1 3 40 5 4 70 8 90 10 110 12 13 140 15 160 17 18 19 20]
the intesection should be [3 5 12 18] only.
My code:
x = [1 2 3 4 5 6 7 80 9 100 11 12 103 14 150 16 170 18 20 19];
y = [22 1 3 40 5 4 70 8 90 10 110 12 13 140 15 160 17 18 19 20];
inter = intersect(x,y);
It's simple with logical indexing:
>> x = [1 2 3 4 5 6 7 80 9 100 11 12 103 14 150 16 170 18 20 19];
>> y = [22 1 3 40 5 4 70 8 90 10 110 12 13 140 15 160 17 18 19 20];
>> x(x==y)
ans =
3 5 12 18
>> x(abs(x-y)<=3) %// or y(abs(x-y)<=3) for the y values instead of the x values
ans =
2 3 5 6 12 18 20 19
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 ) ;