4

ソートされていない固有値のベクトルと関連する固有ベクトルの行列があります。ソートされた固有値のセットに関して、行列の列をソートしたいと思います。(たとえば、eigenvalue[3]がeigenvalue[2]に移動する場合、固有ベクトル行列の列3を列2に移動する必要があります。)

O(N log N)を介して固有値を並べ替えることができることはわかっていstd::sortます。独自の並べ替えアルゴリズムを使用せずに、行列の列(関連する固有ベクトル)が固有値に沿って並べ替えられるようにするにはどうすればよいですか?

4

4 に答える 4

7

通常、次のような構造を作成するだけです。

struct eigen { 
    int value;
    double *vector;

    bool operator<(eigen const &other) const { 
        return value < other.value;
    }
};

または、固有値/固有ベクトルをstd::pair--に入れますが、 eigen.valueandeigen.vectorよりsomething.firstsomething.second.

于 2010-04-21T21:15:54.893 に答える
2

私はこれをさまざまな状況で何度も行ってきました。配列をソートするのではなく、ソートされたインデックスを持つ新しい配列を作成するだけです。

たとえば、長さ n の配列 (ベクトル) evals と 2d nxn 配列 evects があるとします。値 [0, n-1] を含む新しい配列インデックスを作成します。

次に、evals[i] として evals にアクセスするのではなく、evals[index[i]] としてアクセスし、evects[i][j] の代わりに、evects[index[i]][j] としてアクセスします。

ここで、evals 配列ではなくインデックス配列をソートするソート ルーチンを記述します。したがって、インデックスが {0, 1, 2, ... , n-1} のように見えるのではなく、インデックス配列の値が昇順になります。 evals 配列の値の。

したがって、並べ替えた後、これを行うと:

for (int i=0;i<n;++i)
{
  cout << evals[index[i]] << endl;
}

評価のソートされたリストが得られます。

このようにして、実際にメモリを移動することなく、その evals 配列に関連付けられているものを並べ替えることができます。これは n が大きくなった場合に重要です。これは、evects 行列の列を移動したくない場合に重要です。

基本的に、i 番目に小さい eval は index[i] に配置され、index[i] 番目のイベントに対応します。

追加するように編集しました。これは、std::sort と連携して、今言ったことを実行するために作成したソート関数です。

template <class DataType, class IndexType>
class SortIndicesInc
{
protected:
    DataType* mData;
public:
    SortIndicesInc(DataType* Data) : mData(Data) {}
    Bool operator()(const IndexType& i, const IndexType& j) const
    {
        return mData[i]<mData[j];
    }
};
于 2010-04-21T22:26:15.530 に答える
0

ソリューションは、固有ベクトル行列を格納する方法に完全に依存しています。

swap(evector1, evector2)ポインタのみを再バインドし、実際のデータは変更しないように実装できれば、並べ替え中の最高のパフォーマンスが得られます。

これはdouble*、マトリックスの実装に応じて、次のようなもの、またはおそらくもっと複雑なものを使用して実行できます。

このようにswap(...)しても、ソート操作のパフォーマンスには影響しません。

于 2010-04-21T21:49:31.037 に答える
0

ベクトルと行列をまとめるという考えは、おそらく C++ でそれを行うための最良の方法です。Rでどのように行うかを考えており、それがC ++に変換できるかどうかを確認しています。R では非常に簡単で、単に evec<-evec[,order(eval)] です。残念ながら、C++ で order() 操作を実行する組み込みの方法を知りません。おそらく他の誰かがそうするでしょう。その場合、これは同様の方法で行うことができます。

于 2010-04-21T22:03:45.400 に答える