本来应该接着讲离散系统的混沌现象,但在这之前势必要讲动力学系统的临界现象和分岔,而分岔指的就是动力学系统相图的分岔

动力学系统 相图 (phase diagram) 的定义一句话可以说完:

相图是以动力学系统的驻点为因变量,参数为自变量的函数图像。

但这要求读者清楚 因变量 (dependent variable)、自变量 (independent variable)、参数 (parameter) 等等概念。现在是人工智能的时代了,还有个 超参数 (hyperparameter) 的概念也经常被人提起。

它们统统依附于“函数 (function)”这一概念。

函数/映射

戈德门特《代数学教程》(高教社版):

设 X 和 Y 是两个集合,称令 X 中的每一个元素 x 对应 Y 的一个[按一个确定的规律依赖 x 的]元素 y 的运算为定义在集合 X 上在 Y 内取值的函数

括号是我自己加的,不加简直可以拿去考语文阅读理解,整本书的翻译都有这个问题。

简而言之,函数是一种运算。

以上定义是戈德门特《代数学教程》中批评的靶子,罪名是“包含数学上未曾定义过的词汇,例如‘令……对应’意指什么?轻信这个定义,就会又一次仅仅得到一个文字游戏”。然后给出了一个花了一节半内容铺垫的,完全基于集合论的定义。

数学家眼中的 bug,在科学家眼中简直是 feature。数学上未曾定义过的概念,在日常用语中往往有约定俗成的语义,科学要用的数学太多太杂了,辩经的功夫能省一点是一点吧~

写这篇文章的时候回去查了一下现在的中学课本,函数的定义出现过两次:

  • 人教版八年级下册,甚至早于集合的定义,直接把函数定义成了变量 y 而非运算 f;
  • 人教版高中必修一,和上面被批判的定义类似,但是限定了 X 和 Y 都是实数集。

我记得我们那时候课本上还有个映射 (mapping) 的概念,定义和函数很像,就是把里面的“数集”换成了任意对象的集合。这次查课本的时候没找到这个概念。

这很正常,“数”已经不再是现代数学的一等公民了,集合才是。既然没了特殊性,今天绝大多数语境下都不再强调函数和映射的区别,两者往往互换使用。

自变量、函数值、因变量

  • 在函数的出发集 X 中取值的变量 x 叫做自变量
  • 变量 x 的任意一个取值带入函数 f 计算所得的结果 f(x) 叫做函数值
  • X 内所有 x 计算得到的 f(x) 也可以组成一个集合,在此集合中取值的变量叫做因变量

从自然科学的角度

按照大义名分——

  • 因变量是人们感兴趣的变量,是科学试图解释的目标;
  • 函数是科学为了定量地解释因变量而提出的数学模型;
  • 自变量是这个模型为了解释因变量而需要的来自现实的信息。

对于学术民工,函数是饭碗,变量是合作组送来的数据,择其最容易凑出结果者为因变量,余者为自变量~

说正经的,科学中的函数值和因变量也还是有区别。

因为因变量和自变量一样都是由实验测量得到的,来自物质世界,测量的误差不可避免

而函数是人对客观世界的一种认识,存在于观念/理性世界

因变量和函数值之间,按照误差分析的规范,以“无法断言它们不相等”而相等,或者说拟合。

从编程的角度(以 python 为例)

编程中,因变量和函数值的区别之前略微谈过了,前者是左值,后者是右值。

以本系列第 4 篇提到的洛伦兹系统为例:

import numpy as np

def chaotic_derivative(x,y,z)
    fx = 10*(y - x)
    fy = 26*x - y - x*z
    fz = x*y - (8/3)*z
    return fx,fy,fz

dt = 1E-4
N  = int(2.5E5)
XYZ = np.empty((3,N+1))
XYZ[:,0] = np.array([-10.0, -10.0, 20.0])
for t in range(N):
    XYZ[:,t+1] = XYZ[:,t] + chaotic_derivative(*XYZ[:,t])*dt

这里不加解释地用了一个多自变量的函数。既然数/标量相对于其他数学对象并没有特殊性,那么一个有序数组/向量自然也可以做自变量,只要我们约定好向量各分量的顺序和含义。

自变量 vs. 参数

上一节的例子里,为了得到函数值,除了自变量之外,还有 10, 26, 8/3 之类的常数也参与计算。

这些自变量以外,在当下的函数中不变的数,也可以看作某些变量的特定取值 fσ=10,b=8/3,r=26(x,y,z)f_{\sigma=10,b=8/3,r=26}(x,y,z),这些变量叫做函数的参数。

从应用数学的角度来讲,

  • 自变量 取不同的值时,函数一直是那个函数,是同一个对应关系/计算方法 f10,8/3,26f_{10,8/3,26}
  • 参数 取不同的值时,原函数本身会变换成另一个函数,它们整体组成一个以参数(的所有可能取值)为指标集的函数族 {fσ,b,r}\{f_{\sigma,b,r}\}

从纯数学的角度来讲,参数只是一种特殊的自变量,参数的作用和自变量没有区别;

  • 自变量出现在函数的表达式中,自变量的变化会导致函数值的变化;
  • 参数也出现在函数的表达式中,参数的变化也会导致函数值的变化——

fσ,b,r(x,y,z)f_{\sigma,b,r}(x,y,z)f(x,y,z;σ,b,r)f(x,y,z;\sigma,b,r)具体表达式是完全相同的

