2014-11-03 14 views
0

나는 복잡한 벡터 (Eigen 값을 포함하는 VSII_Complex)와 복잡한 행렬 (고유 벡터를 포함하는 CUII_Complex)을 가지고 있습니다. VSII_Complex의 각 요소는 CUII_Complex의 열에 해당합니다. 내 문제는 VSII_Complex 실제 부분 (허수가 아닌 부분)을 기반으로 Eigen 값을 정렬하고 정렬 된 VSII_Complex에 따라 CUII_Complex의 열을 정렬해야합니다. 다음 코드는 내 친구에 의해 개발되었지만이 코드에 문제가있는 것처럼 느껴졌지 만 알아낼 수는 없습니다. 나는 누군가가 무엇이 잘못되었다고 말할 수 있는지 궁금합니다.C++ : 복잡한 벡터의 실수 부분을 기반으로 복잡한 행렬을 정렬하는 방법

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; 
       } 
      } 
     } 
    } 

답변

1

이전에 요소가 있던 위치를 반환하는 빌드 인 정렬을 사용하십시오.

//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)); 
     } 
    } 

//} 

옥타브를 설치하기가 너무 어려웠 기 때문에 실제로 테스트하지 않았습니다. 문서를 읽었습니다.

+0

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

나는 내 대답은 아래에서이 문제에 대한 해결책으로 C++ 코드를 추가했다. 하지만 당신의 해결책은 나에게 잘 어울립니다. – user3405291

+1

이 문제가 해결되어 올바르게 정렬되었습니다. – PeterT

0

다음 코드로 문제를 해결했습니다.이 코드는 다음 웹 페이지의 알고리즘을 기반으로 개발했습니다. 그러나 PeterT의 대답은 나에게 잘 어울립니다.

///// 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; 
     } 
    }