仅从MATLAB导出“相关”数据

时间:2017-08-22 13:52:56

标签: matlab interpolation

导出数据时,我只想导出相关的数据点。因此,当图形是直线时,与非常嘈杂的信号相比,应该有更少的数据点。

当没有MATLAB函数解决我的问题时,我已经对用户制作的函数做了如下思考:

该函数将通过数组同时查看三个点并进行线性回归。如果精度高于某个阈值,则该函数将删除中间点(在原始数组的副本中)。

当我尝试将图形导出到LaTeX并且我检查了数据限制时,问题确实出现了。信号中只有一些我想看到的非常重要的高峰。其余的很直接。

这是一个非常快速的演示脚本,用于可视化问题。对于信号的第一部分,需要更少的点来正确显示信号,但是右侧越多,需要的点越多,这对我的信号没有任何影响。

更新:我自己编写了算法的MVP,其中"工作"。不幸的是,它不适应。因此,如果我改变它抓住的输入点的数量。现在就开始改进它。

Update2:它不起作用。错误就在我身边。仍然显示出这个想法。

clear

x = linspace(0.1,10,1000);

y = sin(x.^2);

hold on

%plot(x,y)

x_new = x;
y_new = y;

for n = 2:999

expected(n) = (y(n+1)-y(n-1))/2+y(n-1);

p(n)=y(n)/expected(n);

if(p(n) > 0.99 && p(n) < 1.01);

del(n)=n;
else
del (n)=1;

end

end 

del (1)=1;

x_new(del) = [];
y_new(del) = [];

plot(x_new,y_new);

2 个答案:

答案 0 :(得分:2)

嗯,这是基于二阶导数阈值的次优尝试:

%Generate test data
x = linspace(0.1,10,1000);
y = sin(x.^2);
hold all;plot(x,y);plot(x,y,'.')
%Params to change
loLim = -1;hiLim = 1;MovWind = 100;
linRatioToChange = 0.6;
numInds2Skip = 4;

rateY = gradient(gradient(y));%Second order derivative, threshold method
rateY_scaled = (rateY-movmin(rateY,MovWind)).*(hiLim-loLim)./(movmax(rateY,MovWind)-movmin(rateY,MovWind)) + loLim; %VERY dubious scaling of derivative

logIdx2Change = abs(rateY_scaled) < linRatioToChange; %apply threshold
%Check interp regions: figure;plot(x,y);hold all;plot(x(logIdx2Change),y(logIdx2Change))
x2Change = x(logIdx2Change); %values to downsample
y2Change=y(logIdx2Change);
newX = x2Change(1:numInds2Skip:end);
newY = interp1(x2Change,y2Change,newX); %Downsample

logIdx2Keep = ~logIdx2Change; %Old values to keep 
x2Keep = x(logIdx2Keep);
y2Keep = y(logIdx2Keep);

[combinedX,sortMap] = sort([x2Keep,newX]); %combine old and downsampled, not perfect but maybe good enough
combinedY = [y2Keep,newY];
combinedY = combinedY(sortMap);

plot(combinedX,combinedY);plot(combinedX,combinedY,'o')

因此,它在信号开始时效果不佳,但后来获得了很好的效果。您可以看到新的紫色数据点跳过检测到的线性区域中的一些原始黄色数据点。

enter image description here

答案 1 :(得分:0)

我实际上找到了一个非常好的解决方案!我的想法来自数字图片分析讲座。结果是找到最大错误并在那里设置数据点的算法。它一直持续到达到最小误差。还可以设置数据点的总量。我打算把它变成一个有几个选项的功能。此技术也可以应用于3D阵列!

请记住,代码根本没有优化,而是第一个工作示例!

enter image description here

clear
clc

x = linspace(0.1,10,1000);
y = sin(x.^2);

rel(1,1) = x(1);
rel(1,2) = x(length(x));
rel(2,1) = y(1);
rel(2,2) = y(length(y));

max_err = 0.1;

while true

    err = abs(interp1(rel(1,:),rel(2,:),x)-y);

    [~,n] = max(err);

    if err(n) < max_err
       break 
    end

    [~,m] = min(abs(x(n)-rel(1,:)));

    rel=    [[rel(1,1:m-1) x(n) rel(1,m:end)];
            [rel(2,1:m-1) y(n) rel(2,m:end)]];

    rel = transpose(sortrows(transpose(rel)));

end


plot(x,y)
hold on
plot(rel(1,:),rel(2,:))
plot(x,err)
hold off
grid on

legend('y','relevant','error')

我还为感兴趣的人创建了一个github回购: https://github.com/JulianWgs/get_relevant_data