矩阵叉乘运算法则(的运算法则及其与点)

矩阵叉乘是线性代数中最为常见、重要的运算之一,它经常被用于计算机科学领域中的图形学、物理模拟、计算机视觉等方面。矩阵叉乘的结果是另一矩阵,而非一个标量或向量。

一、矩阵叉乘的定义

矩阵叉乘的定义是,给定两个矩阵A和B,它们的行列数分别为 m×n 和 n×p,它们的叉乘结果记作C,C的行列数为m×p,C中的每一个元素Cij的值是A的第i行与B的第j列对应元素的乘积之和。


// 矩阵叉乘的代码示例
function matrixMultiplication(A, B) {
  let m = A.length;
  let n = A[0].length;
  let p = B[0].length;
  let C = new Array(m);
  for (let i = 0; i < m; i++) {
    C[i] = new Array(p);
    for (let j = 0; j < p; j++) {
      let sum = 0;
      for (let k = 0; k < n; k++) {
        sum += A[i][k] * B[k][j];
      }
      C[i][j] = sum;
    }
  }
  return C;
}

二、矩阵叉乘的性质

1. 非交换性

矩阵叉乘不满足交换律,即A × B ≠ B × A,因为它们的行列数不同,而且因为乘法本身就不具备交换律。

2. 结合律

矩阵叉乘满足结合律,即(A × B) × C = A × (B × C)。

3. 分配律

矩阵叉乘满足分配律,即A × (B + C) = (A × B) + (A × C)。

三、矩阵叉乘的应用

1. 矢量旋转

在计算机图形学领域中,可以使用矩阵叉乘来实现三维场景中的矢量旋转。假设一个三维矢量v=(x,y,z),要将它绕X、Y、Z轴分别旋转θ角度,就可以使用下面的旋转矩阵进行叉乘运算:


// 矢量旋转的代码示例
function rotateX(theta) {
  let c = Math.cos(theta);
  let s = Math.sin(theta);
  return [
    [1, 0, 0],
    [0, c, -s],
    [0, s, c]
  ];
}

function rotateY(theta) {
  let c = Math.cos(theta);
  let s = Math.sin(theta);
  return [
    [c, 0, s],
    [0, 1, 0],
    [-s, 0, c]
  ];
}

function rotateZ(theta) {
  let c = Math.cos(theta);
  let s = Math.sin(theta);
  return [
    [c, -s, 0],
    [s, c, 0],
    [0, 0, 1]
  ];
}

function vec3Rotate(v, rx, ry, rz) {
  let R = matrixMultiplication(matrixMultiplication(rotateX(rx), rotateY(ry)), rotateZ(rz));
  let vM = [
    [v[0]],
    [v[1]],
    [v[2]]
  ];
  let v1 = matrixMultiplication(R, vM);
  return [v1[0][0], v1[1][0], v1[2][0]];
}

2. 仿射变换

在计算机视觉以及图像处理领域中,可以使用矩阵叉乘来实现仿射变换。仿射变换包括平移、旋转、缩放、剪切等几种变换,可以使用一个3×3的矩阵来描述变换过程。


// 仿射变换的代码示例
function translate(dx, dy) {
  return [
    [1, 0, 0],
    [0, 1, 0],
    [dx, dy, 1]
  ];
}

function rotate(theta) {
  let c = Math.cos(theta);
  let s = Math.sin(theta);
  return [
    [c, -s, 0],
    [s, c, 0],
    [0, 0, 1]
  ];
}

function scale(sx, sy) {
  return [
    [sx, 0, 0],
    [0, sy, 0],
    [0, 0, 1]
  ];
}

function skew(shx, shy) {
  return [
    [1, shx, 0],
    [shy, 1, 0],
    [0, 0, 1]
  ];
}

function transform(pt, m) {
  let ptM = [[pt[0]], [pt[1]], [1]];
  let newPt = matrixMultiplication(m, ptM);
  return [newPt[0][0], newPt[1][0]];
}

3. 线性回归

矩阵叉乘可以用于计算线性回归中的最小二乘法。假设有一个观测数据集,包含n个观测样本,每个样本包含k个自变量和1个因变量。可以将观测数据表示为n×(k+1)的矩阵X,其中最后一列是1,表示截距项。对应的因变量表示为n维的列向量y。则线性回归模型可以表示为y=Xw,其中w是一个(k+1)维的列向量,表示自变量与因变量之间的线性关系。最小二乘法的目标是找到一个使得残差平方和最小的w。


// 线性回归的代码示例
function linearRegression(X, y) {
  let XMat = matrixMultiplication(transpose(X), X);
  let Xy = matrixMultiplication(transpose(X), y);
  let w = matrixMultiplication(inverse(XMat), Xy);
  return w;
}

function transpose(A) {
  let m = A.length;
  let n = A[0].length;
  let AT = new Array(n);
  for (let i = 0; i < n; i++) {
    AT[i] = new Array(m);
    for (let j = 0; j < m; j++) {
      AT[i][j] = A[j][i];
    }
  }
  return AT;
}

function inverse(A) {
  // 通过高斯-乔丹消元法求A的逆矩阵
}

四、总结

矩阵叉乘是一种十分有用的运算,可以用于三维图形学、计算机视觉以及线性回归等很多方面。在实际应用中,使用矩阵叉乘往往需要解决一些实现细节和数值问题,比如矩阵的行列数是否匹配、矩阵是否可逆等。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平