Получил 90% кода JavaScript - не могу понять остальное - PullRequest
3 голосов
/ 03 августа 2011

Поэтому я пытаюсь смоделировать Грамма-Шмидта для любого размера N × N матрицы, и я официально преодолел контрольно-пропускной пункт.прошлое.Я знаю, что это вопрос правильного зацикливания, но я не могу понять, в чем проблема.Помните, я не хочу просто передавать в матрицу 3 × 3, но любой размер N × N .

Примечания к курсу QRРазложение с Грам-Шмидтом объясняет, что именно я хочу сделать.Кстати, очень простой расчет.В записках курса || u ||означает, что это сумма квадратов элементов, поэтому sqrt ( x 1 2 + x 2 2 + x 3 2 + .... + x n 2 ).

Символ умножения на самом деле является точечным произведением.

Код, который я написал до сих пор, приведен ниже.Что с ним не так?

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

1 Ответ

4 голосов
/ 03 августа 2011

Я должен извиниться, что вместо того, чтобы настраивать ваш код, я написал свой собственный с нуля:

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

Обратите внимание, что приведенный выше алгоритм вычисляет ортогонализацию Грамма-Шмидта, которая является матрицей [e 1 2 |... |e n ], не QR-факторизация!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...