找回密码
 立即注册
搜索
查看: 200|回复: 0

线性代数:抽象与应用的数学世界,你真的了解吗?

[复制链接]

9420

主题

0

回帖

2万

积分

管理员

积分
28470
发表于 2024-11-3 21:51:30 | 显示全部楼层 |阅读模式
什么是线性代数?

在大学数学学科中,线性代数是最抽象的课程。从初等数学到线性代数的思维跨度比微积分和概率统计要宽得多。很多人在学习之后,始终停留在知其然不知其所以然的阶段。几年后,他们接触到图形编程或机器学习等领域,发现线性代数的应用无处不在,但苦于无法很好地理解和掌握。事实上,大多数人都能轻松理解初等数学的各种概念。函数、方程和数列都是那么自然。然而,一旦进入线性代数的世界,就好像进入了另一个陌生的世界,周围都是各种奇怪的符号和运算。迷失在.

当我第一次接触线性代数时,我觉得这是一门非凡的学科。我的脑海中浮现出一个问题:

如果当你看到这个问题时,你的反应是“不用问,数学当然是客观自然规律”。我一点也不觉得奇怪。我自己也是这么想的。从中学的基础数学、基础物理开始,很少有人怀疑数学学科是否是自然规律。当我学习微积分和概率统计时,我从来没有怀疑过这一点。只有线性代数才让我怀疑。 ,因为它的各种符号和运算规则太过抽象和陌生,根本无法与生活经验相对应。因此,我真的要感谢线性代数,它引发了我对数学学科本质的思考。其实,不仅是学生,很多数学老师也不知道线性代数是什么,它的用途是什么。不仅在国内如此,在国外也是如此。国内的孟岩写了《理解矩阵》,国外的Axler教授写了《《线性代数应该这样学》》,但是线性代数的来龙去脉都没有从根本上讲清楚。对于我自己来说,我没有学过线性我在大学的时候学过代数,但后来我从编程的角度理解了它,很多人说好的数学可以帮助我编程,但对我来说恰恰相反,理解编程可以帮助我理解数学。

本文的目标读者是程序员。下面我就带大家来一场程序员在线性代数世界的深度探险!既然我们是程序员,在进入线性代数领域之前,不妨先考察一下编程世界。请大家思考一下这个问题:

为什么要问这么一个看似愚蠢的问题呢?因为答案很明显,大家对日常使用的编程语言的理解一定比抽象线性代数更好。显然,编程语言虽然含有内在的逻辑,但本质上都是人为的设计。所有编程语言的共同点是它们建立了一组模型,定义了一组语法,并将每种语法映射到特定的语义。程序员和语言实现者之间遵守语言契约:程序员确保代码符合该语言的语法,编译器/解释器确保代码执行的结果符合该语法对应的语义。例如,C++规定使用new A()语法在堆上构造对象A。如果这样写C++,必须保证相应的执行效果,在堆上分配内存并调用A的构造函数,否则编译器违反了语言契约。

从应用的角度来看,我们是否可以将线性代数视为一种编程语言?答案是肯定的,我们可以以语言契约为标准来尝试一下。假设你有一张图像,你想将其旋转 60 度并沿 x 轴拉伸 2 倍;线性代数告诉你,“好吧!你按照我的语法构造一个矩阵,然后按照矩阵乘法规则相乘你的矩阵。图像和我保证结果会是你想要的”。事实上,线性代数非常类似于DSL 与 SQL 类似,下面是一些类比:

因此,从应用的角度来看,线性代数是人类设计的一种领域特定语言(DSL),它建立一套模型,通过符号系统完成语法和语义的映射。事实上,向量、矩阵的语法和语义以及运算规则都是人为设计的。这和语言中的各种概念是一样的。是创造,但前提是必须满足语言契约。

为什么是线性代数?

有些人可能担心将线性代数视为 DSL。我给你一个矩阵,你将我的图形旋转 60 度并沿 x 轴拉伸它 2 倍。我总是感到不安,我什至不认识你。如何做到“底”!其实这就像有些程序员在使用高级语言时不踏实一样。他们觉得底层才是程序的本质。他们总是想知道这句话编译成汇编后是什么样子?为该操作分配了多少内存?别人只要在Shell中输入wget命令就可以获取网页,而他却要花几十分钟用C语言写一堆代码才可以做到。其实,所谓底层和上层只是一种习惯说法,并不意味着一个比另一个更本质。程序编译和解释本质上是不同模型之间的语义映射。通常,高级语言被映射到低级语言,但方向也可以颠倒过来。我写了一个虚拟机,并在虚拟机上运行Linux。这是将机器模型映射到模型。

