chromium/third_party/blink/web_tests/fast/js/regress/script-tests/Float32Array-matrix-mult.js

function makeEmptyMatrix(rows, columns)
{
    var result = new Array(rows);
    for (var i = 0; i < rows; ++i)
        result[i] = new Float32Array(columns);
    result.rows = rows;
    result.columns = columns;
    return result;
}

function multiplyMatrices(left, right)
{
    if (left.columns != right.rows) {
        throw new Error(
            "Left matrix has " + left.columns + " columns while right matrix has " +
                right.rows + " rows.");
    }
    
    var result = makeEmptyMatrix(left.rows, right.columns);
    
    for (var row = 0; row < result.rows; ++row) {
        for (var column = 0; column < result.columns; ++column) {
            for (var i = 0; i < left.columns; ++i)
                result[row][column] += left[row][i] * right[i][column];
        }
    }
    
    return result;
}

function checkMatricesEqual(left, right)
{
    if (left.columns != right.columns) {
        throw new Error(
            "Left matrix has " + left.columns + " columns while right matrix has " +
                right.columns + " columns");
    }
    if (left.rows != right.rows) {
        throw new Error(
            "Left matrix has " + left.rows + " rows while right matrix has " +
                right.rows + " rows");
    }
    
    for (var row = 0; row < left.rows; ++row) {
        for (var column = 0; column < left.columns; ++column) {
            if (left[row][column] != right[row][column]) {
                throw new Error(
                    "left[" + row + "][" + column + "] = " + left[row][column] +
                        " while right[" + row + "][" + column + "] = " + right[row][column]);
            }
        }
    }
}

function parseMatrix(string)
{
    var columns = null;
    var result = [];
    string.split("\\").forEach(function(string){
        var row = [];
        string.split(" ").forEach(function(string){
            if (string.match(/^ *$/))
                return;
            row.push(parseFloat(string));
        });
        if (columns) {
            if (columns != row.length) {
                throw new Error(
                    "Not all rows have the same number of columns. First row has " +
                        columns + " columns, while column #" + (result.length + 1) + " has " +
                        row.length + " columns.");
            }
        } else
            columns = row.length;
        var typedRow = new Float32Array(row.length);
        for (var i = 0; i < columns; ++i)
            typedRow[i] = row[i];
        result.push(typedRow);
    });
    result.rows = result.length;
    result.columns = columns;
    return result;
}

function printMatrix(matrix)
{
    var maxCellSize = 0;
    
    for (var row = 0; row < matrix.rows; ++row) {
        for (var column = 0; column < matrix.columns; ++column)
            maxCellSize = Math.max(maxCellSize, ("" + matrix[row][column]).length);
    }
    
    function pad(value)
    {
        var result = "" + value;
        while (result.length < maxCellSize)
            result = " " + result;
        return result;
    }
    
    for (var row = 0; row < matrix.rows; ++row) {
        var rowText = "";
        for (var column = 0; column < matrix.columns; ++column) {
            if (column)
                rowText += " ";
            rowText += pad(matrix[row][column]);
        }
        print(rowText);
    }
}

var left = parseMatrix("1 2 3 4 5 \\ 6 7 8 9 10 \\ 21 22 23 24 25 \\ 26 27 28 29 30");
var right = parseMatrix("11 12 31 32 \\ 13 14 33 34 \\ 15 16 35 36 \\ 17 18 37 38 \\ 19 20 39 40");
var expectedResult = parseMatrix("245 260 545 560 \\ 620 660 1420 1460 \\ 1745 1860 4045 4160 \\ 2120 2260 4920 5060");

for (var i = 0; i < 3000; ++i)
    checkMatricesEqual(multiplyMatrices(left, right), expectedResult);