Skip to content

Commit

Permalink
Merge pull request #4 from wandering-the-earth/main
Browse files Browse the repository at this point in the history
修改salon,完全OK了
  • Loading branch information
wandering-the-earth authored Apr 22, 2024
2 parents 59bde02 + 8e01616 commit 071500d
Showing 1 changed file with 68 additions and 26 deletions.
94 changes: 68 additions & 26 deletions docs/salon/线性代数在计算机的一些应用.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
---
tags:
- Crypto
- 计算机图形学
- 算法
- 线性代数
categories: 计算机基础
title: 线性代数的一些应用
mathjax: "true"
---

内容:线性代数的应用,包含(计算机图形学,算法,密码学的相关内容)

前置基础:矩阵乘法
## 算术,代数,算法 | arithmetic, algebra, algorithm
先简单的引入一下,从小学的 **算术** 到中学的 **代数** 这两者之间的差别。

- 小学的算术
- $(3 + 7) \times 5= 10\times5$
- $753+672=1300+120+5=1425$
- 中学的代数
- $x^2-2x-3=0\to x\in\{-1,3\}$

#### 为什么算术比代数简单?

- 算术运算的结果是确定的——会变越来越简单。

- 代数运算是没有办法去定义“好”运算的。

- $x^2-2x-3=x^2-2x+1-4$

