前几天,笔者看了几篇介绍SSM(State Space Model)的文章,才发现原来自己从未认真了解过SSM,于是打算认真去学习一下SSM的相关内容,顺便开了这个新坑,记录一下学习所得。

SSM的概念由来已久,但这里我们特指深度学习中的SSM,一般认为其开篇之作是2021年的S4,不算太老,而SSM最新最火的变体大概是去年的Mamba。当然,当我们谈到SSM时,也可能泛指一切线性RNN模型,这样RWKVRetNet还有此前我们在《Google新作试图“复活”RNN:RNN能否再次辉煌?》介绍过的LRU都可以归入此类。不少SSM变体致力于成为Transformer的竞争者,尽管笔者并不认为有完全替代的可能性,但SSM本身优雅的数学性质也值得学习一番。

尽管我们说SSM起源于S4,但在S4之前,SSM有一篇非常强大的奠基之作《HiPPO: Recurrent Memory with Optimal Polynomial Projections》(简称HiPPO),所以本文从HiPPO开始说起。

基本形式 #

先插句题外话,上面提到的SSM代表作HiPPO、S4、Mamba的一作都是Albert Gu,他还有很多篇SSM相关的作品,毫不夸张地说,这些工作筑起了SSM大厦的基础。不论SSM前景如何,这种坚持不懈地钻研同一个课题的精神都值得我们由衷地敬佩。

言归正传。对于事先已经对SSM有所了解的读者,想必知道SSM建模所用的是线性ODE系统:
x(t)=Ax(t)+Bu(t)y(t)=Cx(t)+Du(t)
其中u(t)Rdi,x(t)Rd,y(t)Rdo,ARd×d,BRd×di,CRdo×d,DRdo×di。当然我们也可以将它离散化,那么就变成一个线性RNN模型,这部分我们在后面的文章再展开。不管离散化与否,其关键词都是“线性”,那么马上就有一个很自然的问题:为什么是线性系统?线性系统够了吗?

我们可以从两个角度回答这个问题:线性系统既足够简单,也足够复杂简单是指从理论上来说,线性化往往是复杂系统的一个最基本近似,所以线性系统通常都是无法绕开的一个基本点;复杂是指即便如此简单的系统,也可以拟合异常复杂的函数,为了理解这一点,我们只需要考虑一个R4的简单例子:
x(t)=(1000010000010010)x(t)
这个例子的基本解是x(t)=(et,et,sint,cost)。这意味着什么呢?意味着只要d足够大,该线性系统就可以通过指数函数和三角函数的组合来拟合足够复杂的函数,而我们知道拟合能力很强的傅里叶级数也只不过是三角函数的组合,如果在加上指数函数显然就更强了,因此可以想象线性系统也有足够复杂的拟合能力。

当然,这些解释某种意义上都是“马后炮”。HiPPO给出的结果更加本质:当我们试图用正交基去逼近一个动态更新的函数时,其结果就是如上的线性系统。这意味着,HiPPO不仅告诉我们线性系统可以逼近足够复杂的函数,还告诉我们怎么去逼近,甚至近似程度如何。

有限压缩 #

接下来,我们都只考虑di=1的特殊情形,di>1只不过是di=1时的平行推广。此时,u(t)的输出是一个标量,进一步地,作为开头我们先假设t[0,1],HiPPO的目标是:用一个有限维的向量来储存这一段u(t)的信息。

看上去这是一个不大可能的需求,因为t[0,1]意味着u(t)可能相当于无限个点组成的向量,压缩到一个有限维的向量可能严重失真。不过,如果我们对u(t)做一些假设,并且允许一些损失,那么这个压缩是有可能做到的,并且大多数读者都已经尝试过。比如,当u(t)在某点n+1阶可导的,它对应的n阶泰勒展开式往往是u(t)的良好近似,于是我们可以只储存展开式的n+1个系数来作为u(t)的近似表征,这就成功将u(t)压缩为一个n+1维向量。

当然,对于实际遇到的数据来说,“n+1阶可导”这种条件可谓极其苛刻,我们通常更愿意使用在平方可积条件下的正交函数基展开,比如傅里叶(Fourier)级数,它的系数计算公式为
cn=10u(t)e2iπntdt
这时候取一个足够大的整数N,只保留|n|N的系数,那么就将u(t)压缩为一个2N+1维的向量了。

