0

请参阅此图以获取说明:前 。两条红色曲线通过两次使用样条函数进行插值。现在我需要找到将蓝色点与两条红色曲线对齐的水平位移。结果必须如下所示:后 .

是否可以找到属于某个样条曲线的某个给定 y 坐标的 x 坐标?那么这可以很容易地解决。

编辑:简单地改变 x 和 y 轴并没有帮助,因为样条曲线并没有为两条曲线之一提供良好的曲线。

Edit2:我忘了说时间很重要。我正在寻找一个非常快速的解决方案。

4

1 回答 1

1

xBlueyBlue是蓝点的坐标(n×1 向量),并且yRedFun是样条逼近函数,因此yRedFun(x)将返回插值的红线x。例如yRedFun,可能是匿名函数句柄@(x) ppval(pp,x)。也许您需要稍微外推红线,以便在所有 xBlue 上定义 yRedFun。

我们现在可以定义一个最小化函数:

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);  
于 2012-10-26T00:34:06.637 回答