Я пишу код для 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 не так давно, и я пытался по-другому исправить свой код. Спасибо вам за помощь!
Насколько отличаются значения от того, чем они должны быть? –
@AhmedFasih Каждый элемент всегда находится в пределах + -1 от предполагаемого значения. Одна итерация вернулась: [-1, 2, 2, -1] T для второй матрицы и [2.8, -1, -1, 1.2] T. Иногда вторая матрица фактически является правильными значениями. Также обратите внимание, что сумма всех элементов во второй матрице равна сумме предполагаемой матрицы. Третья матрица будет также, за исключением того, что два из этих элементов должны быть равны 0. – Rickbox
Хорошо, если это не числовые ошибки округления, то я подозреваю, что проблема с переполнением буфера или проблемой доступа к памяти, поскольку алгоритм полностью детерминирован, но показывает случайные выходы. Положите это через valgrind или некоторые из дезинфицирующих средств Клана? –