How can I find the coordinates of a known vector, within a larger vector?

I'd like to take a group of linear vectors, and find where a smaller known vector is placed within them.
For example if I have:
Vector1 = 3 2 4 1 3 2 4 1 3 2 4 2 4 3 4 3 1 4 2 2 3 4 1 4 2
Vector2 = 1 4 2 3 1 4 2 4 2 3 4 3 1 4 2 2 4 1 3 2 4 1 2 3 1 1 1
Vector3 = 1 4 2 3 4 1 4 2 3 1 4 3 4 3 1 4 2 1 4 2 3 1 4 1 3
Vector4 = 1 3 2 4 2 4 1 4 3 2 3 4 3 1 4 2 1 1 3 2 4 2 4 1 2 3
Vector5 = 1 3 2 4 2 1 1 1 3 4 3 2 3 4 3 1 4 2 1 1 3 2 4 2 4 1 2 3
ConstantVector = 3 4 3 1 4 2
I know that each of the vectors 1-5 have the ConstantVector in them somewhere. I would like to be able to quickly output the position of the vector in each case.
The end aim is to be able to put Vectors 1-5 into a matrix of zeros such the sections denoted by ConstantVector are all aligned in columns. For example the above vectors would become:
3 2 4 1 3 2 4 1 3 2 4 2 4|3 4 3 1 4 2|2 3 4 1 4 2 0 0 0 0 0 0
0 0 0 0 1 4 2 3 1 4 2 4 2|3 4 3 1 4 2|2 4 1 3 2 4 1 2 3 1 1 1
ConstantOverLaying = 0 0 1 4 2 3 4 1 4 2 3 1 4|3 4 3 1 4 2|1 4 2 3 1 4 1 3 0 0 0 0
0 0 0 1 3 2 4 2 4 1 4 3 2|3 4 3 1 4 2|1 1 3 2 4 2 4 1 2 3 0 0
0 1 3 2 4 2 1 1 1 3 4 3 2|3 4 3 1 4 2|1 1 3 2 4 2 4 1 2 3 0 0
I've put lines on either side of the ConstantVector just to show that they overlap.
My current thinking is that once I have the coordinates I can use them to automatically shift them left or right as needed when adding them to the matrix of zeroes. If anyone can think of any better ways to do this it is of course welcome.

 Risposta accettata

You can use strfind:
Vector1 = [3 2 4 1 3 2 4 1 3 2 4 2 4 3 4 3 1 4 2 2 3 4 1 4 2];
Vector2 = [1 4 2 3 1 4 2 4 2 3 4 3 1 4 2 2 4 1 3 2 4 1 2 3 1 1 1];
Vector3 = [1 4 2 3 4 1 4 2 3 1 4 3 4 3 1 4 2 1 4 2 3 1 4 1 3];
Vector4 = [1 3 2 4 2 4 1 4 3 2 3 4 3 1 4 2 1 1 3 2 4 2 4 1 2 3];
Vector5 = [1 3 2 4 2 1 1 1 3 4 3 2 3 4 3 1 4 2 1 1 3 2 4 2 4 1 2 3];
ConstantVector = [3 4 3 1 4 2];
strfind(Vector1,ConstantVector)
if you want all the vectors 1...5 together:
V={Vector1;Vector2;Vector3;Vector4;Vector5};
cellfun(@(x) strfind(x, ConstantVector),V)
Are you able to do the rest on your own? If you need further help, just ask here.

6 Commenti