很多物理老师的幻灯片、讲义,乃至教材让人看不懂,很多时候都是因为数学记号的书写问题,同一对象的表示法前后不统一、同一符号指代的对象前后不统一、统一但是有歧义又没说明……

从自然科学的角度

因为实验仪器和实验方法是有限的,所以能拿到的实验数据类型是有限的。

  • 自变量 是实验科学家能够通过实验观测取得数据的变量,也就是模型的用户输入。
  • 参数 是理论科学家选定一个函数族之后,为了让函数值拟合因变量,而在模型内部调整的变量,对用户屏蔽。

自变量和参数概念的分离,体现的是科学中,实验和理论的分工和解耦。

实验设计

最近看一些实验方向的招聘启事,岗位要求里经常有“能够进行/熟练掌握/精通实验设计”之类的说法。所谓实验设计,目的就是验证已有的理论模型和参数的选择是否正确。

方法是寻找一个新的实验和对应的函数,让旧函数的参数,恰好是新函数的自变量。这样新实验的数据作为自变量代入新函数,和新的因变量进行比较,就可以在实验上验证旧函数和旧参数的正确性。

当旧参数/新自变量的取值只有“是/否”这一对逻辑值时,实验设计就简化回了生命科学里常见的“假设检验法”;

反过来就是“假设检验法”在物理、化学中见得少的原因——那些学科的的定量程度更高,实数集 R\mathbb R 的元素有无穷多,而区区 1024 个可能取值的一个变量,就需要 10 个二进制位编码,也就等价于要设计 10 个待检验假设。

物质科学里,很多情况下是先有一套先进实验设备,低温、高压、强磁场……有啥锤子就敲啥钉子,不说了不说了,再说号没了。

从编程的角度(以 python 为例)

python 中的函数,不仅可以像前一节那样直接定义,也可以实例化一个定义了 __call__() 方法的 class。这里就能体现出参数和自变量的区别了——

import numpy as np

class LorenzDerivative(object):
    def __init__(sigma,b,r):
        self.sigma = sigma
        self.b = b
        self.r = r
    def __call__(x,y,z):
        fx = self.sigma*(y - x)
        fy = self.r*x - y - x*z
        fz = x*y - self.b*z
        return np.array([fx,fy,fz])

chaotic_derivative = LorenzDerivative(sigma=10,b=8/3,r=26)

dt = 1E-4
N  = int(2.5E5)
XYZ = np.empty((3,N+1))
XYZ[:,0] = np.array([-10.0, -10.0, 20.0])
for t in range(N):
    XYZ[:,t+1] = XYZ[:,t] + chaotic_derivative(*XYZ[:,t])*dt

参数__init__() 方法的输入;

自变量__call__() 方法的输入。

超参数

前文所述理论科学工作的本质,

就是向实验科学交付以部分实验数据为自变量,其余数据为因变量的函数;

交付格式就是函数族的表达式,以及其中参数的取值。

其中的函数族是从各学科公理和定理出发,推导出来的特定算法,参数往往也是“客观”存在的物理量,具体问题具体分析。


而机器学习/人工智能 (ML/AI),则是预先想定若干参数量极大的通用函数族,利用超多参数带来的超大信息容量,越过具体的科学理论,直接面向各种不同问题的数据,确定参数的取值。这个专业方向叫做 AI for science,从业者大多是计算机科学家。

确定参数的方式,

首先要计算要交付的模型的函数值和因变量的不同,既然是计算,那就是一个新的函数,叫做损失函数 (loss function)。

然后让损失函数值最小化。这个最小化的过程也有一定之规,是一种运算,也就又是一个函数,有自己的参数。

最小化过程中的参数,完全由计算机科学家掌握,对理论和实验科学家屏蔽,这就是超参数

回到动力学系统的相图

动力学系统本身是一组关于时间 t 的函数 z=z(t)\vec z = \vec z(t)(对不起这里也犯了一个符号两种含义的错误,但是不好改,约定俗成了)

这组函数由动力学微分方程确定 z˙=dz(t)/dt=f(z)\dot{\vec z} = \mathrm d \vec z(t)/\mathrm dt = \vec f(\vec z)

通过求解代数方程组 f(z)=0\vec f(\vec z^*) = 0

可以得到驻点关于动力学系统参数的函数 z=ζ(parameters)\vec z^*=\vec\zeta(\mathrm{\dots parameters})

选择合适的驻点分量和感兴趣的参数 zi=ζi(paramj)z^*_i=\zeta_i(\mathrm{param}_j) 作图,得到的就是相图

还是洛伦兹系统,本系列第 4 篇没画图干讲了:

0 < r < 1 时,系统的驻点是原点,而且稳定;

r > 1 时,原点变为不稳定驻点,此时会出现两个新的稳定驻点: (b(r1),b(r1),r1)(\sqrt{b(r-1)},\sqrt{b(r-1)},r-1)(b(r1),b(r1),r1)(-\sqrt{b(r-1)},-\sqrt{b(r-1)},r-1)

r>rH=σ(σ+b+3)σb1r>r_H=\frac{\sigma(\sigma+b+3)}{\sigma-b-1} 时开始出现混沌。最常讨论的参数取值是 σ=10\sigma=10, b=8/3b=8/3, 此时 rHr_H 约为 24.76

如今可以把相图补上了:

洛伦兹系统的相图 (phase diagram)
洛伦兹系统的相图 (phase diagram)

本文收录于以下合集: