所以我正在尝试建模 Gram-Schmidt对于任何大小的 N×N 矩阵,我正式遇到了无法逾越的障碍。我知道这是正确循环的问题,但我不知道问题出在哪里。请记住,我不想只传入一个 3×3 矩阵,而是任何大小的 N×N。
类(class)笔记 QR Decomposition with Gram-Schmidt 准确地解释了我想做什么。顺便说一下,非常简单的计算。在类(class)笔记中 ||u||表示是元素的平方和,所以 sqrt(x12 + x< sub>22 + x32 + .... + x n2).
乘法符号实际上是点积。
下面列出了我到目前为止编写的代码。有什么问题吗?
function qrProjection(arr) {
var qProjected = [];
var tempArray = [];
var aTemp = arr;
var uTemp = new Array(arr.length);
var uSquareSqrt = new Array(arr.length);
var eTemp = [];
var sum = 0;
var sumOfSquares = 0;
var breakCondition = 0;
var secondBreakCondition = 0;
var iterationCounter = 0;
//Build uTemp Array
for (i = 0; i < arr.length; i++) {
uTemp[i] = new Array(arr[i].length);
}
for (i = 0; i < arr.length; i++) {
eTemp[i] = new Array(arr[i].length);
}
uTemp[0] = aTemp[0];
for (j = 0; j <= arr.length; j++) {
for (l = 0; l < arr[j].length; l++) {
if (breakCondition == 1) break;
sumOfSquares = Math.pow(uTemp[j][l], 2) + sumOfSquares;
}
if (breakCondition == 0) {
uSquareSqrt[j] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
}
for (i = 0; i < arr[j].length; i++) {
if (breakCondition == 1) break;
eTemp[j][i] = (1 / (uSquareSqrt[j])) * (uTemp[j][i]);
}
breakCondition = 1;
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
matrixDotProduct = aTemp[j + 1][m] * eTemp[j][m] + matrixDotProduct;
}
}
else {
for (m = 0; m < arr[j].length; m++) {
for (s = 0; s <= iterationCounter; s++) {
matrixDotProduct = aTemp[j + 1][s] * eTemp[m][s] + matrixDotProduct;
}
for (t = 0; t < arr[j].length; t++) {
uTemp[j + 1][t] = aTemp[j + 1][t] - eTemp[j][t] * matrixDotProduct;
}
}
}
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
uTemp[j + 1][m] = aTemp[j + 1][m] - eTemp[j][m] * matrixDotProduct;
}
}
matrixDotProduct = 0;
for (l = 0; l < arr[j].length; l++) {
sumOfSquares = Math.pow(uTemp[j + 1][l], 2) + sumOfSquares;
}
uSquareSqrt[j + 1] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
for (i = 0; i < arr[j].length; i++) {
eTemp[j + 1][i] = (1 / (uSquareSqrt[j + 1])) * (uTemp[j + 1][i]);
}
iterationCounter++;
}
qProjected = eTemp;
return qProjected;
}
最佳答案
我必须道歉,我没有调整您的代码,而是从头开始编写自己的代码:
/* Main function of interest */
// Each entry of a matrix object represents a column
function gramSchmidt(matrixA, n) {
var totalVectors = matrixA.length;
for (var i = 0; i < totalVectors; i++) {
var tempVector = matrixA[i];
for (var j = 0; j < i; j++) {
var dotProd = dot(matrixA[i], matrixA[j], n);
var toSubtract = multiply(dotProd, matrixA[j], n);
tempVector = subtract(tempVector, toSubtract, n);
}
var nrm = norm(tempVector, n);
matrixA[i] = multiply(1 / nrm, tempVector, n);
}
}
/*
* Example usage:
* var myMatrix = [[1,0,0],[2,3,0],[5,4,7]];
* gramSchmidt(myMatrix, 3);
* ==> myMatrix now equals [[1,0,0],[0,1,0],[0,0,1]]
* 3 here equals the number of dimensions per vector
*/
/* Simple vector arithmetic */
function subtract(vectorX, vectorY, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = vectorX[i] - vectorY[i];
return result;
}
function multiply(scalarC, vectorX, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = scalarC * vectorX[i];
return result;
}
function dot(vectorX, vectorY, n) {
var sum = 0;
for (var i = 0; i < n; i++)
sum += vectorX[i] * vectorY[i];
return sum;
}
function norm(vectorX, n) {
return Math.sqrt(dot(vectorX, vectorX, n));
}
请注意,上面的算法计算了 Gram-Schmidt 正交化,即矩阵 [e1 | e2 | ... | en],不是 QR 分解!
关于javascript - 掌握了 90% 的 JavaScript 代码 - 无法理解其余部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6921826/