2017-08-22 10 views
2

データをエクスポートする際、関連するデータポイントのみをエクスポートします。したがって、グラフが直線の場合、非常にノイズの多い信号と比較してデータポイントが少なくなるはずです。MATLABから「関連」データのみをエクスポートします

機能が同時に3点で見ているとlinar回帰を作るのアレイを通過します:

私はすでにユーザー作られた機能について従う考えを作っ私の問題を解決する何の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); 
+0

あなたは信号がゆっくり変化しているときを決定するために、信号の導関数を使用することができ、そしてそれらの部品アンダーサンプル。コードを使って 'd = abs(diff(y)./ diff(x));'を試してみてください。 – Zep

+0

私もこの考え方を持っていましたが、データをフィルタリングすることは、データポイントが適切かどうかを判断しないという難しい部分です。少なくとも私の意見では。 –

+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

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

+0

いいですね。いくつのデータポイントで終わったのですか? –

+0

変更可能なパラメータ 'linRatioToChange'と' numInds2Skip'に依存します。上記は675で、1000から減少しました。 –

+0

それほど多くはありません。あなたが線形的に675のデータポイントを使用するなら、あなたはおそらくより良い結果を得るでしょう。 (Btwは同じ考えをして同じ結果になった)。 –

関連する問題