『筆記』矩陣


定義

在數學中,矩陣(Matix) 是一個按照長方形陣列排列的復數或實數集合。

\(m \times n\) 個數 \(a_{i,j}\) 排成的 \(m\)\(n\) 列的數表稱為 \(m\)\(n\) 列的矩陣,簡稱 \(m \times n\) 矩陣。(其中 \(m\) 為行數、\(n\) 為列數)

\[\begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ a_{m,1} & a_{m,2} & \cdots & a_{m,n} \end{bmatrix}_{m \times n} \]

幾種常見矩陣類型

實矩陣

數表中多有元素均為實數

復矩陣

數表中所有元素均為復數

行矩陣

數表中只有一行元素,沒有列元素

列矩陣

數表中只有一列元素,沒有行元素

負矩陣

數表中所有元素均為負數

方陣

一種特殊的矩陣,行數 = 列數

\[\begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ a_{n,1} & a_{n,2} & \cdots & a_{n,n} \end{bmatrix}_{n \times n} \]

單位陣

一種特殊的方陣,數表中從左上角到右下角的對角線(稱為主對角線)上的元素均為 \(1\) ,除此以外全都為 \(0\)

記作 \(I_n\)\(E_n\) ,通常用 \(I\)\(E\) 表示。

根據單位矩陣的特點,任何矩陣與單位矩陣相乘都等於本身。

\[\begin{bmatrix} 1 & 0 & \cdots & 0 \\ 0 & 1 & \cdots & 0 \\ \cdots & \cdots & \ddots & \cdots \\ 0 & 0 & \cdots & 1 \end{bmatrix}_{n \times n} \]

同型矩陣

行數和列數分別相同的兩個矩陣。

若有

\[A_{m \times n} = \begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ a_{m,1} & a_{m,2} & \cdots & a_{m,n} \end{bmatrix}_{m \times n} \]

\[B_{m \times n} = \begin{bmatrix} b_{1,1} & b_{1,2} & \cdots & b_{1,n} \\ b_{2,1} & b_{2,2} & \cdots & b_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ b_{m,1} & b_{m,2} & \cdots & b_{m,n} \end{bmatrix}_{m \times n} \]

\[A_{m \times n} \leftrightarrow B_{m \times n} \]

那么顯然,兩個矩陣互為同型矩陣是兩個矩陣相同的充分條件。

特殊矩陣

單元素矩陣

當一個矩陣的數表中只有一個元素時,可以不加括號。

\[A= \begin{bmatrix} 5 \end{bmatrix} =5 \]

但要注意,一個矩陣 \(5\) 和一個數字 \(5\) 的數學意義是不同的。

零矩陣

數表中所有元素均為零。零矩陣可直接表示為 \((0)\) 或者 \(0\)

但是值得注意的是,兩個零矩陣不一定是同型矩陣,更不一定是相同矩陣,例如

\[0 = \begin{bmatrix} 0 & 0 & 0 \\ 0 & 0 & 0 \end{bmatrix}_{2 \times 3} \]

\[0^{\prime} = \begin{bmatrix} 0 & 0 \\ 0 & 0 \\ 0 & 0 \end{bmatrix}_{3 \times 2} \]

既不是同型矩陣,更不是相同矩陣。

矩陣的對角線

注意,只有方陣才能有對角線,即只有當矩陣的 行數 = 列數 時才能有對角線。

錯誤示范:

正確示范:

矩陣運算

加減法

將兩個矩陣的每一個元素相加減,對應元素形成的結果作為新矩陣的對應元素。

注意:兩矩陣能夠做加減法運算的充要條件是這兩個矩陣是同型矩陣

\[\begin{aligned} A_{n \times n} \pm b_{n \times n} &= \begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ a_{n,1} & a_{n,2} & \cdots & a_{n,n} \end{bmatrix}_{n \times n} \pm \begin{bmatrix} b_{1,1} & b_{1,2} & \cdots & b_{1,n} \\ b_{2,1} & b_{2,2} & \cdots & b_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ b_{n,1} & b_{n,2} & \cdots & b_{n,n} \end{bmatrix}_{n \times n} \\ & = \begin{bmatrix} a_{1,1} \pm b_{1,1} & a_{1,2} \pm b_{1,2} & \cdots \pm \cdots & a_{1,n} \pm b_{1,n} \\ a_{2,1} \pm b_{2,1} & a_{2,2} \pm b_{2,2} & \cdots \pm \cdots & a_{2,n} \pm b_{2,n} \\ \cdots \pm \cdots & \cdots \pm \cdots & \cdots \pm \cdots & \cdots \pm \cdots \\ a_{n,1} \pm b_{n,1} & a_{n,2} \pm b_{n,2} & \cdots \pm \cdots & a_{n,n} \pm b_{n,n} \end{bmatrix}_{n \times n} \end{aligned} \]

矩陣乘法

數乘矩陣

用一個數乘一個矩陣等於用一個數乘以這個矩陣的全部元素。