接下来,问题难度就要升级了。刚才我们说t[0,1],这是一个静态的区间,而实际中u(t)代表的是持续采集的信号,所以它是不断有新数据进入的,比如现在我们近似了[0,1]区间的数据,马上就有[1,2]的数据进来,你需要更新逼近结果来试图记忆整个[0,2]区间,接下来是[0,3][0,4]等等,这我们称为“在线函数逼近”。而上面的傅里叶系数公式(3),只适用于区间[0,1],因此需要将它进行推广。

为此,我们设t[0,T]stT(s)[0,1][0,T]的一个映射,那么u(tT(s))作为s的函数时,它的定义区间就是[0,1],于是就可以复用式(3)
cn(T)=10u(tT(s))e2iπnsds
这里我们已经给系数加了标记(T),以表明此时的系数会随着T的变化而变化。

线性初现 #

能将[0,1]映射到[0,T]的函数有无穷多,而最终结果也因tT(s)而异,一些比较直观且相对简单的选择如下:

1、tT(s)=sT,即将[0,1]均匀地映射到[0,T]

2、注意tT(s)并不必须是满射,所以像tT(s)=s+T1也是允许的,这意味着只保留了最邻近窗口[T1,T]的信息,丢掉了更早的部分,更一般地有tT(s)=sw+Tw,其中w是一个常数,这意味着Tw前的信息被丢掉了;

3、也可以选择非均匀映射,比如tT(s)=Ts,它同样是[0,1][0,T]的满射,但s=1/4时就映射到T/2了,这意味着我们虽然关注全局的历史,但同时更侧重于T时刻附近的信息。

