按特征值对特征向量进行排序(相关排序)

时间:2010-04-21 21:03:28

标签: c++ sorting eigenvector eigenvalue associated-sorting

我有一个未排序的特征值向量和一个相关的特征向量矩阵。我想根据排序的特征值集对矩阵的列进行排序。 (例如,如果特征值[3]移动到特征值[2],我希望特征向量矩阵的第3列移到第2列。)

我知道我可以通过O(N log N)std::sort中的特征值进行排序。如果不滚动我自己的排序算法,我如何确保矩阵的列(相关的特征向量)跟随它们的特征值,因为后者是排序的?

4 个答案:

答案 0 :(得分:7)

通常只需创建一个类似这样的结构:

struct eigen { 
    int value;
    double *vector;

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

或者,只需将特征值/特征向量放入std::pair - 但我更喜欢eigen.valueeigen.vector而不是something.firstsomething.second。< / p>

答案 1 :(得分:2)

我在不同的情况下做了很多次。而不是对数组进行排序,只需创建一个新的数组,其中包含已排序的索引。

例如,你有一个长度为n的数组(向量)evals,并且有一个2d nxn数组。创建一个包含值[0,n-1]的新数组索引。

然后,不是将evals作为evals [i]访问,而是将其作为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矩阵的列周围移动。

基本上,我最小的eval将位于index [i],并且对应于索引[i] thve。

编辑添加。这是一个排序函数,我已经编写过使用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];
    }
};

答案 2 :(得分:0)

解决方案纯粹依赖于存储特征向量矩阵的方式。

如果您可以实现swap(evector1, evector2)以便它只重新绑定指针并且实际数据保持不变,那么排序时的最佳性能将会实现。

这可以使用像double*这样的东西来完成,或者可能更复杂一些,取决于你的矩阵实现。

如果这样做,swap(...)不会影响您的排序操作性能。

答案 3 :(得分:0)

将矢量和矩阵联合起来的想法可能是在C ++中实现它的最佳方法。我正在考虑如何在R中执行此操作并查看是否可以将其转换为C ++。在R中它非常简单,只需要evec&lt; -evec [,order(eval)]。不幸的是,我不知道在C ++中执行order()操作的任何内置方法。也许其他人也这样做,在这种情况下,这可以用类似的方式完成。