\[\begin{aligned} K \times A_{m \times n} &= K \times \begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ a_{m,1} & a_{m,2} & \cdots & a_{m,n} \end{bmatrix}_{m \times n} \\ &= \begin{bmatrix} K \times a_{1,1} & K \times a_{1,2} & \cdots & K \times a_{1,n} \\ K \times a_{2,1} & K \times a_{2,2} & \cdots & K \times a_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ K \times a_{m,1} & K \times a_{m,2} & \cdots & K \times a_{m,n} \end{bmatrix}_{m \times n} \\ \end{aligned} \]

矩陣相乘

設 A 為 \(m \times p\) 的矩陣,B 為 \(p \times n\) 的矩陣,那么稱 \(m \times n\) 的矩陣 C 為矩陣 A 與 B 的乘積,記作 \(C = A \times B\),其中矩陣 C 中的第 \(i\) 行第 \(j\) 列元素可以表示為:

\[(A B)_{i j}=\sum_{k=1}^{p} a_{i k} b_{k j}=a_{i 1} b_{1 j}+a_{i 2} b_{2 j}+\cdots+a_{i p} b_{p j} \]

計算過程:

\[\begin{aligned} C &= A_{m \times p} \times b_{p \times n} \\ &= \begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,p} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,p} \\ \cdots & \cdots & \cdots & \cdots \\ a_{m,1} & a_{m,2} & \cdots & a_{m,p} \end{bmatrix}_{m \times p} \times \begin{bmatrix} b_{1,1} & b_{1,2} & \cdots & b_{1,n} \\ b_{2,1} & b_{2,2} & \cdots & b_{2,n} \\ \cdots & \cdots & \cdots & \cdots \\ b_{p,1} & b_{p,2} & \cdots & b_{p,n} \end{bmatrix}_{p \times n} \\ & = \begin{bmatrix} a_{1,1} \times b_{1,1} + a_{1,2} \times b_{2,1} + \cdots \times \cdots + a_{1,p} \times b_{p,1} & a_{1,1} \times b_{1,2} + a_{1,2} \times b_{2,2} + \cdots \times \cdots + a_{1,p} \times b_{p,2} & a_{1,1} \times \cdots + a_{1,2} \times \cdots + \cdots \times \cdots + a_{1,p} \times \cdots & a_{1,1} \times b_{1,n} + a_{1,2} \times b_{2,n} + \cdots \times \cdots + a_{1,p} \times b_{p,n} \\ a_{2,1} \times b_{1,1} + a_{2,2} \times b_{2,1} + \cdots \times \cdots + a_{2,p} \times b_{p,1} & a_{2,1} \times b_{1,2} + a_{2,2} \times b_{2,2} + \cdots \times \cdots + a_{2,p} \times b_{p,2} & a_{2,1} \times \cdots + a_{2,2} \times \cdots + \cdots \times \cdots + a_{2,p} \times \cdots & a_{2,1} \times b_{1,n} + a_{2,2} \times b_{2,n} + \cdots \times \cdots + a_{2,p} \times b_{p,n} \\ \cdots \times b_{1,1} + \cdots \times b_{2,1} + \cdots \times \cdots + \cdots \times b_{p,1} & \cdots \times b_{1,2} + \cdots \times b_{2,2} + \cdots \times \cdots + \cdots \times b_{p,2} & \cdots \times \cdots + \cdots \times \cdots + \cdots \times \cdots + \cdots \times \cdots & \cdots \times b_{1,n} + \cdots \times b_{2,n} + \cdots \times \cdots + \cdots \times b_{p,n} \\ a_{m,1} \times b_{1,1} + a_{m,2} \times b_{2,1} + \cdots \times \cdots + a_{m,p} \times b_{p,1} & a_{m,1} \times b_{1,2} + a_{m,2} \times b_{2,2} + \cdots \times \cdots + a_{m,p} \times b_{p,2} & a_{m,1} \times \cdots + a_{m,2} \times \cdots + \cdots \times \cdots + a_{m,p} \times \cdots & a_{m,1} \times b_{1,n} + a_{m,2} \times b_{2,n} + \cdots \times \cdots + a_{m,p} \times b_{p,n} \end{bmatrix}_{m \times n} \end{aligned} \]

若公式顯示不完整可以點擊這里查看。

運算律

  • 數乘結合律: \(K(AB)=(KA)B=A(KB)\)

  • 乘法結合律: \((AB)C=A(BC)\)

  • 乘法左分配律: \((A+B)C=AC+BC\)

  • 乘法右分配律: \(C(A+B)=CA+CB\)

注意

\(A \times B\) 有意義, \(B \times A\) 不一定有意義。

\(A \times B=B \times A\) ,則說明 \(A\)\(B\) 是可交換的。

矩陣加速

P1962 斐波那契數列

一道非常基礎的矩乘矩陣加速模板題呢~