That strfind() is a neat trick - most people don't think of it because they think it only works with strings. +1 vote.
That's great thanks :)
Not afraid to admit I'm a MatLab novice, but I'm enjoying it so I'll give it a shot tonight and will comment again if I need help.
Thanks again
Hi again,
I tried last night and think I've almost cracked it, but I've spent the whole day unable to get the constant sections of the vectors to align. I'm confident the fix is going to seem obvious when I'm told but I can't work it out.
My code thus far is:
clear
clc
Vector1 = [1 4 2 3 4 1 4 2 3 1 4 3 4 3 1 4 2 1 4 2 3 1 4 1 3];
Vector2 = [1 4 2 3 1 4 2 4 2 3 4 3 1 4 2 2 4 1 3 2 4 1 2 3 1 1 1];
Vector3 = [3 2 4 1 3 2 4 1 3 2 4 2 4 3 4 3 1 4 2 2 3 4 1 4 2];
Vector4 = [1 3 2 4 2 4 1 4 3 2 3 4 3 1 4 2 1 1 3 2 4 2 4 1 2 3];
Vector5 = [1 3 2 4 2 1 1 1 3 4 3 2 3 4 3 1 4 2 1 1 3 2 4 2 4 1 2 3];
ConstantVector = [3 4 3 1 4 2]; %A known constant region within each vector
NumVectors = 5; %Manually input the number of vectors
V={Vector1;Vector2;Vector3;Vector4;Vector5}; %Manually input the name of each vector
Positions = cellfun(@(x) strfind(x, ConstantVector),V); %Find the coridnates of the first digit in the known constant region, within each vector.
Lengths = cellfun('length',V) %Finds the length of each vector
FrameStart = Positions(1) %Finds an abitary starting point for each allignment but taking the first ConstantVector point within the first vector
FrameShift = Positions - FrameStart %Finds the number of units that each vector must shift positively or negitively to allign all the constant regions
MaxLeft = min(FrameShift) %Highlights the maximum amount of shift to the left that will occour
MaxRight = max((Lengths + FrameShift)) %Highlights the maximum amount of shift to the right that will occour
Range = MaxRight - MaxLeft %Gives the number of columns needed in the blank zeros vector to accomodate all vectors after shifting
Empty = zeros(NumVectors,Range); %Creates the matrix of zeros to input the vectors
Start = (MaxLeft * sign(MaxLeft)) + FrameShift %The starting column cordinate for each vector input after shifting. I.e. for Vector 1 it will always be equal to the Frameshift since it is the abitary fixed vector. The idea is that with this the following for loop will then know where to start entering each vector.
InstertSpace = Start:(Start+Lengths)
for i = 1:NumVectors
SubVector = V{(i),1}; %Saves a temporary specific Vector for a specific row of the Empty vector
SubLength = Lengths(i); %Saves a temporary length of the vector to be inserted for a specific row of the Empty vector
SubStart = Start(i); %Saves a temporary starting column cordinate for the Vector insertion to begin for a specific row of the Empty vector
for j = SubStart:(SubStart+SubLength)
for ii = 1:SubLength
Empty(i,ii) = SubVector(ii) %Enters values into the empty matrix
end
end
end
I realise it's a bit messy on here sorry. My main issue is that I can't seem to get it to go through each column of the Empty matrix without it trying to put every value of the vector to be inserted in every space, so it just ends up with the last value of each Vector, in each row.
Hope I've made this clear enough. Thank you.
Learn about vectorization in MATLAB. Try this:
Vector1 = [3 2 4 1 3 2 4 1 3 2 4 2 4 3 4 3 1 4 2 2 3 4 1 4 2];
Vector2 = [1 4 2 3 1 4 2 4 2 3 4 3 1 4 2 2 4 1 3 2 4 1 2 3 1 1 1];
Vector3 = [1 4 2 3 4 1 4 2 3 1 4 3 4 3 1 4 2 1 4 2 3 1 4 1 3];
Vector4 = [1 3 2 4 2 4 1 4 3 2 3 4 3 1 4 2 1 1 3 2 4 2 4 1 2 3];
Vector5 = [1 3 2 4 2 1 1 1 3 4 3 2 3 4 3 1 4 2 1 1 3 2 4 2 4 1 2 3];
ConstantVector = [3 4 3 1 4 2];
V={Vector1;Vector2;Vector3;Vector4;Vector5};
X = cellfun(@(x) strfind(x, ConstantVector),V);
Y = cellfun('length',V);
tot = max(X) + max(Y-X);
W = cellfun(@(v,n)[v,zeros(1,tot-n)], V, num2cell(Y), 'UniformOutput',false);
W = cellfun(@(v,n)circshift(v,[1,n]), W, num2cell(max(X)-X), 'UniformOutput',false);
W = vertcat(W{:})
You've been close to the solution:
FrameStart = max(Positions)
FrameShift = FrameStart-Positions
MaxLength=max(FrameShift+Lengths)
Empty=zeros(length(V),MaxLength);
for cnt=1:length(V)
Empty(cnt,1+FrameShift(cnt):FrameShift(cnt)+Lengths(cnt))=V{cnt};
end
Instead of an arbitrary starting point, I choose the one goes most left. That simplifies further code. The FrameShift must be defined the other way around - big numbers must be shifted far to the right. Finally, it's just simple replacing.
Thanks both of you! :)
Michael I understand your version and think I could do it again from scratch.
Stephen your version has things I've never seen before such as num2cell, but I will definitely spend some time "reverse engineering" it to learn the new commands.
Again thanks

Accedi per commentare.

Più risposte (0)

Categorie

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by