建立新模型当然依赖于现有模型,但这只是建模的手段而不是目的。任何新模型的目的都是为了更简单地分析和解决某一类问题。当线性代数建立起来时,它的各种概念和运算规则都依赖于初等数学的知识。然而,一旦建立了这一层抽象模型,我们就应该习惯于直接使用高层抽象模型来分析和解决问题。线性代数比初等数学更容易分析和解决问题。我们通过一个例子来实际感受一下它的好处:

初等数学中最著名的三角形面积计算公式是面积=1/2*底*。当三角形的一条边恰好在坐标轴上时,我们可以很容易地计算出它的面积。但是,如果我们旋转同一个三角形的坐标轴,使其边不在坐标轴上呢?我们还能得到它的底边和高度吗?答案肯定是肯定的,但是显然很复杂,很多情况下需要单独讨论。

相反,如果我们利用线性代数知识来解决这个问题,那就非常容易了。在线性代数中,两个向量a和b的叉积(Cross)是方向垂直于a和b且大小等于a和b形成的平行四边形面积的向量:



我们可以将三角形的边视为向量,因此三角形的面积等于两个边向量的叉积向量的长度除以二:

注:它表示向量的长度和两个向量的叉积。

初等数学中这么难的问题,用线性代数就能瞬间解决!有人可能会说,如果直接根据叉积来做,当然简单,但是叉积本身不是挺复杂的吗?你为什么不尝试展开它呢?是的,模型的作用就是将部分复杂性隐藏到模型中,以便模型的使用者能够更简单地解决问题。曾经有人质疑C++太复杂了。 C++之父是这样回应的:

在特定的环境中,问题的复杂程度是由其性质决定的。 C++将部分复杂性融入到语言和标准库中,以使应用程序更简单。当然,C++ 并不会在所有情况下都使问题变得更简单,但原则上,C++ 的复杂性是有道理的。除了C++之外,还有Java、SQL、CSS等各种语言和框架,想象一下如果不使用数据库,自己做数据存储和管理该是多么复杂!这样,我们就不难理解为什么线性代数定义了叉积等奇怪的运算。它就像C++将许多常用的算法和容器融入到STL中一样。同样,您甚至可以在线性代数中定义所需的运算并重用它们。因此,数学一点也不僵化。就像节目一样生动。一旦了解了它的来龙去脉,你就能驾驭自如。说到这里,我们顺便回答一个很常见的疑问:

事实上,就像程序复用一样,线性代数定义了点积、叉积和矩阵运算,因为它们应用广泛,具有很大的复用价值,可以作为我们分析和解决问题的基础。例如,很多问题涉及到一个向量到另一个向量的投影或者求两个向量之间的角度,那么你就会考虑专门定义点积(Dot)运算:

点积的概念是一种设计,有创意的空间;一旦设计确定,具体公式就不能随意使用,必须符合逻辑,以保证其映射到初等数学模型的正确性。这就像高级语言可以定义很多概念,比如高阶函数、闭包等,但它必须保证映射到底层实现时执行过程中产生的效果符合其定义的规范。

线性代数有什么好处?

如上所述,线性代数是一种高级抽象模型。我们可以用学习编程语言的方法来学习它的语法和语义。然而,这种理解不仅适用于线性代数,而且适用于所有数学学科。是的,有些人可能会有疑问

这从根本上询问了线性代数的核心:向量模型。我们在初等数学中学到的坐标系属于笛卡尔提出的解析模型。这个模型非常有用,但也有很大的缺点。坐标系是人为添加的虚拟参考系,但我们要解决的问题,如面积计算、图形旋转、拉伸等应用,与坐标系无关。建立虚拟坐标系往往无助于解决问题。这就是刚才三角形面积的例子。

矢量模型很好地克服了解析模型的缺点。如果说解析模型代表了某种“绝对”世界观,那么矢量模型则代表了某种“相对”世界观。我建议将矢量模型和解析模型结合起来。被视为两个对立的模型。

