Time series 执行一项;“在线”;线性插值

Time series 执行一项;“在线”;线性插值,time-series,matlab,interpolation,Time Series,Matlab,Interpolation,我有一个问题,我需要对从传感器获取的一些数据进行线性插值(从技术上讲是位置数据,但数据的性质并不重要)。我现在在matlab中这样做,但由于我最终会将此代码迁移到其他语言,我希望代码尽可能简单,并且不使用任何复杂的matlab特定/内置函数 我的实现最初看起来还不错,但当对照matlab的内置interp1函数检查我的工作时,我的实现似乎并不完美,我也不知道为什么。下面是我在一个已经完全收集的数据集上使用的代码,但是当我在数据中循环时,我的行为就像我只有当前样本和上一个样本一样,这反映了我最终将

我有一个问题,我需要对从传感器获取的一些数据进行线性插值(从技术上讲是位置数据,但数据的性质并不重要)。我现在在matlab中这样做,但由于我最终会将此代码迁移到其他语言,我希望代码尽可能简单,并且不使用任何复杂的matlab特定/内置函数

我的实现最初看起来还不错,但当对照matlab的内置interp1函数检查我的工作时,我的实现似乎并不完美,我也不知道为什么。下面是我在一个已经完全收集的数据集上使用的代码,但是当我在数据中循环时,我的行为就像我只有当前样本和上一个样本一样,这反映了我最终将面临的问题

%make some dummy data
np = 109; %number of data points for x and y
x_data = linspace(3,98,np) + (normrnd(0.4,0.2,[1,np]));
y_data = normrnd(2.5, 1.5, [1,np]);

 %define the query points the data will be interpolated over
qp = [1:100];

kk=2; %indexes through the data
cc = 1; %indexes through the query points

qpi = qp(cc); %qpi is the current query point in the loop
y_interp = qp*nan; %this will hold our solution

while kk<=length(x_data)
    kk = kk+1; %update the data counter

    %perform online interpolation
    if cc<length(qp)-1
        if qpi>=y_data(kk-1) %the query point, of course, has to be in-between the current value and the next value of x_data
            y_interp(cc) = myInterp(x_data(kk-1), x_data(kk), y_data(kk-1), y_data(kk), qpi);
        end

        if qpi>x_data(kk), %if the current query point is already larger than the current sample, update the sample
            kk = kk+1;
        else %otherwise, update the query point to ensure its in between the samples for the next iteration
            cc = cc + 1;
            qpi = qp(cc);

            %It is possible that if the change in x_data is greater than the resolution of the query
            %points, an update like the above wont work. In this case, we must lag the data
            if qpi<x_data(kk),
                kk=kk-1;
            end
        end
    end
end

%get the correct interpolation
y_interp_correct = interp1(x_data, y_data, qp);

%plot both solutions to show the difference
figure;
plot(y_interp,'displayname','manual-solution'); hold on;
plot(y_interp_correct,'k--','displayname','matlab solution');
leg1 = legend('show');
set(leg1,'Location','Best');
ylabel('interpolated points');
xlabel('query points');
下面是显示我的实现不正确的图:-(


有人能帮我找到错误的地方吗?为什么?我怀疑这与确保查询点位于上一个和当前x样本之间有关,但我不确定。

代码中的问题是,您有时调用
myInterp
,值
qpi
超出
x\u数据的范围(kk-1)
x_数据(kk)
。这会导致无效的外推结果

你在
kk
上循环而不是
cc
的逻辑让我很困惑。我会为
cc
上循环写一个简单的
,这是你想要插值的点。对于这些点中的每一个,如果需要,前进
kk
,这样
qp(cc)
就在
x_数据(kk)之间
x_数据(kk+1)
(如果愿意,您可以使用
kk-1
kk
,只需初始化
kk=2
以确保
kk-1
存在,我发现从
kk=1开始更直观)


为了简化这里的逻辑,我将
qp
中的值限制在
x_数据
的范围内,这样我们就不需要进行测试来确保
x_数据(kk+1)
存在,也不必确保
x_数据(1)请包括
x_数据
y_数据
qp
的示例数据。对不起,您是要求我上传数据,还是只打印数据?在脚本中提供示例数据,而不是作为单独的文件。您甚至可以执行
x_数据=1:10;y_数据=randn(1,10)
或类似的内容。让我们更容易地重现您的问题。请参阅。明白了--我添加了一个x_数据和y_数据的快速模拟,以使问题重现。请注意,x_数据和qp(在代码中也定义为qp=[1:100])确实是单调递增的,这就是我认为您之前所问的问题?
function yi = myInterp(x1, x2, y1, y2, qp)
%linearly interpolate the function value y(x) over the query point qp
yi = y1 + (qp-x1) * ( (y2-y1)/(x2-x1) );
end