2017-02-20 1 views
2

QR Factorization을위한 코드를 작성하고 있으며 어떤 이유로 내 직교 방식이 의도 한대로 작동하지 않습니다. 기본적으로, 내 proj() 메서드는 임의의 투영을 출력하고 있습니다. 코드는 다음과 같습니다.QR의 직교 화 약간 부정확 한 직교 화 된 행렬을 출력합니다.

apmatrix<double> proj(apmatrix<double> v, apmatrix<double> u) 
//Projection of u onto v 
{ 
//proj(v,u) = [(u dot v)/(v dot v)]*v 
    double a = mult(transpose(u,u),v)[0][0], b = mult(transpose(v,v),v)[0][0], c = (a/b); 
    apmatrix<double>k; 
    k.resize(v.numrows(),v.numcols()); 
    for(int i = 0; i<v.numrows(); i++) 
    { 
     for(int j = 0; j<v.numcols(); j++) 
     { 
      k[i][j]=v[i][j]*c; 
     } 
    } 
    return k; 
} 

수동 매트릭스 입력으로이 메소드를 테스트 한 결과 제대로 작동하는 것 같습니다. I는 2D 배열 사용 된 테스트 목적

apmatrix<double> orthogonal(apmatrix<double> A) //Orthogonal 
{ 
    /* 
    n = (number of columns of A)-1 
    x = columns of A 
    v0 = x0 
    v1 = x1 - proj(v0,x1) 
    vn = xn - proj(v0,xn) - proj(v1,xn) - ... - proj(v(n-1),xn) 
    V = {v1, v2, ..., vn} or [v0 v1 ... vn] 
    */ 
    apmatrix<double> V, x, v; 
    int n = A.numcols(); 
    V.resize(A.numrows(),n); 
    x.resize(A.numrows(), 1); 
    v.resize(A.numrows(),1); 
    for(int i = 0; i<A.numrows(); i++) 
    { 
     x[i][0]=A[i][1]; 
     v[i][0]=A[i][0]; 
     V[i][0]=A[i][0]; 
    } 
    for (int c = 1; c<n; c++) //Iterates through each col of A as if each was its own matrix 
    { 
     apmatrix<double>vn,vc; //vn = Orthogonalized v (avoiding matrix overwriting of v); vc = previously orthogonalized v 
      vn=x; 
     vc.resize(v.numrows(), 1); 
     for(int i=0; i<c; i++) //Vn = an-(sigma(t=1, n-1, proj(vt, xn)) 
     { 
      for(int k = 0; k<V.numrows(); k++) 
       vc[k][0] = V[k][i]; //Sets vc to designated v matrix 
      apmatrix<double>temp = proj(vc, x); 
      for(int j = 0; j<A.numrows(); j++) 
      { 
       vn[j][0]-=temp[j][0]; //orthogonalize matrix 
      } 
     } 
     for(int k = 0; k<V.numrows(); k++) 
     { 
      V[k][c]=vn[k][0]; //Subtracts orthogonalized col to V 
      v[k][0]=V[k][c]; //v is redundant. more of a placeholder 
     } 
     if((c+1)<A.numcols()) //Matrix Out of Bounds Checker 
     { 
      for(int k = 0; k<A.numrows(); k++) 
      { 
       vn[k][0]=0; 
       vc[k][0]=0; 
       x[k][0]=A[k][c+1]; //Moves x onto next v 
      } 
     } 
    } 
    system("PAUSE"); 
    return V; 
} 

: 여기 내 직교하는 방법이다 [1,1,4], [1,4,2-], [1,4,2-]를 [1,1,0]]. 각 열은 고유 한 4x1 행렬입니다. 행렬은 [1,1,1,1] T, [-1.5,1.5,1.5, -1.5] T 및 [2,0,0, -2] T와 같이 출력되어야합니다. 현재 일어나고있는 일은 첫 번째 열이 올바르게 나오고 (같은 행렬입니다.) 두 번째와 세 번째 열은 잠재적으로 비슷하지만 의도 한 값과 같지 않은 것으로 나옵니다.

다시 말해 직교 방식을 호출 할 때마다 다른 결과가 출력됩니다. proj() 메서드에 입력 된 숫자 때문인 것으로 생각되지만 완전히 확신 할 수는 없습니다.

apmatrix는 AP 대학 보드에서 나 왔으며 cpp를 가르쳤습니다. Java의 Vector 또는 ArrayList와 유사합니다.

Here은 apmatrix.cpp 및 문서 또는 조건 (아마도 더 유용) 인 apmatrix.h에 대한 링크입니다. Here은 전체 코드에 대한 링크입니다 (컴퓨터에서 수행중인 작업을 확인하기 위해 시각적 표시자를 추가했습니다).

모든 사용자 지정 방법이 의도 한대로 작동한다고 가정하는 것이 타당합니다 (단, 행렬 회귀는 제외하지만 이는 무의미 함). 그리고 factorize하기 전에 enter 메서드를 사용하여 행렬에 들어가야합니다. 너무 오래 전 cpp를 스스로 가르쳤고 코드를 수정하기 위해 여러 가지 방법을 시도해 왔기 때문에 부분적으로 코드가 비효율적 일 수 있습니다. 도와 주셔서 감사합니다!

+0

값을 어떻게 다르게해야하나요? –

+0

@AhmedFasih 각 요소는 항상 의도 한 값의 + -1 이내입니다. 첫 번째 행렬에 대해 [-1, 2, 2, -1] T와 [2.8, -1, -1, 1.2] T가 반환되었습니다. 때로는 두 번째 매트릭스가 실제로 올바른 값입니다. 또한 두 번째 행렬에있는 모든 요소의 합계가 원하는 행렬의 합계와 같습니다. 세 번째 행렬은 요소 중 두 개가 0이어야한다는 것을 제외하고는 마찬가지입니다. – Rickbox

+0

숫자 라운드 오프 오류가 아니라면 알고리즘이 완전히 결정적이지만 표시되는 버퍼 오버런 또는 메모리 액세스 유형 문제가 의심됩니다. 무작위 출력. valgrind 또는 Clang의 소독제를 통해 넣어? –

답변

0

으로는 설명했다 :

@AhmedFasih 오늘 더 많은 테스트를 수행 한 후, 나는 그것이에 - 사실 일부> 메모리 문제가 있음을 발견했다. 어떤 이유로 변수 또는 apmatrix 객체가 루프 내에서 선언되고 초기화 된 다음 해당 루프가 반복되어 메모리가 해당 변수 또는 객체에 저장된 값을 완전히 지우지는 않는 것으로 나타났습니다. 이것은> 내 코드의 두 부분에 기록되어 있습니다. 어떤 이유로 든 double> a, b 및 c를 proj 메소드에서 0으로 설정하고 apmatrixdh를 0보다 큰 값으로 설정해야합니다. 그렇지 않으면 다음 반복에서 일부 값을 저장하게됩니다. 고맙습니다.> 많은 도움을!