How can I plot part of a simple vector? - matlab

Suppose I've got the following vector and plot it from index 1 to 11:
a = [1 2 5 4 5 4 2 3 7 1 5];
plot(a);
How can I plot only part of this vector? like from index 3 to index 7. I found this question but couldn't figure out how to use it.

a = [1 2 5 4 5 4 2 3 7 1 5];
plot(a(3:7));

Related

Subtraction by tracking x y coordinates

I have set of arrays:
x1=[1 2 3 4 5 6 7 8 9];
y1=[1 2 3 4 5 6 7 8 9];
z1=[2 2 2 2 2 9 6 2 2];
and
x2=[6 7];
y2=[6 7];
z2=[2 2];
by tracking x y coordinates, the z arrays have to be subtracted so that output will be
x=[1 2 3 4 5 6 7 8 9];
y=[1 2 3 4 5 6 7 8 9];
z=[2 2 2 2 2 7 4 2 2];
You can get the indicies of your elements in z using the ismember function:
a1=[x1.',y1.'];
a2=[x2.',y2.'];
[~,ix]=ismember(a2,a1,'rows')
z1(ix)=z1(ix)-z2
To use the ismember two matrices a1 and a2 are created witch contain the coordinates in rows. Then ismember with 'rows' option is used to get the indices.
When a point exists in x2/y2 which does not exist in x1/y1 the above code will fail.

How to randomly permute some matrix into a bigger matrix in Matlab?

This is the main matrix:
a =
1 2 3 3 4 5 2 5 7
3 4 5 5 6 8 6 4 9
This main matrix contain 3 small matrix. The first one is:
[1 2 3;3 4 5]
The second one is:
[3 4 5;5 6 8]
The third one is:
[2 5 7;6 4 9]
I want to randomly permute these 3 matrix into the main matrix like this:
a =
2 5 7 3 4 5 1 2 3
6 4 9 5 6 8 3 4 5
How I can do that?
If you connect three 2D matrices, it is better to use a 3D matrix:
%get a 3d matrix
b=reshape(a,size(a,1),3,[]);
%randomly permute third dimension
c=b(:,:,randperm(size(b,3)));
%return to 2d representation
d=reshape(c,size(a));

Rearranging matrix using col2im in Matlab

