Пусть xBlue
и yBlue
будут координатами синих точек (векторы размером n на 1), а yRedFun
будет функцией аппроксимации сплайна, поэтому yRedFun(x)
вернет интерполированную красную линию в точке x
. Например. yRedFun
может быть дескриптором анонимной функции @(x) ppval(pp,x)
. Возможно, вам потребуется немного экстраполировать красную линию, чтобы yRedFun определялся для всех xBlue .
Теперь мы можем определить функцию минимизации:
cost = @(deltaX) norm( yBlue - arrayfun(yRedFun, xBlue + deltaX) )
Его минимум можно найти с помощью deltaX = fminsearch(cost, 0)
или deltaX = fzero(cost, 0)
.
Хотя это может быть слишком общий подход, если высокая производительность не требуется, все должно быть в порядке. Кроме того, поскольку соответствие между синим и красным, вероятно, неточное, метод формализует норму, которую вы пытаетесь минимизировать.
Если требуется производительность, можно использовать следующий алгоритм:
function deltaX = findDeltaX(xBlue, yBlue, yRedFun, precision)
deltaX = 0; % total delta
deltaDeltaX = Inf; % delta at each iteration
yRedFunDer = fnder(yRedFun);
while(abs(deltaDeltaX) > precision)
xRed = xBlue + deltaX;
yRed = fnval(yRedFun, xRed);
yRedDer = fnval(yRedFunDer, xRed);
deltaDeltaX = yRedDer \ (yRed - yBlue);
deltaX = deltaX + deltaDeltaX;
end
end
Точки с низкой производной могут снизить точность. На первой итерации вы можете выбрать N
точек с наивысшей производной и отбросить все остальные. Это также повысит производительность.
[~, k] = sort(abs(yRedDer), 'descend');
k = k(1:N);
yRedDer = yRedDer(k);
xBlue = xBlue(k);
yBlue = yBlue(k);
person
VBel
schedule
26.10.2012