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

发布于 2024-08-30 03:37:39 字数 217 浏览 4 评论 0原文

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

我知道我可以在 O(N log N) 中对特征值进行排序代码>通过std::sort。如果不滚动我自己的排序算法,如何确保矩阵的列(关联的特征向量)在后者排序时遵循其特征值?

I have an unsorted vector of eigenvalues and a related matrix of eigenvectors. I'd like to sort the columns of the matrix with respect to the sorted set of eigenvalues. (e.g., if eigenvalue[3] moves to eigenvalue[2], I want column 3 of the eigenvector matrix to move over to column 2.)

I know I can sort the eigenvalues in O(N log N) via std::sort. Without rolling my own sorting algorithm, how do I make sure the matrix's columns (the associated eigenvectors) follow along with their eigenvalues as the latter are sorted?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

披肩女神 2024-09-06 03:37:39

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

struct eigen { 
    int value;
    double *vector;

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

或者,只需将特征值/特征向量放入 std::pair 中 - 尽管我更喜欢 eigen.valueeigen.vector 超过 something.firstsomething.second

Typically just create a structure something like this:

struct eigen { 
    int value;
    double *vector;

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

Alternatively, just put the eigenvalue/eigenvector into an std::pair -- though I'd prefer eigen.value and eigen.vector over something.first and something.second.

尐偏执 2024-09-06 03:37:39

我已经在不同情况下多次这样做过。无需对数组进行排序,只需创建一个包含已排序索引的新数组即可。

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

然后,您不是以 evals[i] 的形式访问 evals,而是以 evals[index[i]] 的形式访问它,并且以 evects[index[i]][j] 的形式访问它,而不是 evects[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 将位于索引 [i] 处,并且对应于第索引 [i] 个 evect。

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

I've done this a number of times in different situations. Rather than sorting the array, just create a new array that has the sorted indices in it.

For example, you have a length n array (vector) evals, and a 2d nxn array evects. Create a new array index that has contains the values [0, n-1].

Then rather than accessing evals as evals[i], you access it as evals[index[i]] and instead of evects[i][j], you access it evects[index[i]][j].

Now you write your sort routine to sort the index array rather than the evals array, so instead of index looking like {0, 1, 2, ... , n-1}, the value in the index array will be in increasing order of the values in the evals array.

So after sorting, if you do this:

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

you'll get a sorted list of evals.

this way you can sort anything that's associated with that evals array without actually moving memory around. This is important when n gets large, you don't want to be moving around the columns of the evects matrix.

basically the i'th smallest eval will be located at index[i] and that corresponds to the index[i]th evect.

Edited to add. Here's a sort function that I've written to work with std::sort to do what I just said:

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];
    }
};
苄①跕圉湢 2024-09-06 03:37:39

该解决方案完全取决于您存储特征向量矩阵的方式。

如果您可以实现swap(evector1, evector2),以便它仅重新绑定指针而实际数据保持不变,则可以在排序时实现最佳性能。

这可以使用诸如 double* 或更复杂的东西来完成,具体取决于您的矩阵实现。

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

The solution purely relies on the way you store your eigenvector matrix.

The best performance while sorting will be achieved if you can implement swap(evector1, evector2) so that it only rebinds the pointers and the real data is left unchanged.

This could be done using something like double* or probably something more complicated, depends on your matrix implementation.

If done this way, swap(...) wouldn't affect your sorting operation performance.

伊面 2024-09-06 03:37:39

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

The idea of conglomerating your vector and matrix is probably the best way to do it in C++. I am thinking about how I would do it in R and seeing if that can be translated to C++. In R it's very easy, simply evec<-evec[,order(eval)]. Unfortunately, I don't know of any built in way to perform the order() operation in C++. Perhaps someone else does, in which case this could be done in a similar way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文