#### 什么是算法
算法是一种自动工作的流程,按照小步工作进行自动运算。
比如下面这道题目。
题目:[Problem - B - Codeforces](https://codeforces.com/contest/985/problem/B)这是 Codeforces 周赛 `div2` 的一道题目,比较简单,大家可以简单的思考一下
题目:
[Problem - B - Codeforces](https://codeforces.com/contest/985/problem/B)

这是 Codeforces 周赛 `div2` 的一道题目,比较简单,大家可以简单的思考一下

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402052231698.png)

英文看着很长,实际题目很简单,有 `n` 个开关和 `m` 盏灯,只要存在一个控制这个灯是开着的这个等就会被点亮。
Expand All @@ -35,17 +37,21 @@ mathjax: "true"

那么这个思路从线性代数的角度怎么看呢……
就是求线性无关组,如果在线性无关组里面就是 `NO`,如果不在线性无关组里面就是 `YES`,当然线性无关组在这里是唯一的。

线性无关组代表没有**冗余的信息**,这些信息都是线性无关的,也就是向量之间无法用彼此之间相互表达的含义,因此,在题目里,就是检测有没有开关是冗余的。

> 源码实现可以参考 `Python numpy` 里面的 `matrix_rank` 函数实现。在 $linalg/\_linalg.py$ 目录下的 $1973$ 行
这是线性代数的思想在算法竞赛里的一个简单应用。

## 线性算术 | Linear Arithmetic

略过基础性的向量加减运算,我们先重新复习一下数乘。
$$
2\times\begin{bmatrix}1\\2\end{bmatrix} = \begin{bmatrix}2\\4\end{bmatrix}
2 \times\begin{bmatrix}1\\\2\end{bmatrix} = \begin{bmatrix}2\\\4\end{bmatrix}
$$
什么意思,这是一个几何上的伸缩运算,把原来的向量拉伸了 $2$ 倍,由此引到我们线性变换的内容。

## 线性变换 | Linear Transformation

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402060006223.png)
Expand All @@ -62,54 +68,59 @@ $$
$$
\vec x \times \vec y = \vec z \quad \vec y \times \vec x = -\vec z
$$
这有什么作用呢,比如在渲染的时候我可以画一个三角形,然后用向量的叉乘快速判断这个点是不是在三角形内部。(可以扩展到任意凸包,求凸包的相关算法可以用点乘,详情参询
https://oi-wiki.org/geometry/convex-hull/
这有什么作用呢,比如在渲染的时候我可以画一个三角形,然后用向量的叉乘快速判断这个点是不是在三角形内部。(可以扩展到任意凸包,求凸包的相关算法可以用点乘,详情参询https://oi-wiki.org/geometry/convex-hull/)

这里我们计算叉乘通常使用右手系,但是在 UE4 和 OpenGL 中使用的是左手系,问题不大,翻转一下就可以了。
向量的叉乘和向量的点乘都可以写成矩阵乘法的形式,可以思考一下怎么个一回事。(提示:伴随矩阵)

### 真正的变换专场
#### 缩放变换

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402062131697.png)

横轴和纵轴都变成了原来的 $\frac{1}{2}$ 用数学的语言表达呢如下
$$
x^{'} = sx \quad y^{'} = sy
$$
作为一个学过线性代数的人呢,需要学会把这个转换成为矩阵形式,就比如这个样子
$$
\begin{bmatrix}x^{'}\\y^{'}\end{bmatrix}=\begin{bmatrix}s & 0\\0&s\end{bmatrix}\begin{bmatrix}x\\ y\end{bmatrix}
\begin{bmatrix}x^{'}\\\y^{'}\end{bmatrix}=\begin{bmatrix}s & 0\\\0&s\end{bmatrix}\begin{bmatrix}x\\\ y\end{bmatrix}
$$

![](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402062140271.png)

当然,也可以不均匀的缩放,比如 $x$ 和 $y$ 一个缩小到 $\frac{1}{2}$,一个保持不变。
$$
\begin{bmatrix}x^{'}\\y^{'}\end{bmatrix}=\begin{bmatrix}s_x & 0\\0&s_y\end{bmatrix}\begin{bmatrix}x\\ y\end{bmatrix}
\begin{bmatrix}x^{'}\\\y^{'}\end{bmatrix}=\begin{bmatrix}s_x & 0\\\0&s_y\end{bmatrix}\begin{bmatrix}x\\\ y\end{bmatrix}
$$
#### 对称变换

学过**近世代数**的同学应该都知道,矩阵运算时非常符合群这个东西的定义的,但是如果从高中数学推导过来呢,群一开始诞生就是为了描述对称性这个东西的。所以矩阵应该是很轻松的就能把对称这个东西给描述出来的。

提示:可以看成是缩放的特殊情况。
#### 切变换 | Sheer
![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402062148378.png)
$$
\begin{bmatrix}x^{'}\\y^{'}\end{bmatrix}=\begin{bmatrix}1 & a\\0&1\end{bmatrix}\begin{bmatrix}x\\ y\end{bmatrix}
\begin{bmatrix}x^{'}\\\y^{'}\end{bmatrix}=\begin{bmatrix}1 & a\\\0&1\end{bmatrix}\begin{bmatrix}x\\\ y\end{bmatrix}
$$
#### 旋转变换
![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402062202768.png)
$$
R_\theta = \begin{bmatrix}\cos \theta & -\sin\theta\\sin\theta&\cos\theta\end{bmatrix}
R_\theta = \begin{bmatrix}\cos \theta & -\sin\theta\\\sin\theta&\cos\theta\end{bmatrix}
$$
#### 进行一些小总结
可以发现上述所有变换都可以写成形如
$$x^{'}=ax+by\quad y^{'}=cx+dy$$
转换成为矩阵形式也就是
$$
\begin{bmatrix}x^{'}\\y^{'}\end{bmatrix} = \begin{bmatrix}a & b\\c&d\end{bmatrix}\begin{bmatrix}x\\ y\end{bmatrix}
\begin{bmatrix}x^{'}\\\y^{'}\end{bmatrix} = \begin{bmatrix}a & b\\\c&d\end{bmatrix}\begin{bmatrix}x\\\ y\end{bmatrix}
$$
#### 平移
![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402062350459.png)
可以想一想还能不能愉快的写成一个矩阵左乘的形式了?我简洁的矩阵形式怎么没有了?
只能写成如下形式:
$$
\begin{bmatrix}x^{'}\\y^{'}\end{bmatrix} = \begin{bmatrix}a & b\\c&d\end{bmatrix}\begin{bmatrix}x\\ y\end{bmatrix}+\begin{bmatrix}t_x\\t_y\end{bmatrix}
\begin{bmatrix}x^{'}\\\y^{'}\end{bmatrix} = \begin{bmatrix}a & b\\\c&d\end{bmatrix}\begin{bmatrix}x\\\ y\end{bmatrix}+\begin{bmatrix}t_x\\\t_y\end{bmatrix}
$$
好像很简单,但是这形式和之前的不统一。也表明平移不是一个很正经的线性变换。这种不统一的形式也不适合程序员偷懒,凭啥同样是二维变换,平移就要搞特殊?

Expand All @@ -129,12 +140,15 @@ $$
因此统一形式如下
$$
\begin{bmatrix}x^{'}\\y^{'}\\1\end{bmatrix} = \begin{bmatrix}a & b & t_x\\c&d&t_y\\0&0&1\end{bmatrix}\begin{bmatrix}x\\ y\\1\end{bmatrix}
\begin{bmatrix}x^{'}\\\y^{'}\\\1\end{bmatrix} = \begin{bmatrix}a & b & t_x\\\c&d&t_y\\\0&0&1\end{bmatrix}\begin{bmatrix}x\\\ y\\\1\end{bmatrix}
$$
希望写到这里能更好的帮你理解很多教科书上突然冒出的 **四元数** 这个奇妙的概念,因为那是在三维空间中,额外升了一维。(01作业光栅化展示)

但是这远远不是图形学,他只是入门,甚至门都没有入。更深一点的比如摄像头的旋转,视图的变换都没有讲到,这些依旧属于矩阵变换的范畴,6个自由度导致矩阵越来越难写,所以对线性代数的功底提出了很高的要求。
光栅化,光线追踪,辐射度量学,基于物理的渲染,以及到最后进行游戏引擎的开发,需要数据结构,需要算法,需要为了更逼真的图片去榨干GPU的性能。这都是图形学。中国科技大学有一套属于自己的图形学Lab,西安交通大学在2024年也在逐步开发自己的图形学作业代码框架,上海交通大学和浙江大学会在本科阶段讲一点蒙特卡洛渲染的内容。正视差距,努力进步。

光栅化,光线追踪,辐射度量学,基于物理的渲染,以及到最后进行游戏引擎的开发,需要数据结构,需要算法,需要为了更逼真的图片去榨干GPU的性能。这都是图形学。

中国科技大学有一套属于自己的图形学Lab,西安交通大学在2024年也在逐步开发自己的图形学作业代码框架,上海交通大学和浙江大学会在本科阶段讲一点蒙特卡洛渲染的内容,正视自己与其他学校本科生之间的差距,努力进步。

图形学是概率论,微积分,线性代数,物理学都需要的一门学科,反正感觉挺好玩的,比如蒙特卡洛积分。
> talk is cheap, show me the code
Expand Down Expand Up @@ -175,7 +189,10 @@ long long quick_pow(long long a, long long b)
$$
\begin{bmatrix}F_{n-1} & F_{n-2}\end{bmatrix}\begin{bmatrix}1&1\\\1&0\end{bmatrix} = \begin{bmatrix}F_{n} & F_{n-1}\end{bmatrix}
$$
定义初始矩阵 $\text{ans} = \begin{bmatrix}F_2 & F_1\end{bmatrix} = \begin{bmatrix}1 & 1\end{bmatrix}, \text{base} = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}。那么,F_n 就等于 \text{ans} \text{base}^{n-2}$ 这个矩阵的第一行第一列元素,也就是 $\begin{bmatrix}1 & 1\end{bmatrix} \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{n-2}$的第一行第一列元素。
定义初始矩阵 $\text{ans} = \begin{bmatrix}F_2 & F_1\end{bmatrix} = \begin{bmatrix}1 & 1\end{bmatrix}, \text{base} = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}。$
那么,$F_n 就等于 \text{ans} \text{base}^{n-2}$ 这个矩阵的第一行第一列元素,也就是 $\begin{bmatrix}1 & 1\end{bmatrix} \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}^{n-2}$的第一行第一列元素。
```C++
const int mod = 1000000007;
Expand Down Expand Up @@ -218,7 +235,7 @@ int main() {
##### HDU 1005 Number Sequence
$\text{给出一个数列定义如下:}f(1)=1,f(2)=1,f(n)=Af(n-1)+Bf(n-2),\text{计算}f(n)$
$$
\begin{bmatrix}F(n-1) \\ F(n-2)\end{bmatrix}\begin{bmatrix}A&B\\1&0\end{bmatrix} = \begin{bmatrix}F(n) \\ F_(n-1)\end{bmatrix}
\begin{bmatrix}F(n-1) \\\ F(n-2)\end{bmatrix}\begin{bmatrix}A&B\\\1&0\end{bmatrix} = \begin{bmatrix}F(n) \\\ F_(n-1)\end{bmatrix}
$$
##### LightOJ 1070 Algebraic Problem
给出 $a+b$ 和 $ab$ 的值,求$a^n+b^n$ 答案对 $2^{64}$ 取模
Expand All @@ -230,7 +247,7 @@ $$
$$
于是,令 $A =a+b,B=ab,F(n) =a^n+b^n$,有
$$
\begin{bmatrix}A&-B\\1&0\end{bmatrix}\begin{bmatrix}F(n) \\ F(n-1)\end{bmatrix} = \begin{bmatrix}F(n+1) \\ F_(n)\end{bmatrix}
\begin{bmatrix}A&-B\\\1&0\end{bmatrix}\begin{bmatrix}F(n) \\\ F(n-1)\end{bmatrix} = \begin{bmatrix}F(n+1) \\\ F_(n)\end{bmatrix}
$$
所以这也是一种迭代的思想(牛顿迭代法算根号)
矩阵快速幂可以用来加速动态规划,还有广义的矩阵乘法以及转移矩阵的相关操作,但是这里不想涉及,因为有点超纲了,有的还是控制论那边的内容。
Expand All @@ -246,7 +263,7 @@ Google 成功的秘诀:为互联网上所有的页面重要性排序
- 在每个网页都随机点击链接
- $Ax = x$ 就是稳定的 “概率分布” ($A^{\infty}$ 恰好是它的解,maybe有点类似信息论里的马尔科夫信源)
$$
A= \begin{bmatrix}0&0&1&\frac{1}{2}\\\frac{1}{3}&0&0&0\\\frac{1}{3}&\frac{1}{2}&0&\frac{1}{2}\\\frac{1}{3}&\frac{1}{2}&0&0\end{bmatrix}\ \ \ \ \ \ \ \ \ \ \ \ \ \ x=\begin{bmatrix}0.387\\0.129\\0.290\\0.194\end{bmatrix}
A= \begin{bmatrix}0&0&1& \frac{1}{2} \\\\ \frac{1}{3}&0&0&0 \\\\ \frac{1}{3}&\frac{1}{2}&0&\frac{1}{2} \\\\ \frac{1}{3}&\frac{1}{2}&0&0\end{bmatrix}\ \ \ \ \ \ \ \ \ \ \ \ \ \ x=\begin{bmatrix}0.387\\\0.129\\\0.290\\\0.194\end{bmatrix}
$$
### 推荐系统
推荐系统:如何为你预测对商品的评分?
Expand All @@ -257,6 +274,7 @@ $$
| 橙子 |||| 3 |
| 香蕉 | 3 ||||
| 西瓜 | 5 | 4 |||

矩阵分解:$M_{m\times n}=P_{m\times k}\times Q_{k\times {n}}$​
$k$ 是隐藏的 “维度” (Latent factor model)
- 如果 $k$ 很小,我们就有足够的数据求解出 “最合适” 的 $P$ 和 $Q$
Expand All @@ -268,9 +286,12 @@ $k$ 是隐藏的 “维度” (Latent factor model)

先介绍一下格密码的成就(?)
已经公布的4个NIST抗量子标准优胜算法中,有3个是格密码,占比达到了惊人的**75%**,遥遥领先于其他算法。(截止到2022年9月)

在 7 个正式入选第三轮的算法中,有5个都属于格密码的范畴,而与此同时,在我国2019年密码学会举办的后量子密码算法竞赛中,格密码也在其中占据了相当大的比例。

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072146174.png)
近代格密码的时间线

- 1982:LLL basis reduction theorem
- 使用Lattice来做Cryptanalysis
- 1996:Ajtai-Dwork
Expand All @@ -283,6 +304,7 @@ $k$ 是隐藏的 “维度” (Latent factor model)
#### Lattice是什么?
Lattice可以被想象成是一个空间中很多有规律分布的、离散的点。
$n$维空间中最简单的 Lattice 就是 Integer Lattice(整数格)。整数格中最简单的就是基于笛卡尔坐标系的$i,j$...等基向量组成的空间。

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072201353.png)
#### Lattice与Bases(格与基)
更好的描述一个格的方法是使用基向量。
Expand All @@ -301,31 +323,44 @@ $n$维空间中最简单的 Lattice 就是 Integer Lattice(整数格)。整

随后,我们可以把这个多面体复制多份,然后平移到每一个Lattice中的点上。这样我们就会得到很多份 $P$,并且这些多面体可以平分整个多维空间 $R^n$。
![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072215117.png)

此时,我们如果在这个空间中任意的画一个球体(多维空间即超球体),然后可以数数看这个球体中覆盖了多少Lattice里的点。点的数量平均于球体的体积,就是这个格的密度了。
#### 最短距离
我们一般用 $\lambda_1$ 来定义整个格中点与点之间最短的距离。一般为了方便理解,我们就把其中的一个点设置成坐标轴 $O$ 点,然后 $\lambda_1$就变成了距离 $O$ 点距离最近的格点。

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072220497.png)

#### 距离函数与覆盖半径
给定任意一个点 $t$(这个点不需要在Lattice上),我们可以定义距离函数 $\mu(t,L)$ 为这个点到附近的Lattice点的最短距离。

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072223477.png)

同理可得,我们也可以左右移动 $t$ 的位置,然后就可以找到在这个 Lattice 中可以得到的最大的 $\mu$。我们一般称这个最大值叫覆盖半径(Covering Radius)。
直到所有的圆正好完美的覆盖了所有的空间的时候,这个时候的半径,就是我们之前得到的 $\mu$ 了。这就是覆盖半径这一名字的由来。

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072225689.png)

#### Minkowski凸集定理
最重要的用处就是给出一个Lattice中最短向量的一个上限值。理解这个玩意可能需要引入凸包的概念,就给结论吧。
#### SVP问题(Shortest Vector Problem)
顾名思义,**最短向量问题(SVP,Shortest Vector Problem)** 就是在格中找到“长度”最短的向量。
一个很直观的想法,如果我们手上的格基是相互正交的,那么我们只需要遍历格基中的各个向量就可以找到最短的向量了。

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072231319.png)

于是我们就发现了这个惊天秘密:**为了找到最短向量,就要尽量使得格基正交**
#### CVP问题(Closest Vector Problem)
Lattice中另一大问题就是最近向量问题(CVP,Closest Vector Problem)了。问题的定义是这样的:给定连续空间中任意的一个点 $t$ ,找到距离这个点最近的格点 $B_x$
#### CVP → SVP
如果能够一招鲜吃遍天,那何乐而不为呢?另外就是因为日益增长的攻击手法和不太够的脑容量之间的矛盾。
为了方便演示,假设我们有一个一维的格,然后我们需要找到距离点 $t$ 最近的格点 $B_x$

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072234181.png)

那么我们可以进行一个类似于“升维”的操作,使得 $t$ 点也成为新格的一个格点。

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402072236926.png)

然后在这个新格中我们解决一下 **SVP**,找到最短向量,然后再将这个最短向量投影回原来的低维中,我们就能找到原来格中距离 $t$ 最近的格点 $B_x$ 了。
于是压力来到解决 **SVP** 这边,而我们之前也说了,“为了找到最短向量,就要尽量使得格基正交”,于是压力又来到 **找到正交基** 这边。(施密特正交化用在哪里有点数了哈)
#### LLL 算法
Expand All @@ -339,11 +374,18 @@ Lattice中另一大问题就是最近向量问题(CVP,Closest Vector Problem
二分图,网络流啥的,由于算法竞赛退役多年,人菜,留待后人补充。(相信后人的智慧)
# 参考 | Reference
南大蒋炎岩老师对中学生JSNOI分享: https://jyywiki.cn/OI/

闫令琪老师的Games101: https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html

3blue1brown: https://www.3blue1brown.com/

Zach数学系列: https://www.youtube.com/watch?v=i8FukKfMKCI&t=110s

Van1sh的博客:[http://jayxv.github.io/2023/10/17/密码学基础之格中难题与格基规约/](https://jayxv.github.io/2023/10/17/%E5%AF%86%E7%A0%81%E5%AD%A6%E5%9F%BA%E7%A1%80%E4%B9%8B%E6%A0%BC%E4%B8%AD%E9%9A%BE%E9%A2%98%E4%B8%8E%E6%A0%BC%E5%9F%BA%E8%A7%84%E7%BA%A6/ "密码学基础之格中难题与格基规约")

Steven Yue的文章: [ Steven Yue - 知乎 (zhihu.com)](https://www.zhihu.com/people/steven-yue-72)

2020年Simons格密码讲座:[Lattices: Algorithms, Complexity, and Cryptography Boot Camp (berkeley.edu)](https://simons.berkeley.edu/workshops/lattices-algorithms-complexity-cryptography-boot-camp#simons-tabs)

![image.png](https://cdn.jsdelivr.net/gh/wandering-the-earth/blog-img//blog/202402061102688.png)

0 comments on commit 071500d

Please sign in to comment.