简体   繁体   English

C ++:如何根据复杂向量的实部对复杂矩阵进行排序

[英]C++: how to sort a complex matrix based on real parts of a complex vector

I have a complex vector ( VSII_Complex containing Eigen values) and a complex matrix ( CUII_Complex containing Eigen vectors). 我有一个复杂的向量(包含特征值的VSII_Complex )和一个复杂的矩阵(包含特征向量的CUII_Complex )。 Each element of VSII_Complex is corresponding to a column of CUII_Complex . VSII_Complex每个元素都对应于CUII_Complex一列。 My problem is that I want to sort the Eigen values inside VSII_Complex based on their real part (NOT imaginary part) and I will have to sort the columns of CUII_Complex according to the sorted VSII_Complex . 我的问题是我想根据VSII_Complex的本征值的实部(不是虚部)进行排序,并且我将不得不根据排序后的VSII_ComplexCUII_Complex的列进行排序。 The following code is developed by my friend but I feel like something is wrong with this code but I cannot figure it out. 以下代码是由我的朋友开发的,但是我觉得这段代码有问题,但是我无法弄清楚。 I wonder if anybody can tell what is wrong if any. 我想知道是否有人可以告诉我哪里出了问题。

EIG eigA=EIG(m_IIStiffnessAct,m_IIMassAct,true);
    ComplexColumnVector VSII_Complex=eigA.eigenvalues();
    ComplexMatrix CUII_Complex=eigA.eigenvectors();
///// make eigenvalues in decreasing order, so do eigenvectors
    for (long ii = 0; ii < VSII_Complex.rows(); ii++)
    {
        for (long jj = ii+1; jj < VSII_Complex.rows(); jj++)
        {
          if (VSII_Complex(ii).real() < VSII_Complex(jj).real())
          {
              Complex temp = VSII_Complex(ii);
              VSII_Complex(ii) = VSII_Complex(jj);
              VSII_Complex(jj) = temp;             
              for (long kk = 0; kk < CUII_Complex.rows(); kk++)
              {
                  Complex tempVec =  CUII_Complex(kk,ii);
                  CUII_Complex(kk,ii) = CUII_Complex(kk,jj);
                  CUII_Complex(kk,jj) = tempVec;
              }
          }
        }
    }

Just use the build-in sort that returns the position that the element was in previously. 只需使用返回元素先前所在位置的内置排序即可。

//couldn't find this in the docs, I'm overlooking something probably:
void swapColumns (ComplexMatrix &mat, octave_idx_type colA, octave_idx_type colB)
{
    if(colA == colB) return;
    ComplexColumnVector temp = mat.column(colA);
    mat.insert(mat.column(colB),0,colA);
    mat.insert(temp,0,colB);
}


bool isRealGreater(const Complex& a, const Complex& b)
{
    return a.real() > b.real();
}

//presumably in another function
//int func() {
    EIG eigA=EIG(m_IIStiffnessAct,m_IIMassAct,true);

    ComplexColumnVector VSII_Complex=eigA.eigenvalues();
    ComplexMatrix CUII_Complex=eigA.eigenvectors();
///// make eigenvalues in decreasing order, so do eigenvectors

    //create indices from 1-len(VSII_Complex)
    Array<octave_idx_type> sort_order(VSII_Complex.length(),0);
    for(int i =0 ; i< sort_order.length(); i++)
    {sort_order.elem(i)= i;}

    //create sorting object and sort VSII_Complex in descending order of the real component
    octave_sort<Complex> sort_obj(&isRealGreater);
    sort_obj.sort(VSII_Complex.jit_slice_data(), sort_order.jit_slice_data(), VSII_Complex.length());

    //swap the columns of CUII_Complex in the same way VSII_Complex got sorted
    for(octave_idx_type i=0; i<sort_order.length(); i++)
    {
        if(sort_order.elem(i) > i)
        {
            swapColumns(CUII_Complex,i,sort_order.elem(i));
        }
    }

//}

Haven't actually tested this, because I was too lazy to install octave, I just read the docs. 尚未实际测试,因为我懒得安装八度,所以我只看了文档。

I solved the problem with the following code, I developed this code based on the algorithm in the following webpage. 我用以下代码解决了这个问题,我根据以下网页中的算法开发了此代码。 But the answer of PeterT looks better to me. 但是PeterT的答案对我来说看起来更好。

http://www.learncpp.com/cpp-tutorial/64-sorting-an-array-using-selection-sort/ http://www.learncpp.com/cpp-tutorial/64-sorting-an-array-using-selection-sort/

///// make eigenvalues in decreasing order, so do eigenvectors
    ComplexColumnVector ComplexColumnVector_toBesSorted=VSII_Complex;
    ComplexMatrix ComplexMatrix_toBeSorted=CUII_Complex;
    for (long idx_start = 0; idx_start < ComplexColumnVector_toBesSorted.rows(); idx_start++)
    {
        long idx_smallest=idx_start;
        for (long idx_current = idx_start+1; idx_current < ComplexColumnVector_toBesSorted.rows(); idx_current++)
        {
          if (ComplexColumnVector_toBesSorted(idx_current).real() < ComplexColumnVector_toBesSorted(idx_smallest).real())
              idx_smallest=idx_current;
        }
        Complex Complex_temp=ComplexColumnVector_toBesSorted(idx_start);
        ComplexColumnVector_toBesSorted(idx_start)=ComplexColumnVector_toBesSorted(idx_smallest);
        ComplexColumnVector_toBesSorted(idx_smallest)=Complex_temp;
        for (long kk = 0; kk < ComplexMatrix_toBeSorted.rows(); kk++)
        {
            Complex Complex_temp_2 =  ComplexMatrix_toBeSorted(kk,idx_start);
            ComplexMatrix_toBeSorted(kk,idx_start) = ComplexMatrix_toBeSorted(kk,idx_smallest);
            ComplexMatrix_toBeSorted(kk,idx_smallest) = Complex_temp_2;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM