编程中,经常出现正交这个词。正交指相互独立,不可替代,并且组合起来可实现其它功能。
为什么相互独立,会使用正交这个词呢?
正交,最开始是数学术语,被引到计算机领域。正交英文是 orthogonal,本意是垂直,几何概念。线性代数中,两向量正交指它们内积为 0。而函数正交,是指两个函数相乘的积分为 0。
但就算知道这些,还是不明白正交是什么,数学上的正交概念跟编程上的正交概念有什么关系呢?
原则
无论什么领域,表象都是无穷无尽的,会出现各种情形。假如出现情形 A, 就单独去研究情形 A;出现情形 B, 就单独去研究情形 B,各种情形分别去解决,根本就没有尽头。
人们不会单纯研究表象,而是不断简化,最终产生几条最基本的原理,和一套基本原理的组合法则。这几条原理相互独立,不可再进行简化。假如 C 原理可以用 A、B 原理组合起来表示,这样 C 原理就不是最基本的。
于是知道基本原理和组合规则,其它表象就可以归结成基本原理和基本组合法则的重复推演。这样只要研究好基本原理,研究好组合规则,其它的表象可以一大批统一地解决了。
向量正交
相同的思路,应用到向量。
所有的向量构成一个空间,而所有的向量是无穷无尽的。一个个向量分别分析也自然没有尽头。这样我们挑选几个相互独立的基本向量,再定义一套组合规则。这样其它的向量,就用基本向量组合起来表示。
于是很自然地产生问题,基本向量是什么?如何才叫相互独立?组合规则是什么?
对于向量空间,组合规则其实就是线性叠加。乘法和加法很基本,不同的领域常常会重新定义类似乘法的概念和类似加法的概念。在线性叠加中,类似乘法的概念,就是向量的内积,当内积为 0 表示两个向量相互独立。
假设 A、B 为基本向量,C 可以用 A、B 叠加起来表示。于是
C = a * A + b * B
两边乘以 B,得到
C * B = a * A * B + b * B * B
这里的乘法符号其实是内积,假如 A * B = 0,就可以消去第一项,系数 b 就只和 C 和 B 有关。而当 B * B = 1 时,可以再次简化计算过程。
当将二维向量几何化后,内积为 0,两个向量刚好正交(orthogonal)。另外一个术语就是平行,跟正交对应。平行表示完全相关,正交表示完全不相关,有时会处于平行是正交之间,它们的夹角可以表示相关程度。
当 A * B = 0 ,A、B 正交;B * B = 1,B 标准化,也叫归一化。当正交归一的向量,作为独立的基本向量,线性叠加成其它向量。会使得计算过程大大简化。
函数正交
将相同的思路,应用到函数。
所有函数构成函数空间,取一些基本的、正交的函数,再定义组合规则。每个具体领域,加法和乘法的含义有所不同。对于函数,类似于乘法的概念是积分。两函数的正交,就是相乘后积分为 0。当 f(x)、t(x) 作为基本函数,这样 k(x) 用两个函数叠加的方式来表示。
k(x) = a f(x) + b t(x)
这时需要求出系数 a 和 b 的。可以两边先乘以 f(x), 得出,
k(x) * f(x) = a f(x) * f(x) + b t(x) * f(x)
当 f(x) 和 t(x) 正交,两边取积分,就可以消去,t(x) * f(x)。这样系数 a 就只会跟 k(x) 和 f(x) 有关系。
还可以有多个函数相互正交,甚至无限多个函数正交。比如选取 cos、sin,作为基本函数,叠加起来表示其它函数,就演变成了傅里叶变换。
编程上的正交
从数学上引进正交这个词,用于表示指相互独立,相互间不可替代,并且可以组合起来实现其它功能。比如 if 和 for 语句是正交的,但 for 和 while 语句的功能是有重叠的。逻辑运算 not、and、or 也是正交的,其它复杂的逻辑运算都可以用这三种基本运算叠加起来。
编程语言经常定义一组正交语法特性,相互间不可替代,组合起来可以其它功能。而为了更方便使用,在基础特性之上,再添加一些额外特性。这些非基本的额外特性,称为语法糖(Syntactic sugar)。语法糖对语言的功能没有太大影响,有可以,没有也可以,但有了之后,代码写起来更方便些。