My matrix is this:
0 3 0
0 1 2
4 4 1
I use im2col on it like this:
im2col(A, [2 2], 'sliding')
which correctly yields this:
0 0 3 1
0 4 1 4
3 1 0 2
1 4 2 1
I call this matrix K. Now I use col2im to go back to my original matrix. From the Matlab documentation I use this:
col2im(K, [2 2], [5 5],'sliding')
But this doesn't gives me my original matrix A. Reason being [5 5] should be [4 4] to get a 3*3 matrix for starters. But when I do that I get
??? Error using ==> reshape
To RESHAPE the number of elements must not change.
Why is that? And how can I get my original matrix back?
Fromthe docs:
A = col2im(B,[m n],[mm nn],'sliding') rearranges the row vector B into
a matrix of size (mm-m+1)-by-(nn-n+1). B must be a vector of size
1-by-(mm-m+1)*(nn-n+1). B is usually the result of processing the
output of im2col(...,'sliding') using a column compression function
(such as sum).
So that says to me you should be trying something like:
col2im(sum(K), [2 2], [4 4],'sliding')
however that would require K to have 9 columns. I don't have the image processing toolbox handy to test this right now
Your col2im doesn't work because it uses reshape and for that the number of elements of the matrix you wish to reshape (K) and the new one, need to be the same. This is not the case anymore, as through your transformation of A with im2col you obviously changed that. A has 9 and K 16 elements.
So you basically need to get back to a 3*3 matrix again by getting rid of the redundand doubled elements (due to the overlapping 2*2 blocks used in im2col) in K.
For that you could just make a new matrix (C) with the elements that you need:
C = [K([1,3,11;2,4,12;6,8,16])]
As long as you first went from a 3*3 to a 4*4 matrix using the same order of blocks this should work.
Maybe you could tell us more about what you really want to achieve, because I don't see any reason for this in the first place. It may also be possible that you might be better off using other functions instead, but I can only see that if I know what the reasoning behind your question is.
clear
clc
img = double(imread('tire.tif'));
[r c] = size(img);
w = 8;
imgBlock = im2col(img,[w w],'sliding'); imgBlock = imgBlock(:);
[x y] = meshgrid(1:c,1:r);
xx = im2col(x,[w w], 'sliding'); xx = xx(:);
yy = im2col(y,[w w], 'sliding'); yy = yy(:);
img2 = accumarray([yy xx], imgBlock, [], #mean);
figure,imshow(img, []);
figure,imshow(img2,[]);
% random matrix as image
img = randi(10,4)
img =
6 2 2 7
5 8 7 8
1 4 3 5
4 6 7 1
% matrix size
[r c] = size(img)
% patch size
w = 2;
% image to patch
imgBlock = im2col(img,[w w],'sliding')
% image patchs matrix to a vector
imgBlock = imgBlock(:);
r =
4
c =
4
imgBlock =
6 5 1 2 8 4 2 7 3
5 1 4 8 4 6 7 3 7
2 8 4 2 7 3 7 8 5
8 4 6 7 3 7 8 5 1
% index matrix size equal image size
[x y] = meshgrid(1:c,1:r)
% index matric to patchs;to vector
xx = im2col(x,[w w], 'sliding'); xx = xx(:);
yy = im2col(y,[w w], 'sliding'); yy = yy(:);
x =
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
y =
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
% yy :row index xx: column index
% applies the function mean to each subset of elements in imgBlock that have identical subscripts in [yy xx].
img2 = accumarray([yy xx], imgBlock, [], #mean);
img
img2
img =
6 2 2 7
5 8 7 8
1 4 3 5
4 6 7 1
img2 =
6 2 2 7
5 8 7 8
1 4 3 5
4 6 7 1
% [col,row,value]
a = [xx,yy,imgBlock]
a =
1 1 6
1 2 5
2 1 2
2 2 8
1 2 5
1 3 1
2 2 8
2 3 4
1 3 1
1 4 4
2 3 4
2 4 6
2 1 2
2 2 8
3 1 2
3 2 7
2 2 8
2 3 4
3 2 7
3 3 3
2 3 4
2 4 6
3 3 3
3 4 7
3 1 2
3 2 7
4 1 7
4 2 8
3 2 7
3 3 3
4 2 8
4 3 5
3 3 3
3 4 7
4 3 5
4 4 1
% The number of times that img(2,2) occurs in the matrix img
a(xx == 2 & yy == 2,:)
ans =
2 2 8
2 2 8
2 2 8
2 2 8

MATLAB Concatenate vectors with unequal dimensions

Lets say I have got vector1:
2
3
5
6
7
9
And a vector2:
1
2
3
Now I would like to obtain the following matrix:
2 1
3 2
5 3
6 1
7 2
9 3
That is, I want to add vector2 as a column next to vector1 until the new column is completely filled. I have to do this with a lot of vectors with different sizes. The only thing I know in advance is that the length of vector1 is an integer multiple of the length of vector2.
Any suggestions?
Use repmat to replicate the smaller matrix.
a = [2 3 5 6 7 9]';
b = [1 2 3]';
c = [a repmat(b, length(a) / length(b), 1)]
Result:
c =
2 1
3 2
5 3
6 1
7 2
9 3
You can then replicate the vector:
[vector1, repmat(vector2,n,1)]
where n is your multiple of vector2.
This could be an alternative
[x [y'; y']]

How do I convert a 2X2 matrix to 4X4 matrix in MATLAB?

I need some help in converting a 2X2 matrix to a 4X4 matrix in the following manner:
A = [2 6;
8 4]
should become:
B = [2 2 6 6;
2 2 6 6;
8 8 4 4;
8 8 4 4]
How would I do this?
In newer versions of MATLAB (R2015a and later) the easiest way to do this is using the repelem function:
B = repelem(A, 2, 2);
For older versions, a short alternative to the other (largely) indexing-based solutions is to use the functions kron and ones:
>> A = [2 6; 8 4];
>> B = kron(A, ones(2))
B =
2 2 6 6
2 2 6 6
8 8 4 4
8 8 4 4
Can be done even easier than Jason's solution:
B = A([1 1 2 2], :); % replicate the rows
B = B(:, [1 1 2 2]); % replicate the columns
Here's one more solution:
A = [2 6; 8 4];
B = A( ceil( 0.5:0.5:end ), ceil( 0.5:0.5:end ) );
which uses indexing to do everything and doesn't rely on the size or shape of A.
This works:
A = [2 6; 8 4];
[X,Y] = meshgrid(1:2);
[XI,YI] = meshgrid(0.5:0.5:2);
B = interp2(X,Y,A,XI,YI,'nearest');
This is just two-dimensional nearest-neighbor interpolation of A(x,y) from x,y ∈ {1,2} to x,y ∈ {0.5, 1, 1.5, 2}.
Edit: Springboarding off of Jason S and Martijn's solutions, I think this is probably the shortest and clearest solution:
A = [2 6; 8 4];
B = A([1 1 2 2], [1 1 2 2]);
A = [2 6; 8 4];
% arbitrary 2x2 input matrix
B = repmat(A,2,2);
% replicates rows & columns but not in the way you want
B = B([1 3 2 4], :);
% swaps rows 2 and 3
B = B(:, [1 3 2 4]);
% swaps columns 2 and 3, and you're done!
Here's a method based on simple indexing that works for an arbitrary matrix. We want each element to be expanded to an MxN submatrix:
A(repmat(1:end,[M 1]),repmat(1:end,[N 1]))
Example:
>> A=reshape(1:6,[2,3])
A =
1 3 5
2 4 6
>> A(repmat(1:end,[3 1]),repmat(1:end,[4 1]))
ans =
1 1 1 1 3 3 3 3 5 5 5 5
1 1 1 1 3 3 3 3 5 5 5 5
1 1 1 1 3 3 3 3 5 5 5 5
2 2 2 2 4 4 4 4 6 6 6 6
2 2 2 2 4 4 4 4 6 6 6 6
2 2 2 2 4 4 4 4 6 6 6 6
To see how the method works, let's take a closer look at the indexing. We start with a simple row vector of consecutive numbers
>> m=3; 1:m
ans =
1 2 3
Next, we extend it to a matrix, by repeating it M times in the first dimension
>> M=4; I=repmat(1:m,[M 1])
I =
1 2 3
1 2 3
1 2 3
1 2 3
If we use a matrix to index an array, then the matrix elements are used consecutively in the standard Matlab order:
>> I(:)
ans =
1
1
1
1
2
2
2
2
3
3
3
3
Finally, when indexing an array, the 'end' keyword evaluates to the size of the array in the corresponding dimension. As a result, in the example the following are equivalent:
>> A(repmat(1:end,[3 1]),repmat(1:end,[4 1]))
>> A(repmat(1:2,[3 1]),repmat(1:3,[4 1]))
>> A(repmat([1 2],[3 1]),repmat([1 2 3],[4 1]))
>> A([1 2;1 2;1 2],[1 2 3;1 2 3;1 2 3;1 2 3])
>> A([1 1 1 2 2 2],[1 1 1 1 2 2 2 2 3 3 3 3])
There is a Reshape() function that allows you to do this...
For example:
reshape(array, [64, 16])
And you can find a great video tutorial here
Cheers