矢量和标量的概念在矢量模型中定义。向量有大小和方向,满足线性组合定律;标量是只有大小而没有方向的量(注:标量的另一个更深刻的定义是在旋转变换下保持不变的量)。矢量模型的优点之一是它的坐标系独立性,即相对性。它在定义向量和运算规则时从一开始就抛开了坐标系的约束。不管你怎么旋转坐标轴,我都能适应。 、向量的线性组合、内积、叉积、线性变换等操作都是与坐标系无关的。注意,所谓坐标系独立并不是说没有坐标系,还是有的。刚才三角形例子的顶点是用坐标来表示的,但是不同的坐标系在解决问题时不会产生影响。用一个比喻来说,Java 声称是平台无关的。这并不是说Java是空中楼阁,而是说当你用Java编程时,底层的Linux是否是Linux往往对你没有影响。

矢量模型有什么好处?除了刚才以三角形面积问题为例外,我再举一个几何例子:



如果要从解析几何的角度来解决这个问题,几乎一开始就太复杂了,除非是平面恰好穿过坐标轴的特殊情况,但如果从矢量模型来思考,很简单:根据平面方程,平面 ( ) 的法向量为 v=(a, b, c),假设从任意点 (x, y, z) 到 (x0, y0, z0)在平面上是w,则计算w 到 v 的投影向量 p 的大小是 (x0, y0, z0) 到平面 a*x + b*y + c*z + d = 0 的垂直距离。使用向量模型的基本概念这里:法向量、投影向量和点积。整个解题过程简单明了。

下面我给大家做一个类似的练习(熟悉机器学习的朋友可能会发现,这就是线性代数在线性分类中的应用):

抛开向量,我们来介绍一下线性代数的另一个主角:()。

线性代数定义了矩阵与向量、矩阵与矩阵的乘法。操作规则非常复杂,并且不清楚它们是做什么用的。许多初学者不能很好地理解它们。可以说,矩阵是学好线性代数的拦路虎。遇到复杂的事情时,往往需要避免陷入细节,先从整体上把握。其实从程序的角度来看,无论形式多么奇怪,无非就是语法,而语法必须对应语义,所以理解矩阵的重点是理解它的语义。矩阵有不止一种语义。它在不同的环境中有不同的语义,在同一环境中也可以有不同的解释。最常见的包括:1)表示线性变换; 2) 表示列向量或行向量的集合。 ;3) 表示子矩阵的集合。

矩阵整体对应线性变换语义:矩阵A乘以向量v得到w,矩阵A表示从v到w的线性变换。例如,要将向量v0逆时针方向旋转60度得到v',只需将v0乘以旋转变换矩阵( )即可。

除了旋转变换之外,拉伸变换也是常见的变换。例如,我们可以通过拉伸矩阵将向量沿x轴拉伸2倍(请尝试自己给出拉伸矩阵的形式)。更重要的是,矩阵乘法有一个很好的性质:它满足结合率,这意味着线性变换可以叠加。例如,我们可以将“逆时针旋转60度”的矩阵M与“沿x轴拉伸2次”的矩阵N相乘,得到一个新的矩阵T,表示“逆时针旋转60度并沿x轴拉伸” “将 x 轴拉伸 2 次”这与通过 Shell 中的管道叠加多个命令非常相似吗?

上面重点讨论的是矢量模型的坐标系独立性。另外,向量模型的另一个优点是可以描述线性关系。让我们看一个熟悉的序列示例:

首先,我们构造两个向量 v1=(f(n+1), f(n)) 和 v2=(f(n+2), f(n+1))。根据序列性质,我们可以得到从v1到v2的递归变换矩阵:

并进一步得到:

这样,线性递推问题就转化为矩阵n次方的经典问题,可以在O(log n)时间复杂度内求解。除了线性递归序列之外,初等数学中著名的n维线性方程组问题也可以转化为矩阵和向量乘法的形式来更容易求解。这个例子是为了说明,任何满足线性关系的系统都是向量模型的用武之地。我们通常可以将其转换为线性代数,以获得简单而有效的解决方案。

总结

本文提出一个观点:从应用的角度来看,我们可以将线性代数视为一种特定领域的编程语言。线性代数在初等数学的基础上建立了向量模型,定义了一套语法和语义,并符合编程语言的语言契约。矢量模型具有坐标系独立性和线性性。它是整个线性代数的核心,也是解决线性空间问题的最佳模型。向量的概念、性质、关系和变换是掌握和应用线性代数的重点。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|【科创星域】 ( 京ICP备20013102号-15 )

GMT+8, 2025-5-6 06:48 , Processed in 0.063978 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表