我正在做一个乘以2个矩阵的函数。矩阵将始终具有相同的行数和列数。 (2x2,5x5,23x23,......)
当我打印它时,它不起作用。为什么呢?
例如,如果我创建两个2x2矩阵:
矩阵matrixA:
[1][2]
[3][4]
matrixB:
[5][6]
[7][8]
结果应为:
[19][22]
[43][50]
(http://ncalculators.com/matrix/2x2-matrix-multiplication-calculator.htm)
但是,我明白了:
[19][undefined]
[22][indefined]
function multiplyMatrix(matrixA, matrixB)
{
var result = new Array();//declare an array
//var numColsRows=$("#matrixRC").val();
numColsRows=2;
//iterating through first matrix rows
for (var i = 0; i < numColsRows; i++)
{
//iterating through second matrix columns
for (var j = 0; j < numColsRows; j++)
{
var matrixRow = new Array();//declare an array
var rrr = new Array();
var resu = new Array();
//calculating sum of pairwise products
for (var k = 0; k < numColsRows; k++)
{
rrr.push(parseInt(matrixA[i][k])*parseInt(matrixB[k][j]));
}//for 3
resu.push(parseInt(rrr[i])+parseInt(rrr[i+1]));
result.push(resu);
//result.push(matrixRow);
}//for 2
}//for 1
return result;
}// function multiplyMatrix
&#13;
答案 0 :(得分:12)
您对各种临时阵列感到困惑。 undefined
值是由最内层循环下面的行上的越界访问引起的。
我建议您坚持为乘法结果制作单个数组。正如您可能意识到的那样,遗憾的是JavaScript并不允许您初始化多维数组。要制作二维数组,必须初始化一维数组,然后迭代其元素并将每个数组初始化为一维数组。
function multiply(a, b) {
var aNumRows = a.length, aNumCols = a[0].length,
bNumRows = b.length, bNumCols = b[0].length,
m = new Array(aNumRows); // initialize array of rows
for (var r = 0; r < aNumRows; ++r) {
m[r] = new Array(bNumCols); // initialize the current row
for (var c = 0; c < bNumCols; ++c) {
m[r][c] = 0; // initialize the current cell
for (var i = 0; i < aNumCols; ++i) {
m[r][c] += a[r][i] * b[i][c];
}
}
}
return m;
}
function display(m) {
for (var r = 0; r < m.length; ++r) {
document.write(' '+m[r].join(' ')+'<br />');
}
}
var a = [[8, 3], [2, 4], [3, 6]],
b = [[1, 2, 3], [4, 6, 8]];
document.write('matrix a:<br />');
display(a);
document.write('matrix b:<br />');
display(b);
document.write('a * b =<br />');
display(multiply(a, b));
&#13;
答案 1 :(得分:8)
你可以使用来自http://tech.pro/tutorial/1527/matrix-multiplication-in-functional-javascript的multiplyMatrices()函数,它就像魅力一样。示例(您可以使用console.table()在Chrome和Firefox控制台中打印带样式的矩阵):
function multiplyMatrices(m1, m2) {
var result = [];
for (var i = 0; i < m1.length; i++) {
result[i] = [];
for (var j = 0; j < m2[0].length; j++) {
var sum = 0;
for (var k = 0; k < m1[0].length; k++) {
sum += m1[i][k] * m2[k][j];
}
result[i][j] = sum;
}
}
return result;
}
var m1 = [[1,2],[3,4]]
var m2 = [[5,6],[7,8]]
var mResult = multiplyMatrices(m1, m2)
/*In Google Chrome and Firefox you can do:*/
console.table(mResult) /* it shows the matrix in a table */
&#13;
答案 2 :(得分:7)
我知道这是一个老问题,但我建议切换到我的答案。
我的解决方案获得了良好的效果,因为它使用
Map
Reduce
功能
//The chosen one
function matrixDot (A, B) {
var result = new Array(A.length).fill(0).map(row => new Array(B[0].length).fill(0));
return result.map((row, i) => {
return row.map((val, j) => {
return A[i].reduce((sum, elm, k) => sum + (elm*B[k][j]) ,0)
})
})
}
var print = m => m.forEach(r => document.write(` ${r.join(' ')}<br/>`))
var a = [[8, 3], [2, 4], [3, 6]]
var b = [[1, 2, 3], [4, 6, 8]]
document.write('matrix a:<br />');
print(a);
document.write('matrix b:<br />');
print(b);
document.write('a * b =<br />');
print(matrixDot(a,b));
&#13;
答案 3 :(得分:2)
对于那些对纯功能解决方案感兴趣的人:
let MatrixProd = (A, B) =>
A.map((row, i) =>
B[0].map((_, j) =>
row.reduce((acc, _, n) =>
acc + A[i][n] * B[n][j], 0
)
)
)
浏览器的测试代码:
let A = [[8, 3], [2, 4], [3, 6]];
let B = [[1, 2, 3], [4, 6, 8]];
console.table(MatrixProd(A,B));
答案 4 :(得分:1)
如果你想要去疯狂路线,你也可以对现在在一些现代浏览器中提供的WebGL设施中的顶点变换做些什么。
不确定这是否会像在OpenCL中接近矢量转换一样工作(**实际上它们是类型等效/可互操作的),但总体思路是:
将您的值添加到缓冲区
“假装”它是一个顶点数组
使用GPU引擎转换大量数据
从向量中检索修订后的值
(见这里的演示) http://www.html5rocks.com/en/tutorials/webgl/webgl_transforms/
只是通常的循环回路方法的替代方案。说实话,有点小提琴,因为OpenCL就是为这种事而设计的
在OpenCL 1.2规范中,OpenGL的顶点缓冲区可以使用OpenCL加载和转换(参见。https://software.intel.com/en-us/articles/opencl-and-opengl-interoperability-tutorial)
答案 5 :(得分:1)
您可以使用动态编程通过动态编程解决此问题。它是一个描述优化技术的术语,您可以在其中缓存先前计算的结果,并在再次需要相同的计算时返回缓存的结果。
let mat1 = [[1, 2, 3], [2, 1, 2]];
let mat2 = [[1, 2], [1, 2], [1, 2]];
function matrixMulti(x, y) {
let saveComputation = {};
let finalMat = [],
length=x.length,
length1 = y[0].length,
length2 = y.length;
for (let i = 0; i < length; i++) {
finalMat.push([]);
for (let j = 0; j < length1; j++) {
finalMat[i][j] = 0;
for (let k = 0; k < length2; k++) {
// check if we already computed this calculation or not
if (saveComputation[y[k][j] + '*' + x[i][k]] || saveComputation[x[i][k] + '*' + y[k][j]]) {
finalMat[i][j] = finalMat[i][j] + saveComputation[y[k][j] + '*' + x[i][k]];
} else {
// save if not computed
saveComputation[x[i][k] + '*' + y[k][j]] = x[i][k] * y[k][j]; // check format below how it is saved.
saveComputation[y[k][j] + '*' + x[i][k]] = x[i][k] * y[k][j];
finalMat[i][j] = finalMat[i][j] + saveComputation[y[k][j] + '*' + x[i][k]];
}
}
}
}
console.log(finalMat);
}
matrixMulti(mat1, mat2);
对于 saveComputation 的上述输入值将为
{ '1*1': 1,
'2*1': 2,
'1*2': 2,
'3*1': 3,
'1*3': 3,
'2*2': 4,
'3*2': 6,
'2*3': 6 }
答案 6 :(得分:0)
这是我的带有数学错误处理功能的ES6解决方案:
const matrixDot = (A, B) => {
// Math error handling
const matrices = [A, B];
const cols = matrices.map((item) => item[0].length);
if (!matrices.every((item, i) => item.every((row) => row.length === cols[i])))
return console.error('All rows in a matrix must have equal amount of columns');
else if (cols[0] !== B.length)
return console.error(
'Amount of columns in the 1st matrix must match amount of rows in the 2nd matrix'
);
// Calculations
return A.map((rowA) =>
B[0].map((_, colBIndex) =>
rowA.reduce((acc, itemA, rowBIndex) => acc + itemA * B[rowBIndex][colBIndex], 0)
)
);
};
// Example
const A = [
[3, 2, 5],
[6, 4, 1],
];
const B = [
[2, 6],
[5, 3],
[1, 4],
];
console.log(matrixDot(A, B));
// [ [21, 44],
// [33, 52] ]
如果要添加书签,请在这里gist
希望对您有所帮助;)
答案 7 :(得分:0)
此版本将行存储为临时行,从而减少了有效的索引查找量。通过此benchmark,与不存储行的版本相比,实现的性能几乎快2倍。
function multiply(a, b) {
let aRows = a.length;
let aCols = a[0].length;
let bCols = b[0].length;
let result = new Array(aRows);
for (let r = 0; r < aRows; ++r) {
const row = new Array(bCols);
result[r] = row;
const ar = a[r];
for (let c = 0; c < bCols; ++c) {
let sum = 0.;
for (let i = 0; i < aCols; ++i) {
sum += ar[i] * b[i][c];
}
row[c] = sum;
}
}
return result;
}
const m = multiply(
[[8, 3], [2, 4], [3, 6]],
[[1, 2, 3], [4, 6, 8]]
);
console.log(m);
function display(m) {
for (var r = 0; r < m.length; ++r) {
document.write(' '+m[r].join(' ')+'<br />');
}
}
var a = [[8, 3], [2, 4], [3, 6]],
b = [[1, 2, 3], [4, 6, 8]];
document.write('matrix a:<br />');
display(a);
document.write('matrix b:<br />');
display(b);
document.write('a * b =<br />');
display(multiply(a, b));
答案 8 :(得分:0)
const getDot = (arrA, arrB, row, col) => {
return arrA[row].map((val, i) => (val * arrB[i][col]))
.reduce((valA, valB) => valA + valB);
}
const multiplyMatricies = (a, b) => {
let matrixShape = new Array(a.length).fill(0)
.map(() => new Array(b[0].length).fill(0));
return matrixShape.map((row, i) =>
row.map((val, j) => getDot(a, b, i, j)));
}
const arrA = [
[1, 3, 0],
[2, 1, 1]
];
const arrB = [
[1, 2, 0, 1],
[2, 3, 1, 2],
[1, 2, 1, 1]
];
let product = multiplyMatricies(arrA, arrB);
console.log("product:", product);
答案 9 :(得分:-6)
npm install express
node server.js
var express = require('express');
var app = express();
var A=new Array(3);
var B=new Array(3);
var preA = [ 1, 2, 3, 4, 5, 6,7, 8, 9 ];
var preB = [ 1,1 ,1,2,2, 2,3, 3, 3 ];
//#########################preparing blank 3*3 matrix A and B###############
for(i=0;i<3;i++){
A[i]=new Array(3);
B[i]=new Array(3);
}
//#####################Assigning values to matrix places from predefine arrays preA and preB #####
var k=0;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
A[i][j]=preA[k];
B[i][j]=preB[k];
k++;
}
};
console.log('################################');
console.log('First matrix:');
console.log(A[0]);
console.log(A[1]);
console.log(A[2]);
console.log('');
console.log('################################');
console.log('Second matrix:');
console.log(B[0]);
console.log(B[1]);
console.log(B[2]);
//###################### multiplication logic as disscussed ################
var result =[];
for (var i = 0; i < 3; i++) {
result[i] = new Array(3);
for (var j = 0; j < 3; j++) {
var sum = 0;
for (var k = 0; k < 3; k++) {
sum += A[i][k] * B[k][j];
}
result[i][j] = sum;
}
}
console.log('');
console.log('################################');
console.log('################################');
console.log('After Multiplication');
console.log(result[0]);
console.log(result[1]);
console.log(result[2]);
app.listen(9999);