现在我们以tT(s)=sw+Tw为例,代入式(4)得到
cn(T)=10u(sw+Tw)e2iπnsds
现在我们两边求关于T的导数:
ddTcn(T)=10u(sw+Tw)e2iπnsds=1wu(sw+Tw)e2iπns|s=1s=0+2iπnw10u(sw+Tw)e2iπnsds=1wu(T)1wu(Tw)+2iπnwcn(T)
其中第二个等号我们用了分部积分公式。由于我们只保留了|n|N的系数,所以根据傅立叶级数的公式,可以认为如下是u(sw+Tw)的一个良好近似:
u(sw+Tw)k=Nk=Nck(T)e2iπks
那么u(Tw)=u(sw+Tw)|s=0k=Nk=Nck(T),代入式(6)得:
ddTcn(T)1wu(T)1wk=Nk=Nck(T)+2iπnwcn(T)
T换成t,然后所有的cn(t)堆在一起记为x(t)=(cN,c(N1),,c0,,cN1,cN),并且不区分=,那么就可以写出
x(t)=Ax(t)+Bu(t),An,k={(2iπn1)/w,k=n1/w,kn,Bn=1/w
这就出现了如式(1)所示的线性ODE系统。即当我们试图用傅里叶级数去记忆一个实时函数的最邻近窗口内的状态时,结果自然而言地导致了一个线性ODE系统。

一般框架 #

当然,目前只是选择了一个特殊的tT(s),换一个tT(s)就不一定有这么简单的结果了。此外,傅里叶级数的结论是在复数范围内的,进一步实数化也可以,但形式会变得复杂起来。所以,我们要将上一节的过程推广成一个一般化的框架,从而得到更一般、更简单的纯实数结论。

t[a,b],并且有目标函数u(t)和函数基{gn(t)}Nn=0,我们希望有后者的线性组合来逼近前者,目标是最小化L2距离:
argminc1,,cNba[u(t)Nn=0cngn(t)]2dt
这里我们主要在实数范围内考虑,所以方括号直接平方就行,不用取模。更一般化的目标函数还可以再加个权重函数ρ(t),但我们这里就不考虑了,毕竟HiPPO的主要结论其实也没考虑这个权重函数。

对目标函数展开,得到
bau2(t)dt2Nn=0cnbau(t)gn(t)dt+Nm=0Nn=0cmcnbagm(t)gn(t)dt
这里我们只考虑标准正交函数基,其定义为bagm(t)gn(t)dt=δm,nδm,n克罗内克δ函数,此时上式可以简化成
bau2(t)dt2Nn=0cnbau(t)gn(t)dt+Nn=0c2n
这只是一个关于cn的二次函数,它的最小值是有解析解的:
cn=bau(t)gn(t)dt
这也被称为u(t)gn(t)的内积,它是有限维向量空间的内积到函数空间的平行推广。简单起见,在不至于混淆的情况下,我们默认cn就是cn

接下来的处理跟上一节是一样的,我们要对一般的t[0,T]考虑u(t)的近似,那么找一个[a,b][0,T]的映射stT(s),然后计算系数
cn(T)=bau(tT(s))gn(s)ds
同样是两边求T的导数,然后用分部积分法
ddTcn(T)=bau(tT(s))tT(s)Tgn(s)ds=ba(tT(s)T/tT(s)s)gn(s)du(tT(s))=u(tT(s))(tT(s)T/tT(s)s)gn(s)|s=bs=abau(tT(s))d[(tT(s)T/tT(s)s)gn(s)]

请勒让德 #

接下来的计算,就依赖于gn(t)tT(s)的具体形式了。HiPPO的全称是High-order Polynomial Projection Operators,第一个P正是多项式(Polynomial)的首字母,所以HiPPO的关键是选取多项式为基。现在我们请出继傅里叶之后又一位大牛——勒让德(Legendre),接下来我们要选取的函数基正是以他命名的“勒让德多项式”。

勒让德多项式pn(t)是关于tn次函数,定义域为[1,1],满足
11pm(t)pn(t)dt=22n+1δm,n
所以pn(t)之间只是正交,还不是标准(平分积分为1),gn(t)=2n+12pn(t)才是标准正交基。

当我们对函数基{1,t,t2,,tn}执行施密特正交化时,其结果正是勒让德多项式。相比傅里叶基,勒让德多项式的好处是它是纯粹定义在实数空间中的,并且多项式的形式能够有助于简化部分tT(s)的推导过程,这一点我们后面就可以看到。勒让德多项式有很多不同的定义和性质,这里我们不一一展开,有兴趣的读者自行看链接中维基百科介绍即可。

接下来我们用到两个递归公式来推导一个恒等式,这两个递归公式是
pn+1(t)pn1(t)=(2n+1)pn(t)pn+1(t)=(n+1)pn(t)+tpn(t)
由第一个公式(17)迭代得到:
pn+1(t)=(2n+1)pn(t)+(2n3)pn2(t)+(2n7)pn4(t)+=nk=0(2k+1)χnkpk(t)
其中当k是偶数时χk=1否则χk=0。代入第二个公式(18)得到
tpn(t)=npn(t)+(2n3)pn2(t)+(2n7)pn4(t)+
继而有
(t+1)pn(t)=npn(t)+(2n1)pn1(t)+(2n3)pn2(t)+=(n+1)pn(t)+nk=0(2k+1)pk(t)
这些就是等会要用到的恒等式。此外,勒让德多项式满足pn(1)=1,pn(1)=(1)n,这个边界值后面也会用到。

正如n维空间中不止有一组正交基也一样,正交多项式也不止有勒让德多项式一种,比如还有切比雪夫(Chebyshev)多项式,如果算上加权的目标函数(即ρ(t)),还有拉盖尔多项式等,这些在原论文中都有提及,但HiPPO的主要结论还是基于勒让德多项式展开的,所以剩余部分这里也不展开讨论了。

邻近窗口 #

完成准备工作后,我们就可以代入具体的t_{\leq T}(s)进行计算了,计算过程跟傅里叶级数的例子大同小异,只不过基函数换成了勒让德多项式构造的标准正交基g_n(t)=\sqrt{\frac{2n+1}{2}} p_n(t)。作为第一个例子,我们同样先考虑只保留最邻近窗口的信息,此时t_{\leq T}(s) = (s + 1)w / 2 + T - w[-1,1]映射到[T-w,T],原论文将这种情形称为“LegT(Translated Legendre)”。

直接代入式\eqref{eq:hippo-base},马上得到
\begin{equation}\small\frac{d}{dT}c_n(T) = \frac{\sqrt{2(2n+1)}}{w}\left[u(T) - (-1)^n u(T-w)\right] - \frac{2}{w}\int_{-1}^1 u((s + 1)w / 2 + T - w) g_n'(s) ds\end{equation}
我们首先处理u(T-w)项,跟傅里叶级数那里同样的思路,我们截断n\leq N作为u((s + 1)w / 2 + T - w)的一个近似:
\begin{equation}u((s + 1)w / 2 + T - w)\approx \sum_{k=0}^N c_k(T)g_k(s)\end{equation}
从而有u(T-w)\approx \sum\limits_{k=0}^N c_k(T)g_k(-1) = \sum\limits_{k=0}^N (-1)^k c_k(T) \sqrt{\frac{2k+1}{2}}。接着,利用式\eqref{eq:leg-dot}得到
\begin{equation}\begin{aligned} &\,\int_{-1}^1 u((s + 1)w / 2 + T - w) g_n'(s) ds \\ =&\,\int_{-1}^1 u((s + 1)w / 2 + T - w) \sqrt{\frac{2n+1}{2}} p_n'(s) ds \\ =&\, \int_{-1}^1 u((s + 1)w / 2 + T - w)\sqrt{\frac{2n+1}{2}}\left[\sum_{k=0}^{n-1} (2k+1) \chi_{n-1-k} p_k(s)\right]ds \\ =&\, \int_{-1}^1 u((s + 1)w / 2 + T - w)\sqrt{\frac{2n+1}{2}}\left[\sum_{k=0}^{n-1} \sqrt{2(2k+1)} \chi_{n-1-k} g_k(s)\right]ds \\ =&\, \sqrt{2n+1}\sum_{k=0}^{n-1} \sqrt{2k+1} \chi_{n-1-k} c_k(T) \end{aligned}\end{equation}
将这些结果整合起来,就有
\begin{equation}\begin{aligned} \frac{d}{dT}c_n(T) \approx &\, \frac{\sqrt{2(2n+1)}}{w}u(T) - \frac{\sqrt{2(2n+1)}}{w} (-1)^n \overbrace{\sum\limits_{k=0}^N (-1)^k c_k(T) \sqrt{\frac{2k+1}{2}}}^{u(T-w)} \\ &\quad- \frac{2}{w}\overbrace{\sqrt{2n+1}\sum_{k=0}^{n-1} \sqrt{2k+1} \chi_{n-1-k} c_k(T)}^{\int_{-1}^1 u((s + 1)w / 2 + T - w) g_n'(s) ds} \\[12pt] = &\, \frac{\sqrt{2(2n+1)}}{w}u(T) - \frac{\sqrt{2n+1}}{w} \sum\limits_{k=0}^N (-1)^{n-k} c_k(T) \sqrt{2k+1} \\ &\quad- \frac{2}{w}\sqrt{2n+1}\sum_{k=0}^{n-1} \sqrt{2k+1} \chi_{n-1-k} c_k(T) \\[12pt] = &\, \frac{\sqrt{2(2n+1)}}{w}u(T) - \frac{\sqrt{2n+1}}{w} \sum\limits_{k=n}^N (-1)^{n-k} c_k(T) \sqrt{2k+1} \\ &\quad- \frac{\sqrt{2n+1}}{w}\sum_{k=0}^{n-1} \sqrt{2k+1} \underbrace{\left(2\chi_{n-1-k} + (-1)^{n-k}\right)}_{\equiv 1}c_k(T) \\ \end{aligned}\label{eq:leg-t}\end{equation}
再次地,将T换回t,并将所有的c_n(t)堆在一起记为x(t) = (c_0,c_1,\cdots,c_N),那么根据上式可以写出
\begin{equation}\begin{aligned} x'(t) =&\, Ax(t) + Bu(t)\\[8pt] \quad A_{n,k} =&\, -\frac{1}{w}\left\{\begin{array}{l}\sqrt{(2n+1)(2k+1)}, &k < n \\ (-1)^{n-k}\sqrt{(2n+1)(2k+1)}, &k \geq n\end{array}\right.\\[8pt] B_n =&\, \frac{1}{w}\sqrt{2(2n+1)} \end{aligned}\label{eq:leg-t-hippo-1}\end{equation}
我们还可以给每个c_n(T)都引入一个缩放因子,来使得上述结果更一般化。比如我们设c_n(T) = \lambda_n \tilde{c}_n(T),代入式\eqref{eq:leg-t}整理得
\begin{equation}\begin{aligned} \frac{d}{dt}\tilde{c}_n(T) \approx &\, \frac{\sqrt{2(2n+1)}}{w\lambda_n}u(T) - \frac{\sqrt{2n+1}}{w} \sum\limits_{k=n}^N (-1)^{n-k} \tilde{c}_k(T) \frac{\lambda_k\sqrt{2k+1}}{\lambda_n} \\ &\quad- \frac{\sqrt{2n+1}}{w}\sum_{k=0}^{n-1} \frac{\lambda_k\sqrt{2k+1}}{\lambda_n} \tilde{c}_k(T) \\ \end{aligned}\end{equation}
如果取\lambda_n = \sqrt{2},那么A不变,B_n = \frac{1}{w}\sqrt{2n+1},这就对齐了原论文的结果,如果取\lambda_n = \frac{2}{\sqrt{2n+1}},那么就得到了Legendre Memory Units中的结果
\begin{equation}\begin{aligned} x'(t) =&\, Ax(t) + Bu(t)\\[8pt] \quad A_{n,k} =&\, -\frac{1}{w}\left\{\begin{array}{l}2n+1, &k < n \\ (-1)^{n-k}(2n+1), &k \geq n\end{array}\right.\\[8pt] B_n =&\, \frac{1}{w}(2n+1) \end{aligned}\label{eq:leg-t-hippo-2}\end{equation}
这些形式在理论上都是等价的,但可能存在不同的数值稳定性。比如一般来说当u(t)的性态不是特别糟糕时,我们可以预期n越大,|c_n|的值就相对越小,这样直接用c_n的话x(t)向量的每个分量的尺度就不大对等,这样的系统在实际计算时容易出现数值稳定问题,而取\lambda_n = \frac{2}{\sqrt{2n+1}}改用\tilde{c}_n的话意味着数值小的分量会被适当放大,可能有助于缓解多尺度问题从而使得数值计算更稳定。

整个区间 #

现在我们继续计算另一个例子:t_{\leq T}(s) = (s + 1)T / 2,它将[-1,1]均匀映射到[0,T],这意味着我们没有舍弃任何历史信息,并且平等地对待所有历史,原论文将这种情形称为“LegS(Scaled Legendre)”。

同样地,通过代入式\eqref{eq:hippo-base}得到
\begin{equation}\frac{d}{dT}c_n(T) = \frac{\sqrt{2(2n+1)}}{T}u(T) - \frac{1}{T}\int_{-1}^1 u((s + 1)T / 2) \left[g_n(s) + (s+1) g_n'(s)\right] ds\end{equation}
利用公式\eqref{eq:leg-dot-t1}得到
\begin{equation}\begin{aligned} &\,\int_{-1}^1 u((s + 1)T / 2) \left[g_n(s) + (s+1) g_n'(s)\right] ds \\ =&\,c_n(T) + \int_{-1}^1 u((s + 1)T / 2) (s+1) g_n'(s) ds \\ =&\, c_n(T) + \int_{-1}^1 u((s + 1)T / 2)(s+1) \sqrt{\frac{2n+1}{2}} p_n'(s) \\ =&\, c_n(T) + \int_{-1}^1 u((s + 1)T / 2)\sqrt{\frac{2n+1}{2}}\left[-(n+1) p_n(s) + \sum_{k=0}^n (2k + 1) p_k(s)\right] ds \\ =&\, c_n(T) + \int_{-1}^1 u((s + 1)T / 2)\left[-(n+1) g_n(s) + \sum_{k=0}^n \sqrt{(2n+1)(2k + 1)} g_k(s)\right] ds \\ =&\, -n c_n(T) + \sum_{k=0}^n \sqrt{(2n+1)(2k + 1)} c_k(T) \\ \end{aligned}\end{equation}
于是有
\begin{equation}\frac{d}{dT}c_n(T) = \frac{\sqrt{2(2n+1)}}{T}u(T) - \frac{1}{T}\left(-n c_n(T) + \sum_{k=0}^n \sqrt{(2n+1)(2k + 1)} c_k(T)\right)\label{eq:leg-s}\end{equation}
T换回t,将所有的c_n(t)堆在一起记为x(t) = (c_0,c_1,\cdots,c_N),那么根据上式可以写出
\begin{equation}\begin{aligned} x'(t) =&\, \frac{A}{t}x(t) + \frac{B}{t}u(t)\\[8pt] \quad A_{n,k} =&\, -\left\{\begin{array}{l}\sqrt{(2n+1)(2k+1)}, &k < n \\ n+1, &k = n \\ 0, &k > n\end{array}\right.\\[8pt] B_n =&\, \sqrt{2(2n+1)} \end{aligned}\label{eq:leg-s-hippo}\end{equation}
引入缩放因子来一般化结果也是可行的:设c_n(T) = \lambda_n \tilde{c}_n(T),代入式\eqref{eq:leg-t}整理得
\begin{equation}\frac{d}{dT}\tilde{c}_n(T) = \frac{\sqrt{2(2n+1)}}{T\lambda_n}u(T) - \frac{1}{T}\left(-n \tilde{c}_n(T) + \sum_{k=0}^n \frac{\sqrt{(2n+1)(2k + 1)}\lambda_k}{\lambda_n} \tilde{c}_k(T)\right)\end{equation}
\lambda_n=\sqrt{2}就可以让A不变,B变为B_n = \sqrt{2n+1},就对齐了原论文的结果。如果取\lambda_n=\sqrt{\frac{2}{2n+1}},就可以像上一节LegT的结果一样去掉根号
\begin{equation}\begin{aligned} x'(t) =&\, \frac{A}{t}x(t) + \frac{B}{t}u(t)\\[8pt] \quad A_{n,k} =&\, -\left\{\begin{array}{l}2n+1, &k < n \\ n+1, &k = n \\ 0, &k > n\end{array}\right.\\[8pt] B_n =&\, 2n+1 \end{aligned}\label{eq:leg-s-hippo-2}\end{equation}
但原论文没有考虑这种情况,原因不详。

延伸思考 #

回顾Leg-S的整个推导,我们可以发现其中关键一步是将(s+1) g_n'(s)拆成g_0(s),g_1(s),\cdots,g_n(s)的线性组合,对于正交多项式来说,(s+1) g_n'(s)是一个n次多项式,所以这种拆分必然可以精确成立,但如果是傅立叶级数的情况,g_n(s)是指数函数,此时类似的拆分做不到了,至少不能精确地做到,所以可以说选取正交多项式为基的根本目的是简化后面推导。

特别要指出的是,HiPPO是一个自下而上的框架,它并没有一开始就假设系统必须是线性的,而是从正交基逼近的角度反过来推出其系数的动力学满足一个线性ODE系统,这样一来我们就可以确信,只要认可所做的假设,那么线性ODE系统的能力就是足够的,而不用去担心线性系统的能力限制了你的发挥。

当然,HiPPO对于每一个解所做的假设及其物理含义也很清晰,所以对于重用了HiPPO矩阵的SSM,它怎么储存历史、能储存多少历史,从背后的HiPPO假设就一清二楚。比如LegT就是只保留w大小的最邻近窗口信息,如果你用了LegT的HiPPO矩阵,那么就类似于一个Sliding Window Attention;而LegS理论上可以捕捉全部历史,但这有个分辨率问题,因为x(t)的维度代表了拟合的阶数,它是一个固定值,用同阶的函数基去拟合另一个函数,肯定是区间越小越准确,区间越大误差也越大,这就好比为了一次性看完一幅大图,那么我们必须站得更远,从而看到的细节越少。

诸如RWKV、LRU等模型,并没有重用HiPPO矩阵,而是改为可训练的矩阵,原则上具有更多的可能性来突破瓶颈,但从前面的分析大致上可以感知到,不同矩阵的线性ODE只是函数基不同,但本质上可能都只是有限阶函数基逼近的系数动力学。既然如此,分辨率与记忆长度就依然不可兼得,想要记忆更长的输入并且保持效果不变,那就只能增加整个模型的体量(即相当于增加hidden_size),这大概是所有线性系统的特性。

文章小结 #

本文以尽可能简单的方式重复了《HiPPO: Recurrent Memory with Optimal Polynomial Projections》(简称HiPPO)的主要推导。HiPPO通过适当的记忆假设,自下而上地导出了线性ODE系统,并且针对勒让德多项式的情形求出了相应的解析解(HiPPO矩阵),其结果被后来诸多SSM(State Space Model)使用,可谓是SSM的重要奠基之作。

转载到请包括本文地址:https://spaces.ac.cn/archives/10114

更详细的转载事宜请参考:《科学空间FAQ》

如果您还有什么疑惑或建议,欢迎在下方评论区继续讨论。

如果您觉得本文还不错,欢迎分享/打赏本文。打赏并非要从中获得收益,而是希望知道科学空间获得了多少读者的真心关注。当然,如果你无视它,也不会影响你的阅读。再次表示欢迎和感谢!

如果您需要引用本文,请参考:

苏剑林. (May. 24, 2024). 《重温SSM(一):线性系统和HiPPO矩阵 》[Blog post]. Retrieved from https://spaces.ac.cn/archives/10114

@online{kexuefm-10114,
        title={重温SSM(一):线性系统和HiPPO矩阵},
        author={苏剑林},
        year={2024},
        month={May},
        url={\url{https://spaces.ac.cn/archives/10114}},
}