代码之家  ›  专栏  ›  技术社区  ›  fbrereto

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

  •  4
  • fbrereto  · 技术社区  · 15 年前

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

    我知道我可以把特征值分类 O(N log N) 通过 std::sort . 在不使用我自己的排序算法的情况下,当矩阵的列(相关的特征向量)被排序时,如何确保它们的特征值跟在后面?

    4 回复  |  直到 15 年前
        1
  •  7
  •   Jerry Coffin    15 年前

    通常只需创建如下结构:

    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 .

        2
  •  2
  •   miked    15 年前

    我在不同的情况下做过很多次。与其对数组进行排序,不如创建一个包含排序索引的新数组。

    例如,有一个长度n数组(向量)求值和一个2d nxn数组evects。创建包含值[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矩阵的列周围移动。

    基本上,第i个最小的eval将位于索引[i]处,并且对应于索引[i]的evect。

    编辑以添加。这是我编写的一个函数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];
        }
    };
    
        3
  •  0
  •   M. Williams    15 年前

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

    如果您能够实现 swap(evector1, evector2) 这样它只重新绑定指针,而实际数据保持不变。

    这可以用类似于 double* 或者更复杂的事情,取决于矩阵的实现。

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

        4
  •  0
  •   frankc    15 年前

    在C++中使用向量和矩阵的方法可能是最好的方法。我在考虑如何在R中做它,看看它是否可以翻译成C++。在r中,很简单,evec<-evec[,order(eval)].不幸的是,我不知道有什么内置的方式来执行C++中的Ord()操作。也许其他人会这样做,在这种情况下,也可以用类似的方式来做。

    推荐文章