1

信号の総エネルギーを計算するために、次の式が与えられました。

Ex= ∑ n|x[n]|2 

これは、各ブロックを二乗してから、ブロック全体の合計を取得することをお勧めします。私が書いたコード/アルゴリズムがこの式に対して正確であるかどうか疑問に思っており、最も効率的な方法でそれを行いました。

double totalEnergy(vector<double> data, const int rows, const int cols)
{
vector<double> temp;
double energy = 0;

for(int i=0; (i < 2); i++)
{
    for(int j=0; (j < 2); j++)
    {
        temp.push_back( (data[i*2+j]*data[i*2+j]) );
    }
}

energy = accumulate (temp.begin(), temp.begin()+(rows*cols), 0);
return energy;
 }
 int main(int argc, char *argv[]) {

vector<double> data;
data.push_back(4);
data.push_back(4);

data.push_back(4);
data.push_back(4);

totalEnergy(data, 2, 2);

 }

結果: 64

どんな助け/アドバイスも大歓迎です:)!

4

1 に答える 1

2

実装はほぼ正しいと思いますが、これは確かにこの計算を行うための最も効率的な方法ではありません。ただし、乗算はnどういうわけか失われました。合計インデックスと境界がわからないので、これを修正するつもりはありませんが、実装の結果を「より良い」ものとして再現します。改善できる明らかなポイントが2つあります。

  1. このコードは、特定の列または行にあることを利用していません。つまり、入力を、入力ベクトルのサイズから実際にサイズがわかっているフラットな配列と見なすこともできます。
  2. 関数は2つの一時ベクトルを使用します(1つは関数に渡され、もう1つは関数内に渡されます)。安価std::vector<T>な操作ではないメモリを割り当てる必要があります。

最初の近似として、入力ベクトルをインプレースで変換してから、結果を累積します。

double square(double value) {
    return value * value;
}

double totalEnergy(std::vector<double> data) {
    std::transform(data.begin(), data.end(), data.begin(), &square);
    return std::accumulate (data.begin(), data.end(), 0);
}

この関数は引き続きデータのコピーを作成し、それを変更します。私はこれが好きではありません。奇妙なことに、実装した操作は基本的にベクトルとそれ自体の内積です。つまり、これにより、追加のベクトルを作成しなくても同じ結果が得られます。

double totalEnergy(std::vector<double> const& data) {
    return std::inner_product(data.begin(), data.end(), data.begin(), 0);
}

これが正しい式を実装していると仮定すると(元の式ではまだ疑わしいですがn)、これはおそらくかなり高速です。それももっと簡潔なようです...

于 2012-09-22T23:37:23.397 に答える