2010-04-21 222 views
4

我有一個未排序的特徵向量和特徵向量矩陣。我想對排序的特徵值集合對矩陣的列進行排序。 (例如,如果特徵值[3]移動到特徵值[2],我想特徵向量矩陣的列3移動到列2.)按特徵值排序特徵向量(相關排序)

我知道我可以通過std::sort排序O(N log N)的特徵值。如果沒有滾動我自己的排序算法,我如何確定矩陣的列(相關的特徵向量)以及它們的特徵值,因爲後者是排序的?

回答

7

通常只需要創建一個結構是這樣的:

struct eigen { 
    int value; 
    double *vector; 

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

或者,只是把特徵值/特徵向量爲std::pair - 儘管我寧願eigen.valueeigen.vectorsomething.firstsomething.second

+0

+1指出std :: pair技巧。 – ypnos 2010-04-21 21:24:11

+0

@Jerry:這是一個可靠的解決方案。我唯一的想法是看看我是否可以做相關的排序,而不必在向量/矩陣和排序結構(對)之間來回複製數據,因爲我需要以矩陣形式排序的特徵向量。不過,我要從這開始,謝謝。 – fbrereto 2010-04-21 21:31:18

+0

@fbrereto:你可能更喜歡這樣排序,然後(如果你必須)重新排列數據到最終訂單。在排序過程中交換完整的特徵向量可能會比提取這些特徵向量更慢,排序,然後將特徵向量重新排列爲最終順序。 – 2010-04-21 21:43:25

0

該解決方案完全依賴於存儲您的特徵向量矩陣的方式。

如果您可以實現swap(evector1, evector2),則可以實現排序時的最佳性能,以便僅重新綁定指針並保持實際數據不變。

這可以使用類似double*或可能更復雜的東西來完成,取決於您的矩陣實現。

如果以這種方式完成,swap(...)不會影響您的分類操作性能。

0

聚合你的向量和矩陣的想法可能是在C++中完成它的最好方法。我正在考慮如何在R中做這件事,看看它是否可以轉換爲C++。在R中,它非常簡單,只需簡單地將evec < -evec [,order(eval)]。不幸的是,我不知道在C++中執行order()操作的內置方式。也許別人會這樣做,在這種情況下,這可以用類似的方式完成。

2

我在不同的情況下做了很多次。而不是排序數組,只需創建一個新的數組,其中有排序的索引。

例如,您有一個長度爲n的數組(矢量)evals,並且一個2d nxn數組會相隔。創建一個包含值[0,n-1]的新數組索引。

然後,您不是通過訪問evals [i],而是將它作爲evals [index]訪問,而不是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的排序列表。

通過這種方式,您可以排序與evals數組關聯的任何內容,而無需實際移動內存。當n變大時,這是很重要的,你不想在矩陣的矩陣列上移動。

基本上,第i個最小的eval將位於索引[i]處並且對應於索引[i] thve。

編輯添加。這裏有一個我用std :: sort編寫的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]; 
    } 
}; 
+0

有趣;感謝你的回答。 – fbrereto 2010-04-21 22:46:09