注意到數據范圍是 \(1 \leq n \leq 2^{63}\) ,肯定不能直接進行常規遞推求解。

  • \(Fib(n)\) 表示矩陣 \(\begin{bmatrix}F_n & F_{n-1}\end{bmatrix}\)

  • \(base\) 使得 \(Fib(n-1) \times base = Fib(n)\) ,即 \(\begin{bmatrix}F_{n-1} & F_{n-2}\end{bmatrix} \times base = \begin{bmatrix}F_n & F_{n-1}\end{bmatrix}\)

斐波那契數列的遞推式為 \(F_n = F_{n-1} + F_{n-2}\)

如果要使得矩陣進行乘法時能令 \(F_{n-1}\)\(F_{n-2}\) 相加,得出 \(F_n\),那么 \(base\) 矩陣的第一列一定為 \(\begin{bmatrix}1 \\ 1\end{bmatrix}\)

同理,如果要計算 \(F_{n-1}\)\(base\) 矩陣的第二列一定為 \(\begin{bmatrix}1 \\ 0 \end{bmatrix}\)

綜上所述,

\[base = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix} \]

原式可化為

\[\begin{bmatrix} F_{n-1} & F_{n-2} \end{bmatrix} \times \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix} = \begin{bmatrix} F_n & F_{n-1} \end{bmatrix} \]

代碼:

/*

Name: P1962 斐波那契數列

Solution: 矩陣加速
   

By Frather_

*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

#define Kmod 1000000007
#define int long long

using namespace std;
/*==================================================快讀*/
inline int read()
{
    int X = 0, F = 1;
    char CH = getchar();
    while (CH < '0' || CH > '9')
    {
        if (CH == '-')
            F = -1;
        CH = getchar();
    }
    while (CH >= '0' && CH <= '9')
    {
        X = (X << 3) + (X << 1) + (CH ^ 48);
        CH = getchar();
    }
    return X * F;
}
/*===============================================定義變量*/
int n;
struct Matrix
{
    int z[3][3];
    void init()
    {
        memset(z, 0, sizeof z);
    }
} base, ans;

/*=============================================自定義函數*/
void prepare()
{
    ans.init();
    ans.z[1][1] = 1;
    ans.z[1][2] = 1;

    base.init();
    base.z[1][1] = 1;
    base.z[1][2] = 1;
    base.z[2][1] = 1;
}

Matrix mul(Matrix a, Matrix b)
{
    Matrix res;
    res.init();
    for (int i = 1; i <= 2; ++i)
        for (int j = 1; j <= 2; ++j)
            for (int k = 1; k <= 2; ++k)
                res.z[i][j] = (res.z[i][j] + a.z[i][k] * b.z[k][j]) % Kmod;
    return res;
}

void Qpow(int b)
{
    while (b)
    {
        if (b & 1)
            ans = mul(ans, base);
        base = mul(base, base);
        b >>= 1;
    }
}
/*=================================================主函數*/
signed main()
{
    prepare();

    n = read();
    // if (n <= 2)
    // {
    //     printf("1\n");
    //     return 0;
    // }

    Qpow(n - 1);

    printf("%lld\n", ans.z[1][2] % Kmod);
    return 0;
}

感謝巨佬 @KnightL 為代碼優化做出的貢獻!!

P1939 【模板】矩陣加速(數列)

上一題的推廣版,思路相同。

代碼:

/*

Name: P5550 Chino的數列

Solution: 
   

By Frather_

*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

// #define int long long

using namespace std;
/*==================================================快讀*/
inline int read()
{
    int X = 0, F = 1;
    char CH = getchar();
    while (CH < '0' || CH > '9')
    {
        if (CH == '-')
            F = -1;
        CH = getchar();
    }
    while (CH >= '0' && CH <= '9')
    {
        X = (X << 3) + (X << 1) + (CH ^ 48);
        CH = getchar();
    }
    return X * F;
}
/*===============================================定義變量*/
int n, s, m, k;

struct Matrix
{
    int z[100][100];
    Matrix()
    {
        memset(z, 0, sizeof z);
    }
} base, ans;

/*=============================================自定義函數*/
inline Matrix mul(Matrix a, Matrix b)
{
    Matrix res;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            for (int k = 1; k <= n; k++)
                res.z[i][j] += a.z[i][k] * b.z[k][j];
    return res;
}

inline Matrix Qpow(Matrix a, int p)
{
    Matrix res;
    for (int i = 1; i <= n; i++)
        res.z[i][i] = 1;
    while (p)
    {
        if (p & 1)
            res = mul(res, a);
        a = mul(a, a);
        p >>= 1;
    }
    return res;
}
/*=================================================主函數*/
signed main()
{
    n = read();
    s = read();
    m = read();
    k = read();
    for (int i = 1; i <= n; i++)
    {
        ans.z[1][i] = read();
        base.z[i % n + 1][i] = 1;
    }
    swap(base.z[s], base.z[m]);
    ans = mul(ans, Qpow(base, k));

    for (int i = 1; i <= n; i++)
        printf("%d ", ans.z[1][i]);
    puts("");
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM