通过其特征值(相关排序)对特征向量进行分类
-
30-09-2019 - |
题
我有一个未分类的特征值和特征向量矩阵的载体。我想根据分类的特征值集对矩阵的列进行排序。 (例如,如果特征值[3]移至特征值[2],我希望特征值矩阵的第3列移至第2列。)
我知道我可以在 O(N log N)
通过 std::sort
. 。如果不滚动我自己的排序算法,我如何确保矩阵的列(相关的特征向量)随着他们的特征值而在后者进行分类时跟随其特征值?
解决方案
通常只是创建这样的结构:
struct eigen {
int value;
double *vector;
bool operator<(eigen const &other) const {
return value < other.value;
}
};
另外,只需将特征值/特征向量放入 std::pair
- 虽然我喜欢 eigen.value
和 eigen.vector
超过 something.first
和 something.second
.
其他提示
在不同情况下,我已经多次做到这一点。而不是对数组进行排序,而只需创建一个带有排序索引的新数组即可。
例如,您有一个长度n数组(向量)evals,而2D NXN数组的Evects。创建一个包含值[0,n-1]的新数组索引。
然后,您没有以evals [i]访问evals,而是作为evals [index [i]]访问它,而不是Exects [i] [j],而是访问它的Evects [index [i] [j] [j]。
现在您编写排序程序以对索引数组进行排序,而不是evals数组,因此索引中的索引数组中的值将以越来越多evals数组中的值。
因此,在排序之后,如果您这样做:
for (int i=0;i<n;++i)
{
cout << evals[index[i]] << endl;
}
您将获得一个排序的Evals列表。
这样,您可以对与Evals数组相关的任何内容进行整理,而无需实际移动内存。当n变大时,这很重要,您不想在Evects矩阵的列周围移动。
基本上,最小的评估将位于索引[i],这对应于索引[i] exect。
编辑要添加。这是我为与STD ::合作的一种类别函数来做我刚才说的事情:
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];
}
};
该解决方案纯粹依赖于您存储特征向量矩阵的方式。
如果您可以实施,将实现排序时最好的性能 swap(evector1, evector2)
这样它只会重新定位指针,而真实数据则保持不变。
这可以使用类似 double*
或可能更复杂的东西取决于您的矩阵实现。
如果这样做, swap(...)
不会影响您的排序操作性能。
在C ++中进行企业和矩阵的结合的想法可能是完成此操作的最佳方法。我正在考虑如何在R中做到这一点,看看是否可以将其翻译成C ++。在r中非常容易,简单地evec <-evec [,order(eval)]。不幸的是,我不知道在C ++中执行Order()操作的内置方式。也许其他人会这样做,在这种情况下,这可以以类似的方式完成。