Combing Algorithm: Finding Unique Equaltiy between Vectors of Different Sizes Using Ranges
1 次查看(过去 30 天)
显示 更早的评论
I need to make an algorithm in MATLAB that can compare two vectors of different sizes, but of the same type of data. The algorithm goes as follows:
- There are 3 times as many variables in vector B as there are in vector A.
- We are trying to figure out what offset of vector A makes all of the elements in vector A equal to the same proportion of elements in vector B. In other words, A(1)=B(1), A(2)=B(4), and so on for each element in A; basically A needs to have an equal in B.
- Elements in vector A can be within certain ranges of vector B, where those ranges are defined by another vector we'll call vector C. To understand this visually, think of a single index of B as a static block that doesn't move, and an index of A as a bristle that must fit in the range of any given index B where each respective value in the offset vector A fit into specific indexes of vector B.
- To find this fit, these instances where A falls between [B,B+C] are then saved as a conditional (0s&1s) vector called "instances" which is then compared to a static instance vector called "siginstances". If instances == siginstances, then the offset of A has been found, else continue to offset A until a given number or until a match has been found.
To better understand the approach of this algorithm, you may want to consider that the vectors mentioned are being used to compare times caught by two different computers recording the same information. The relative algorithm goes as follows:
%Postive Incrimentation%
%test the offset of sigA between 0 and 90 seconds after sigA
IncrementA = sigA;
for a = 0.0:.000001:90
IncrementA = sigA+a; %offset vector A
instance = (IncrementA>=sigB) & (IncrementA<=sigB+sigC);
%see if the values of vector A are within [sigB,sigB+sigC]
%Think of sigB as a block and sigA as bristles. The proper bristles of sigA need to fit into
%the range of block sigB, where each of these blocks and bristles are a single index of that vector.
%The range in which an index of sigA mus fit into sigB is defined by sigC, whose size is the same
%as sigB, but contains different ranges for each instance of B.
if (instance == siginstances)
%compare the resulting conditional vector to the static vector; if true print out offset,
%else continue algorithm till an offset is found, if any.
disp(a);
break;
end %end if statement
end %end for statement
%use the same approach for decrementation (aka subtracting a from sigA)
I hope that this approach and request is clear to you so that you can help me create the proper algorithm that can properly process the above mathematical nightmare in MATLAB. Let me know if you need further clarification. Thank you.
5 个评论
Geoff Hayes
2016-1-4
Midimistro - is this homework? While you have explained the problem that you need to solve, you haven't indicated where in the algorithm you are getting stuck. Please clarify which part is causing you a problem and please show what you have tried so far.
回答(1 个)
Guillaume
2016-1-4
Despite your claim, it's not entirely clear what you want. Particularly I've not understood at all what your truth vectors correspond to. A simple example would really help.
If I understood correctly you have as input something like:
A = [1 4 7 10];
B = 0:12;
C = [0.5 1 2 0.5 0 1 2 1 1 0.5 1 0 1];
Creating a truth table that tells you which element of A is between which elements of [B, B+C] is easy:
inrange = bsxfun(@ge, A', B) & bsxfun(@le, A', B+C)
The rows of inrange corresponds to elements of A, the columns correspond to elements of B. A 1 indicates that the corresponding element of A is within the range of B. If you have several 1 in a row, that means that element of A can match several elements of B.
You can create all combinations of potential match with ndgrid:
Bmatches = cellfun(@find, num2cell(inrange, 2), 'UniformOutput', false);
[Bmatches{:}] = ndgrid(Bmatches{:});
Bcombs = reshape(cat(numel(A)+1, Bmatches{:}), [], numel(A))
Each row of BCombs is a combination of B indices that match A
Note that ndgrid will run out of memory for A with a moderate number of elements and you may have to use a loop instead to generate the combinations.
8 个评论
Guillaume
2016-1-7
Your latest explanation does make things a lot clearer, thanks. But, unless I've misunderstood something, it seems to me that you're over complicating things a bit with your noise/non-noise and truth vectors.
You could just remove the noise values from ATime, and then try to match the resulting ATime with BTime. No need for DynamicTruth and you don't care about the signal values anymore.
My bsxfun method would work in combination with your loop approach:
ATime = [0.012, 0.023, 0.032, 0.042];
ASig = [-14, -100, -14.2, -14.1];
ATimeValid = ATime(ASig > -100);
BTime = [1.012, 1.013, 1.014, 1.022, 1.024, 1.025, 1.032, 1.033, 1.040, 1.041, 1.042];
BLife = [.001, .001, .003, .001, .002, .003, .001, .004, .001, .001, .005];
BUpper = BTime + BLife;
for offset = 0 : .001 : 90
AOffset = ATimeValid + offset;
if all(any(bsxfun(@ge, AOffset, BTime') & bsxfun(@le, AOffset, BUpper')))
fprintf('found a valid offset: %g\n', offset);
end
end
I'm not convinced that a trial and error method is the most efficient way of going about it. You're basically trying to match two signals, one being sampled at a lower and random frequency. I'm sure that there are some more efficient methods of doing that.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Numeric Types 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!