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