JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで数値の2次元配列(行列)同士の乗算結果を返す関数の実装方法

はじめに

本記事では、2つの数値の2次元配列(行列)を受け取り、その行列の乗算結果を返すJavaScript関数の実装方法を解説します。

前提となる行列の定義

ここでは、次の2つの行列を例として扱います。1つ目は5行4列の行列a、2つ目は4行6列の行列bです。

// 5 x 4 の行列
let a = [
    [1, 2, 3, 1],
    [4, 5, 6, 1],
    [7, 8, 9, 1],
    [1, 1, 1, 1],
    [5, 7, 2, 6]
];
// 4 x 6 の行列
let b = [
    [1, 4, 7, 3, 4, 6],
    [2, 5, 8, 7, 3, 2],
    [3, 6, 9, 6, 7, 8],
    [1, 1, 1, 2, 3, 6]
];

行列の乗算のルール

行列の掛け算では、「1つ目の行列の列数」と「2つ目の行列の行数」が一致している必要があります。今回の例では、5×4の行列と4×6の行列を掛けるため、計算可能であり、結果は5×6の行列になります。一般化すると「X×Z の行列 × Z×Y の行列 = X×Y の行列」となります。

実装コード

それでは、この関数のコードを見ていきましょう。

const multiplyMatrices = (a, b) => {
    // 引数が2次元配列であるかどうかを検証
    if (!Array.isArray(a) || !Array.isArray(b) || !a.length || !b.length) {
        throw new Error('引数は2次元配列形式である必要があります');
    }
    let x = a.length,
        z = a[0].length,
        y = b[0].length;
    // 列数と行数の整合性チェック
    if (b.length !== z) {
        // XxZ & ZxY => XxY
        throw new Error('1つ目の行列の列数は、2つ目の行列の行数と同じである必要があります');
    }
    // 結果を格納するためのゼロ初期化された配列を準備
    let productRow = Array.apply(null, new Array(y)).map(Number.prototype.valueOf, 0);
    let product = new Array(x);
    for (let p = 0; p < x; p++) {
        product[p] = productRow.slice();
    }
    // 三重ループで各要素の内積を計算
    for (let i = 0; i < x; i++) {
        for (let j = 0; j < y; j++) {
            for (let k = 0; k < z; k++) {
                product[i][j] += a[i][k] * b[k][j];
            }
        }
    }
    return product;
};
// 5 x 4 の行列
let a = [
    [1, 2, 3, 1],
    [4, 5, 6, 1],
    [7, 8, 9, 1],
    [1, 1, 1, 1],
    [5, 7, 2, 6]
];
// 4 x 6 の行列
let b = [
    [1, 4, 7, 3, 4, 6],
    [2, 5, 8, 7, 3, 2],
    [3, 6, 9, 6, 7, 8],
    [1, 1, 1, 2, 3, 6]
];
// 5 x 6 の行列が出力される
console.log(multiplyMatrices(a, b));

コードのポイント

  • 入力チェック: 引数が配列かどうか、また空でないかを最初に検証し、不正な入力に対してはエラーを投げます。
  • 次元の検証: 1つ目の行列の列数(z)と2つ目の行列の行数(b.length)が一致しない場合は、乗算が定義されないためエラーになります。
  • 三重ループ: 結果行列の各行・各列について、対応する行ベクトルと列ベクトルの内積を求めることで、積の各要素を計算しています。
  • 計算量: 計算量は O(x・y・z) となり、行列サイズが大きくなると処理時間が増大します。必要に応じて最適化を検討してください。

出力結果

上記のコードをコンソールで実行すると、次のような5×6の行列が出力されます。

[
    [ 15, 33, 51, 37, 34, 40 ],
    [ 33, 78, 123, 85, 76, 88 ],
    [ 51, 123, 195, 133, 118, 136 ],
    [ 7, 16, 25, 18, 17, 22 ],
    [ 31, 73, 115, 88, 73, 96 ]
]

まとめ

このように、JavaScriptでもシンプルな三重ループを使うことで、行列の乗算を容易に実装できます。引数の妥当性チェックを組み込むことで、安全で堅牢な関数になっています。データ分析やグラフィックス処理など、行列演算が必要な場面でぜひ活用してみてください。

  1. JavaScriptで2つの配列を結合する方法【concat()とスプレッド構文】

    JavaScriptで2つの配列を1つにまとめたい場合、最も一般的なのが concat() メソッドです。このメソッドは、元の配列を変更することなく、複数の配列や値を連結した新しい配列を返します。 concat()メソッドの基本構文 let 新しい配列 = 配列A.concat(配列B); サンプルコード 以下は、ボタンをクリックすると2つの配列を結合し、その結果を画面に表示する完全なサンプルです。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8&

  2. JavaScriptで2つの配列を乗算する方法|forループとmap()の実装例

    JavaScriptで2つの配列の各要素同士を乗算し、その結果を新しい配列として取得する方法を解説します。基本的にはforループでインデックスを順番に処理しながら、対応する位置にある要素同士を掛け合わせていくシンプルなアプローチです。 2つの配列を乗算するサンプルコード 以下の例では、「CLICK HERE」ボタンをクリックすると、配列 arr と arr1 の対応する要素が乗算され、結果が新しい配列 multArray に格納された上で画面に表示されます。 <!DOCTYPE html> <html lang=en> <head> <meta ch