矩阵理论基础
本章主要介绍矩阵理论的基本概念、基本运算,为理解这一数学工具打下坚实的
基础。通过本章的学习,读者将掌握矩阵的基本构造,了解它们如何通过简单的规则
进行变换,以及这些变换如何影响我们对世界的理解和解释。
当前为 MD 笔记,自:清华大学出版社
1. 向量与矩阵
当我们在研究各种问题的时候,很多都可以数学建模转换成一个线性方程组:
\left\{ \begin{array}{l} a_{11}x_1 + a_{12}x_2 + \cdots + a_{1n}x_n = b_1\\ a_{21}x_1 + a_{22}x_2 + \cdots + a_{2n}x_n = b_2\\ \cdots\\ a_{m1}x_1 + a_{m2}x_2 + \cdots + a_{mn}x_n = b_m \end{array} \right.
在线性方程组 (1-1) 中,使用 m 个方程描述 n 个未知量之间的线性关系。这种表示方式在研究问题时不够简练,为了简化问题,可以采用向量和矩阵。下面介绍向量与矩阵的概念。
2. 向量与矩阵的概念
线性方程组 (1-1) 中所有变量的系数可按相对位置排成 m 行 n 列的数集,写作:
A = \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{bmatrix}
称 A 为 m\times n 矩阵,简记为 A=(a_{ij})_{m\times n},其中 a_{ij} 表示矩阵 A 的第 i 行、第 j 列元素,简称第 (i,j) 个元素。
当 a_{ij} 取实数时,称 A 为实矩阵;当 a_{ij} 取复数时,称 A 为复矩阵。
- 当 m=n 时,称 A 为 n 阶方阵;
- 当 m
时,称 A 为 宽矩阵; - 当 m>n 时,称 A 为 高矩阵。
2.1 向量及其 C 语言表示
(1)列向量
当 n=1 时,矩阵退化为:
\begin{bmatrix} a_1 \\ a_2 \\ \vdots \\ a_m \end{bmatrix} \quad\quad
称其为 m 维列向量,简称 m 维向量,一般用小写字母表示,如 \mathbf{a},\mathbf{b},\mathbf{x},\mathbf{y},\dots。
若 a_i\in\mathbb{R},则称其为 m 维实向量,记作 \mathbf{a}\in\mathbb{R}^{m\times1},或简记为 \mathbf{a}\in\mathbb{R}^m。
若 a_i\in\mathbb{C},则称其为 m 维复向量,记作 \mathbf{a}\in\mathbb{C}^{m\times1}。
列向量
c
#include <stdio.h>
int main() {
double a[3] = {1.0, 2.0, 3.0}; // 3 维实列向量
for (int i = 0; i < 3; i++) {
printf("a[%d] = %.2f\n", i, a[i]);
}
return 0;
}
(2)行向量
称 [a_1,a_2,\dots,a_n] 为一个 n 维行向量,通常记作 \mathbf{a}^\mathrm{T}\in\mathbb{R}^{1\times n} 或 \mathbf{a}^\mathrm{T}\in\mathbb{C}^{1\times n}。
C 语言示例:行向量
c
#include <stdio.h>
#define ROWS 2
#define COLS 3
int main(void) {
double A[ROWS][COLS] = {
{1.0, 2.0, 3.0},
{4.0, 5.0, 6.0}
};
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
printf("A[%d][%d] = %.2f\t", i, j, A[i][j]);
}
printf("\n");
}
return 0;
}
在 C 语言中,行向量与列向量在内存中是一样的,区别主要体现在数学意义和使用方式上。
2.2 矩阵的 C 语言表示
有了向量与矩阵的概念,方程组 (1-1) 可简洁地写为:
A\mathbf{x}=\mathbf{b}
(1)一般矩阵
二维数组表示矩阵
c
#include <stdio.h>
int main() {
double A[2][3] = {
{1.0, 2.0, 3.0},
{4.0, 5.0, 6.0}
}; // 2×3 实矩阵
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("A[%d][%d] = %.2f\t", i, j, A[i][j]);
}
printf("\n");
}
return 0;
}
(2)方阵、特殊矩阵与零矩阵
一个 n 阶方阵 A 的主对角线是从左上角到右下角、满足 i=j 的元素连线。
主对角线以外的元素全为零的方阵称为对角矩阵:
D=\mathrm{diag}(d_{11},d_{22},\dots,d_{nn})
若对角矩阵的主对角线元素全部为 1,则称为单位矩阵,记为 I_n。
所有元素为零的矩阵称为零矩阵,记为 O_{m\times n};所有元素为零的向量称为零向量,记为 \mathbf{0}。
单位矩阵
c
#include <stdio.h>
int main() {
int n = 3;
double I[3][3] = {{0}};
for (int i = 0; i < n; i++) {
I[i][i] = 1.0; // 单位矩阵
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%.0f ", I[i][j]);
}
printf("\n");
}
return 0;
}
零矩阵
c
double O[3][4] = {{0}}; // 3×4 零矩阵
3. 矩阵的基本运算
矩阵的基本运算是处理线性变换的核心工具。本节将介绍矩阵的转置、共轭、共轭转置、求逆,以及相关的重要矩阵类型。
3.1 矩阵的转置
若 A = (a_{ij})_{m \times n},将其行与列互换得到 n \times m 矩阵,称为 转置矩阵,记作 A^{\mathrm{T}}:
A^{\mathrm{T}} = \begin{bmatrix} a_{11} & a_{21} & \cdots & a_{m1} \\ a_{12} & a_{22} & \cdots & a_{m2} \\ \vdots & \vdots & & \vdots \\ a_{1n} & a_{2n} & \cdots & a_{mn} \end{bmatrix}
矩阵转置
c
#include <stdio.h>
int main() {
double A[2][3] = {{1, 2, 3}, {4, 5, 6}};
double AT[3][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
AT[j][i] = A[i][j];
}
}
printf("Transpose of A:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
printf("%.0f ", AT[i][j]);
}
printf("\n");
}
return 0;
}
3.2 共轭与共轭转置
若 A 为复矩阵,对每个元素取复共轭得到 共轭矩阵 A^*:
A^* = \begin{bmatrix} a^*_{11} & a^*_{12} & \cdots & a^*_{1n} \\ a^*_{21} & a^*_{22} & \cdots & a^*_{2n} \\ \vdots & \vdots & & \vdots \\ a^*_{m1} & a^*_{m2} & \cdots & a^*_{mn} \end{bmatrix}
先转置再取共轭,得到 共轭转置矩阵 A^{\mathrm{H}}:
A^{\mathrm{H}} = (A^{\mathrm{T}})^*
复共轭
c
#include <stdio.h>
// 自定义复数结构体
typedef struct {
double real;
double imag;
} Complex;
// 计算共轭
Complex conjugate(Complex c) {
Complex result;
result.real = c.real;
result.imag = -c.imag;
return result;
}
int main() {
Complex A[2][2] = {
{{1.0, 2.0}, {3.0, -1.0}},
{{4.0, -2.0}, {5.0, 0.0}}
};
printf("Conjugate of A:\n");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Complex c = conjugate(A[i][j]);
printf("(%.1f,%.1f) ", c.real, c.imag);
}
printf("\n");
}
return 0;
}
3.3 矩阵的求逆
对于方阵 A,若存在方阵 B 使得
AB = BA = I
则称 B 为 A 的 逆矩阵,记作 A^{-1}。
若逆矩阵存在,A 称为 非奇异矩阵。
2×2 矩阵求逆(解析法)
c
#include <stdio.h>
int main() {
double A[2][2] = {{4, 7}, {2, 6}};
double det = A[0][0]*A[1][1] - A[0][1]*A[1][0];
double invA[2][2];
if (det != 0) {
invA[0][0] = A[1][1] / det;
invA[0][1] = -A[0][1] / det;
invA[1][0] = -A[1][0] / det;
invA[1][1] = A[0][0] / det;
}
printf("Inverse of A:\n");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("%.3f ", invA[i][j]);
}
printf("\n");
}
return 0;
}
3.4 正交矩阵与酉矩阵
正交矩阵(实数)
若 A 为实方阵,且
A^{\mathrm{T}}A = AA^{\mathrm{T}} = I
则称 A 为 正交矩阵。
酉矩阵(复数)
若 A 为复方阵,且
A^{\mathrm{H}}A = AA^{\mathrm{H}} = I
则称 A 为 酉矩阵。
验证正交矩阵
c
#include <stdio.h>
int main() {
double Q[2][2] = {
{0.7071, -0.7071},
{0.7071, 0.7071}
};
double QTQ[2][2] = {{0}};
// 计算 Q^T * Q
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
QTQ[i][j] += Q[k][i] * Q[k][j];
}
}
}
printf("Q^T * Q:\n");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("%.3f ", QTQ[i][j]);
}
printf("\n");
}
return 0;
}
更新中……