1

2 つの波形間の最適なオーバーラップを見つける方法の例をいくつか見ようとしています。ここにいくつかの例のデータがあります。

x1 = [108.1 108.2 108.3 108.4 108.5 108.6 108.7 108.8 108.9 109.0 109.1 109.2 109.3 109.4 109.5 109.6];
y1 = [0 0 2 6 7 6 2 -5 -6 -5 0 8 9 8 0 0];

x2 = [-1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y2 = [0 0 0 3 6 9 8 7 6 5 3 -3 -7 -3 0 1 10 9 4 0 0 0];

ここに画像の説明を入力 ここに画像の説明を入力

x波形の-値と -値の範囲が異なることに注意してくださいxx2具体的には、 と のみを変更したいと思いy2ます。値はx相対的な間隔を維持する必要があります (つまり、任意の 2 つの連続する x 値 (上記のx2例では1) の間の距離は同じでなければなりませんが、最適なオーバーラップを見つける際に、新しい距離は元の距離とは異なる可能性があります)。 . つまり、2 番目の波形の「形状」は同じままでなければなりません。

一般に、次の 2 つの手順を実行する必要があります。

  1. x2新しい値 を割り当てる
  2. y2値をグローバルな係数でスケーリングします

最適なオーバーラップを、2 つの波形間の最小化された減算として定義したいと思います。つまり、最初のx値 (x1およびの最小値x2) から最後の値 (およびxの最大値) まで、2 つの波形の減算は最小になります。ポイント間を補間することにより、波形が異なる値を持っていても、波形を減算できることに注意してください。データが存在しない場合、減算には基本的にいずれかの波の a を含める必要があります。x1x2x0

何か案は?前もって感謝します!

4

1 に答える 1

2

方法 1:全体的な形状が同じであるが、確実に比較できる絶対的な特徴 (極値など) がない場合にうまく機能します。

function optim = minimize_distance()

x1 = [108.1 108.2 108.3 108.4 108.5 108.6 108.7 108.8 108.9 109.0 109.1 109.2 109.3 109.4 109.5 109.6];
y1 = [0 0 2 6 7 6 2 -5 -6 -5 0 8 9 8 0 0];
x2 = [-1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20];
y2 = [0 0 0 3 6 9 8 7 6 5 3 -3 -7 -3 0 1 10 9 4 0 0 0];

%Get educated guesses for parameters
xScalingInitial = abs((x1(end)-x1(1))/(x2(end)-x2(1)));
yScalingInitial = mean(abs(y2))/mean(abs(y1));
xOffsetInitial = (x2(1) - x1(1));

%determine how much these educated guesses can vary (here 10% for the
%Offset in x and 20% for the scaling)
x2diff = peak2peak(x2);
lowerBounds = [xScalingInitial - xScalingInitial*0.2, ...
               yScalingInitial - yScalingInitial*0.2, ...
               xOffsetInitial-x2diff*0.1];
upperBounds = [xScalingInitial + xScalingInitial*0.2, ...
               yScalingInitial + yScalingInitial*0.2, ...
               xOffsetInitial+x2diff*0.1];

%fminsearch performs an unconstrained search, fminsearchbnd (from
%MatlabFileExchange) also handles constrained functions. First input is the
%function to be minimized (see below, function to_minimize()). The output
%of this function (dist) will be minimized by fminsearch. @(x) tells matlab
%which variable is varied (see anonymous functions for reference). x1, x2,
%y1, y2 are parameters that are not changed by fminsearch. x is an array
%containing the three variable values for xScaling, yScaling and xOffSet
%which are varied. 
optim = fminsearchbnd(@(x) ...
                    to_minimize(x, x1, y1, x2, y2), ...
                    [xScalingInitial, yScalingInitial, xOffsetInitial],...
                    lowerBounds, upperBounds);

function dist = to_minimize(x, x1, y1, x2, y2)
%Assign variables from input array
xScaling = x(1);
yScaling = x(2);
xOffSet  = x(3);
%Get the scaled version of arrays y2 and x2.
y2Scaled = y2*yScaling;
x2Scaled = x2*xScaling-xOffSet;
%Linspace() creates 100 (default, this can be set to more or less if you
%want more or less precision) points between x1(1) and x1(end) (same for x2), 
%linearly spaced
x2Interp = linspace(x2Scaled(1), x2Scaled(end));
x1Interp = linspace(x1(1), x1(end));
%Interpolate y values at these points
y2Interp = interp1(x2Scaled, y2Scaled, x2Interp);
y1Interp = interp1(x1, y1, x1Interp);
%Now that we have two arrays of same size and scale we can compare by
%taking the point to point distance and minimizing it.
dist = sum((x1Interp-x2Interp).^2+(y1Interp-y2Interp).^2);
%Plot, comment out for performance!
clf
hold on;
plot(x1, y1);
plot(x2Interp, y2Interp);
hold off;
pause(0.01);

出力: 方法 2:曲線の形状が実質的に同じである場合は、最小値と最大値を比較し、それに応じて x2/y2 のインデックス/スケーリングを調整することをお勧めします。次のように実行できます。ここに画像の説明を入力

%find minima and maxima (and their indices) in original graphs
[~, minIdxY1] = min(y1);
[y1max, maxIdxY1] = max(y1);
[~, minIdxY2] = min(y2);
[y2max, maxIdxY2] = max(y2);

%Compare maxima, to get scaling factor for y
yScaling = y1max/y2max;
y2Scaled = y2*yScaling;

%Get x distance between minimum and maximum for both graphs
x1diff = abs(x1(minIdxY1) - x1(maxIdxY1));
x2Diff = abs(x2(minIdxY2) - x2(maxIdxY2));

%Stretch x2 to the shape of x1 by multiplying with the ratio of the two
%above distances
stretchFactor = x1diff/x2Diff;
x2stretched = x2* stretchFactor;

%Get new offset by comparing the midpoint between maximum and minimum
%of graph1 (x1/y1) and x2stretched/y2
midX1 = (x1(minIdxY1)+x1(maxIdxY1))/2;
midX2 = (x2stretched(minIdxY2)+x2stretched(maxIdxY2))/2;
x2stretchedOffset = x2stretched + (midX1-midX2);

figure;
hold on;
plot(x1, y1);
plot(x2stretchedOffset, y2Scaled);
legend('x1/y1', 'x2stretched/y2');
hold off;

出力: ここに画像の説明を入力

于 2015-08-11T21:58:24.500 に答える