2017-02-20 98 views
2

Я пишу код для QR-факторизации, и по какой-то причине мой ортогональный метод не работает должным образом. В принципе, мой 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; 
} 

Я протестировал метод самостоятельно с помощью ручных матричных входов, и, похоже, он работает нормально. Вот мой ортогональный метод:

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

Для целей тестирования, я использую 2D массива: [[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. Он похож на векторы или ArrayLists в Java.

Here - ссылка на apmatrix.cpp и на документацию или условия (возможно, более полезную), apmatrix.h. Here - это ссылка на полный код (я добавил визуальные маркеры, чтобы увидеть, что делает компьютер).

Справедливо предположить, что все пользовательские методы работают по назначению (за исключением, может быть, матричных регрессий, но это не имеет значения). И не забудьте ввести матрицу, используя метод ввода, прежде чем пытаться разложить факторизацию. Код может быть неэффективным, частично потому, что я сам себя учил cpp не так давно, и я пытался по-другому исправить свой код. Спасибо вам за помощь!

+0

Насколько отличаются значения от того, чем они должны быть? –

+0

@AhmedFasih Каждый элемент всегда находится в пределах + -1 от предполагаемого значения. Одна итерация вернулась: [-1, 2, 2, -1] T для второй матрицы и [2.8, -1, -1, 1.2] T. Иногда вторая матрица фактически является правильными значениями. Также обратите внимание, что сумма всех элементов во второй матрице равна сумме предполагаемой матрицы. Третья матрица будет также, за исключением того, что два из этих элементов должны быть равны 0. – Rickbox

+0

Хорошо, если это не числовые ошибки округления, то я подозреваю, что проблема с переполнением буфера или проблемой доступа к памяти, поскольку алгоритм полностью детерминирован, но показывает случайные выходы. Положите это через valgrind или некоторые из дезинфицирующих средств Клана? –

ответ

0

Как сказано в комментариях:

@AhmedFasih После этого больше испытаний сегодня, я обнаружил, что это в самом деле, некоторые> проблема памяти. Я обнаружил, что по какой-либо причине, если переменная или объект apmatrix> объявлена ​​в цикле, инициализирована, то этот цикл повторяется,> память не полностью уничтожает значение, хранящееся в этой переменной или объекте. Это> отмечено в двух местах моего кода. По какой-то причине мне пришлось установить> удвоения a, b и c в 0 в методе proj и apmatrixdh в 0 в методе> mult или они сохранили бы некоторое значение в следующей итерации. Спасибо вам большое за помощь!