Поиск оптимального перекрытия сигналов в Matlab

Я пытаюсь увидеть несколько примеров того, как найти оптимальное перекрытие между двумя сигналами. Вот несколько примеров данных.

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-значения и диапазоны для x-значений. В частности, я хотел бы изменить ТОЛЬКО x2 и y2. Значения x должны сохранять свой относительный интервал (т. Е. Расстояние между любыми двумя последовательными значениями x (в приведенном выше примере x2 это 1) должно быть одинаковым, но при нахождении оптимального перекрытия это новое расстояние может отличаться от исходное расстояние). Другими словами, "форма" 2-го сигнала должна оставаться прежней.

Как правило, необходимо предпринять два шага:

  1. Присвойте новые x2-значения
  2. Масштабируйте y2-значения по некоторому глобальному коэффициенту

Я хотел бы определить оптимальное перекрытие как минимальное вычитание между двумя сигналами. То есть от первого x-значения (самого низкого из x1 и x2) до последнего x-значения (самого высокого из x1 и x2) вычитание двух сигналов является минимальным. Обратите внимание, что формы сигналов можно вычесть, даже если они имеют разные x-значения, путем интерполяции между точками. Если данных нет, вычитание должно просто включать 0 для той или иной волны.

Любые идеи? Заранее спасибо!


person CodeGuy    schedule 11.08.2015    source источник
comment
Так почему бы вам просто не сделать векторы одинаковой длины и учесть разницу между двумя y?   -  person kkuilla    schedule 11.08.2015
comment
Данные не работают. Они не всегда будут иметь одинаковую длину и одинаковые значения x.   -  person CodeGuy    schedule 11.08.2015
comment
Я правильно понимаю, что вы можете масштабировать по x и y? Имеют ли данные в конце примерно такой же диапазон x, как и в том же количестве пиков?   -  person lhcgeneva    schedule 11.08.2015
comment
Да, две формы волны, как правило, всегда будут иметь один и тот же общий тип формы с точки зрения пиков и впадин. Единственное требование - чтобы форма этого второго сигнала оставалась прежней. Таким образом, некоторые значения x не могут быть сжаты или растянуты больше, чем другие.   -  person CodeGuy    schedule 11.08.2015


Ответы (1)


Метод 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;

Вывод:  введите описание изображения здесь

person lhcgeneva    schedule 11.08.2015
comment
Кроме того, не могли бы вы добавить код, чтобы продемонстрировать, как устанавливать ограничения. xOffSet, кажется, прыгает гораздо больше, чем нужно. - person CodeGuy; 12.08.2015
comment
И последняя идея: можем ли мы добавить возможность сжимать или растягивать формы волны? Я нахожу, что часто это не очень хорошо работает визуально, потому что вторая форма волны слишком тонкая или толстая, несмотря на ту же форму, и простое масштабирование значений x не исправит этого. Есть ли способ растянуть / сжать второй сигнал? Это может быть еще один параметр. Огромное спасибо!! - person CodeGuy; 12.08.2015
comment
Не уверен, поможет ли здесь добавление дополнительного параметра, что бы это изменилось с точки зрения функции, если не относительный интервал между вашими x-значениями? Единственное, что я мог представить, - это добавить параметр согласия, который проверяет, насколько хорошо fminsearch выполняет свою работу. Если найденный локальный минимум невелик, вы можете снова запустить fminserach с скорректированными семенами. Не могли бы вы привести мне еще несколько примеров, например, трех или четырех сигналов, для которых это не работает? - person lhcgeneva; 12.08.2015