1

私はC++を使用して、いくつかのタスクのROOTスクリプトを記述しています。ある時点で、多くが非常に似ていて、1つまたは2つが異なるdoubleの配列があります。親指の痛みを除いて、すべての数を平均したいと思います。どのようにアプローチすればよいですか?例として、次のことを考えてみましょう。

x = [2.3, 2.4, 2.11, 10.5, 1.9, 2.2, 11.2, 2.1]

10.511.2、異なるものを除いて、どういうわけかすべての数を平均したいと思います。このアルゴリズムは数千回繰り返され、doubleの配列には2000のエントリがあるため、(読みやすさを維持しながら)最適化が望まれます。ありがとうSO!

チェックアウト: http ://tinypic.com/r/111p0ya/3 パルスのy値の「異なる」数。

波形のグランド値を決定するためのこのポイント。私は最も負の値を地面と比較しており、サンプルの最初のNポイントを平均するよりも優れた接地方法が得られることを望んでいます。

4

6 に答える 6

1

可能であれば、ソートされたリストを維持してください。そうすれば、平均を計算するたびに、リストの先頭と末尾を簡単に切り取ることができます。

これは、中央値に基づいて外れ値を削除するのとよく似ています(つまり、中央値を見つけるために1つ、浮動小数点データの並べ替えとほぼ同じくらい遅い、もう1つは平均を計算するために、データを2回パスする必要があります) 、ただし、ソートされたリストを維持することを犠牲にして、平均を計算するときに必要なオーバーヘッドが少なくなります。どちらが最速かは、状況によって異なります。もちろん、あなたが本当に欲しいのはとにかく中央値であるかもしれません!

個別のデータ(たとえば、bytes = 256の可能な値)がある場合は、256のヒストグラムの「ビン」を使用してデータを1回パスし、各ビンに入る値をカウントすると、中央値/概算値を簡単に見つけることができます。平均/外れ値の削除など。データの精度をいくらか失う余裕がある場合は、これが私の推奨オプションであり、データに適している場合は、並べ替えられたリストを維持します。

于 2009-07-31T07:18:29.303 に答える
1

ROOT を使用していることを考えるとTSpectrum、不特定数のピークの下からバックグラウンドを抽出することをサポートするクラスを検討することを検討してください...

ベースライン ノイズが多い環境で使用したことはありませんが、堅牢なはずです。

ところで:このデータのソースは何ですか。ピークは粒子検出器のパルスのように見えますが、高レベルのバックグラウンド ジッターは、難しいソフトウェアの問題を解決しようとするよりも、DAQ ハードウェアをかなり微調整することで実際に改善できる可能性があることを示唆しています。

最後に、非常に原始的なハードウェアに制限されていない限り (その場合、なぜ、どのように ROOT を実行しているのですか?)、そのようなスペクトルが数千しかない場合は、かなり遅いアルゴリズムを使用できます。それとも、イベントごとに 2000 のスペクトルと高いイベント レートですか?

于 2009-07-31T01:44:39.023 に答える
0

手っ取り早い方法は、中央値を取得してから、中央値からそれほど離れていない数の平均を取得することです。

あなたのプロジェクトに依存しているので、「そう遠くない」。

于 2009-07-31T00:23:39.303 に答える
0

外れ値の可能性を判断するための経験則として、四分位範囲 (IQR)を計算すると、最も近い四分位数から 1.5*IQR 離れた値が外れ値になります。

これは、多くの統計システム (R など) が外れ値を自動的に検出するために使用する基本的な方法です。

于 2009-07-31T00:26:47.090 に答える
0

統計的に有意であり、それに近づくための良い方法 (Dark Eru、Daniel White) は、計算量が多すぎて繰り返すことができません。接地)。

提案をありがとう。時間があれば調べて、速度を落とす価値があるかどうかを確認したいと思います。

于 2009-07-31T00:40:56.953 に答える
0

これは、私が以前に使用した手っ取り早い汚い方法です (最初に異常値がほとんどなく、異常値を構成する条件が非常に複雑でない場合にうまく機能します)。

アルゴリズムは O(N) です。本当に高価な部分は分割だけです。

ここでの本当の利点は、数分で起動して実行できることです。

avgX = Array[0]  // initialize array with the first point
N = length(Array)
percentDeviation = 0.3  // percent deviation acceptable for non-outliers
count = 1
foreach x in Array[1..N-1]
    if      x < avgX + avgX*percentDeviation
       and  x > avgX - avgX*percentDeviation
          count++
          sumX =+ x
          avgX = sumX / count
    endif
endfor

return avgX
于 2009-07-31T00:53:50.850 に答える