2014-11-29 85 views
7

Tôi đang thực hiện một chức năng nhân 2 ma trận. Các ma trận sẽ luôn có cùng số hàng và cột. (2x2, 5x5, 23x23, ...)Nhân 2 ma trận trong Javascript

Khi tôi in, nó không hoạt động. Tại sao?

Ví dụ, nếu tôi có thể tạo hai ma trận 2x2:

matrixA:

[1][2] 

[3][4] 

matrixB:

[5][6] 

[7][8] 

Kết quả sẽ là:

[19][22] 

[43][50] 

(http://ncalculators.com/matrix/2x2-matrix-multiplication-calculator.htm)

Nhưng, tôi nhận được:

[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

+0

có bạn đã cố gắng để gỡ lỗi mã trong trình duyệt tích hợp sẵn trong trình gỡ lỗi hoặc có lẽ trong Firebug ? – Aprillion

+0

với mã của bạn, tôi nhận được kết quả khác với yêu cầu của bạn - 'multiplyMatrix ([[1,2], [3,4]], [[5,6], [7,8]])' trả về ' [[19], [22], [NaN], [Nan]] ' – Aprillion

Trả lời

12

Bạn đang bị nhầm lẫn với mảng tạm thời khác nhau của bạn. Giá trị undefined là do truy cập ngoài giới hạn trên dòng bên dưới vòng lặp trong cùng của bạn.

Tôi khuyên bạn nên tạo một mảng đơn cho kết quả phép nhân. Như bạn có thể đã biết, sự cản trở là JavaScript không cho phép bạn khởi tạo một mảng đa chiều. Để tạo một mảng hai chiều, bạn phải khởi tạo một mảng một chiều, sau đó lặp qua các phần tử của nó và khởi tạo từng mảng một thành mảng một chiều.

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('&nbsp;&nbsp;'+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));

+0

Tôi đã sử dụng nó trên MSE cho các ma trận trung bình. Nó hoạt động tốt. –

7

Bạn có thể sử dụng multiplyMatrices() chức năng từ: http://tech.pro/tutorial/1527/matrix-multiplication-in-functional-javascript nó hoạt động như quyến rũ. Ví dụ (Bạn có thể in một ma trận với phong cách trong Chrome và Firefox console với console.table()):

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 */

Result matrix in console.table()

1

Nếu bạn muốn đi con đường bonkers, bạn cũng có thể làm điều gì đó với việc chuyển đổi đỉnh trong các cơ sở WebGL hiện có sẵn trong một số trình duyệt hiện đại.

Không thực sự chắc chắn nếu điều này sẽ làm việc theo cách tương tự như người ta có thể tiếp cận chuyển đổi vector trong OpenCL (** trong thực tế, họ đang loại tương đương/tương thích), nhưng ý tưởng chung là:

  • thêm giá trị của bạn đến một bộ đệm

  • "giả vờ" đó là một mảng các đỉnh

  • biến đổi en-tin đại chúng sử dụng công cụ GPU

  • lấy các giá trị sửa đổi từ vector

(xem demo ở đây) http://www.html5rocks.com/en/tutorials/webgl/webgl_transforms/

Chỉ cần một thay thế cho các phương pháp thông thường vòng lặp trong vòng lặp. Và thành thật mà nói, một chút của một fiddle, cho rằng OpenCL được thiết kế cho loại điều

Trong OpenCL 1.2 đặc tả bộ đệm đỉnh từ OpenGL có thể được nạp và chuyển đổi sử dụng OpenCL (xem. https://software.intel.com/en-us/articles/opencl-and-opengl-interoperability-tutorial)

+0

điều này thật tuyệt vời !! Bạn không chắc chắn tại sao điều này lại bị bỏ phiếu. Cuối cùng tôi nghĩ rằng tất cả các hoạt động đại số tuyến tính nên được thực hiện theo cách này trong trình duyệt. – episodeyang

-5

NPM cài đặt hiện

nút 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); 
0

Bạn có thể giải quyết vấn đề này với lập trình động sử dụng Ghi nhớ. Nó là một thuật ngữ mô tả một kỹ thuật tối ưu hóa nơi bạn lưu trữ các kết quả tính toán trước đó và trả về kết quả được lưu trong bộ nhớ cache khi cần tính toán lại.

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

Đối với giá trị đầu vào trên của saveComputation sẽ

{ '1*1': 1, 
    '2*1': 2, 
    '1*2': 2, 
    '3*1': 3, 
    '1*3': 3, 
    '2*2': 4, 
    '3*2': 6, 
    '2*3': 6 } 
0

Tôi biết đó là một câu hỏi cũ nhưng tôi khuyên để chuyển sang câu trả lời của tôi.

Giải pháp của tôi đã thực hiện tốt vì nó sử dụng MapReduce chức năng

//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(`&nbsp;&nbsp;${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));