公司动态
动态模式分解(DMD)原理、实现与应用全解析
简介本资源是面向科研与工程实践者的动态模式分解DMDMATLAB实现工具包专为流体动力学、信号处理、结构健康监测等领域的数据分析初学者及进阶研究者设计解决高维时序数据中主导模态提取、系统演化机制解析与短期状态预测等核心问题。压缩包共含3个文件146KB包括核心算法脚本demo_DMD.m可直接运行的DMD主流程实现、原理说明PDF涵盖SVD构造、DMD模式计算、频率/增益求解与重构公式推导及Markdown格式README提供使用说明与关键参数注释结构精炼、即开即用。已有497人学习下载读者可快速掌握DMD从理论到代码落地的完整链路获得可复现的数值实验范例、清晰的矩阵运算步骤注释以及面向实际数据预处理与结果可视化的实用接口封装。1. 项目概述从数据洪流中捕捉动态的“指纹”如果你也经常和数据打交道尤其是那些随时间变化、蕴含着复杂动态的系统数据——比如流体湍流的仿真结果、金融市场波动、机械结构的振动监测甚至是社交媒体上的话题热度演变——你肯定遇到过这样的困境数据量巨大维度高看起来一团乱麻我们如何从中提炼出最核心、最本质的动态规律Dynamic Mode Decomposition简称DMD就是为解决这类问题而生的一把利器。它不是一个具体的软件包而是一种强大的数据驱动算法框架其核心思想是从高维的时序数据中直接提取出主导系统演化的线性动力学模式包括这些模式的频率、增长率或衰减率和空间结构。简单来说你可以把DMD想象成一个“动态模式识别器”。给DMD喂入一段系统状态随时间变化的“快照”序列它就能帮你分解出几个关键的“基本动作”即DMD模态并告诉你每个“基本动作”是以多快的频率在振荡、是在增强还是在衰减。这对于理解复杂系统的内在机理、进行稳定性分析、甚至构建低维度的预测模型都有着不可估量的价值。我最初接触DMD是在处理计算流体动力学CFD的仿真数据时面对GB级别的流场序列传统分析方法耗时耗力而DMD让我在几分钟内就识别出了主导的涡脱落频率和对应的空间结构效率提升是数量级的。这个名为“Dynamic Mode Decomposition (DMD).zip”的项目很可能是一个汇集了DMD算法核心实现、常用变种以及相关工具和示例的代码资源包。对于研究者、工程师和数据科学家而言这样一个整合良好的资源包能让我们跳过从零推导和编码的繁琐阶段直接上手应用于自己的实际问题。接下来我将结合自己多年的使用和踩坑经验为你深度拆解DMD的核心原理、关键实现步骤、各种实用变体以及如何避开那些新手最容易掉进去的“坑”。2. DMD核心原理与算法拆解不只是奇异值分解SVD理解DMD不能只停留在“调用一个函数”的层面。明白其数学内核才能在使用时知其然且知其所以然尤其在算法输出结果不合预期时你能快速定位问题所在。DMD的核心思想建立在这样一个假设上尽管真实世界系统往往是非线性的但其演化在短时间内或某些状态下可以由一个线性的算子来近似描述。2.1 基本假设与数据矩阵构建假设我们有一个动力系统其状态向量为x∈ ℝⁿ。我们通过实验或仿真在等时间间隔 Δt 上采集了 m1 个快照得到数据序列x₁, x₂, ..., xₘ₊₁。 DMD的核心假设是存在一个线性算子A使得相邻两个状态满足xₖ₊₁ ≈ A xₖ 对于 k 1, 2, ..., m。我们将这些快照组织成两个数据矩阵X [x₁, x₂, ..., xₘ]维度 n × mY [x₂, x₃, ..., xₘ₊₁]维度 n × m 这样我们的假设就可以写成矩阵形式Y ≈ A X。注意这里“≈”是关键。DMD寻找的是在最小二乘意义下最优的A。对于非线性系统这个A是原系统在所选数据轨迹上的最佳线性近似也称为Koopman算子的有限维近似。2.2 标准DMD算法步骤详解标准DMD算法通过一种巧妙的方式来避免直接计算高维n可能很大的A矩阵其步骤如下步骤1对数据矩阵 X 进行降维SVD我们对X进行奇异值分解SVDX U Σ V*其中U∈ ℝⁿ×ʳ,Σ∈ ℝʳ×ʳ,V∈ ℝᵐ×ʳʳ 是X的秩或我们保留的奇异值个数。U的列向量是X列空间即状态空间的一组正交基称为POD模态Σ包含了奇异值表示每个模式的重要性V包含了时间系数。步骤2在降维子空间中构建近似算子 Ã将高维算子A投影到U张成的低维子空间上得到降维后的算子Ã UA U ≈ UY V Σ⁻¹** 这个推导需要结合Y ≈ A X和X的SVD。Ã是一个 ʳ×ʳ 的小矩阵大大降低了计算复杂度。步骤3求解 Ã 的特征值与特征向量计算Ã的特征分解Ã W W Λ。其中Λ是一个对角矩阵其对角线元素 λⱼ 就是Ã的特征值W的列向量是对应的特征向量。步骤4重构DMD模态空间结构DMD模态Φ定义了每个动态模式在原始高维空间中的空间结构。它可以通过下式重构Φ Y V Σ⁻¹ W或者更常用且数值稳定的方式是Φ U W。这两种方式在理论上等价当SVD截断精确时但后者计算更简单。Φ的第 j 列φⱼ就是第 j 个DMD模态。步骤5计算DMD特征值的物理意义Ã的特征值 λⱼ 是离散时间下的特征值。我们通常更关心连续时间的动力学特性。通过变换 μⱼ ln(λⱼ) / Δt我们可以得到频率 ωⱼ Im(μⱼ) / (2π) 单位Hz增长率/衰减率 σⱼ Re(μⱼ)若 σⱼ 0该模式振幅随时间增长不稳定。若 σⱼ 0该模式振幅随时间衰减稳定。若 σⱼ 0该模式振幅不变中性稳定。步骤6初始幅值与模式叠加每个DMD模态对初始状态的贡献由一个向量b来描述b Φ⁺ x₁其中 ⁺ 表示伪逆。这样原系统的状态随时间演化可以近似重构为x(t) ≈ ∑_{j1}^{r} φⱼ bⱼ exp(μⱼ t) Φ diag(exp(μ t)) b这个公式是DMD威力的直观体现它将复杂的高维时空数据分解为少数几个以特定频率振荡、并以指数率增长或衰减的模式的线性叠加。2.3 关键参数选择与物理意义截断秩 r这是SVD步骤中最重要的参数。保留多少奇异值通常有两种策略硬阈值设定一个阈值如累积能量占比99%保留贡献达到该阈值的奇异值。观察奇异值谱绘制奇异值大小寻找“肘部”拐点拐点之后的值通常对应噪声可以截断。选择过大的 r 会引入噪声模式过小的 r 会丢失重要动力学信息。时间间隔 Δt它直接决定了频率分析的奈奎斯特极限最高可分辨频率为 1/(2Δt)。同时Δt 必须足够小以捕捉你感兴趣的最快动态。如果数据是等间隔采样的Δt 就是采样间隔如果不是则需要先进行插值处理。DMD模态的归一化DMD模态φⱼ本身只定义了空间结构的相对分布。其绝对大小没有固定意义通常我们会将其归一化例如归一化为单位范数以便于不同模式间的比较和可视化。3. DMD算法家族应对不同场景的变体标准DMD很强大但也有其局限性比如对噪声敏感、要求数据等间隔采样、难以处理非线性等。因此衍生出了一系列DMD变体就像一套组合工具针对不同问题选用不同的工具。3.1 精确DMD与优化DMD标准DMDExact DMD如上所述是当前最通用的框架。它强调Y ≈ A X这个拟合关系。优化DMDOptimized DMD这是一种更先进的框架它不再分别拟合X和Y而是将所有快照数据一起考虑通过优化算法如可变投影法直接求解一组指数函数对应DMD模式来最佳拟合整个数据序列。这种方法对噪声更鲁棒能提供更精确的频率和衰减率估计尤其适用于信噪比较低或数据量不大的情况。但计算成本通常高于标准DMD。3.2 稀疏DMD与压缩DMD当DMD模态很多时我们可能只关心其中少数几个关键模式。稀疏DMD在重构状态x(t)时在代价函数中增加对幅值向量b的 L1 正则化项如LASSO迫使许多bⱼ变为零从而自动筛选出最重要的少数模式。这非常有利于模型解释和简化。压缩DMD在数据维度 n 极高例如百万像素的图像序列时先对每个快照进行随机投影压缩感知在低维空间执行DMD然后再将结果映射回原空间。这能极大降低内存和计算需求。3.3 多分辨率DMD与时域DMD多分辨率DMDmrDMD受小波分析启发mrDMD递归地对数据进行不同时间尺度的分解。首先用DMD提取数据中最慢变化的模式将其从原始数据中减去然后在残差上重复此过程提取更快变化的模式。这非常适合分析包含多种时间尺度动态的系统如气候数据、湍流。时域DMDTDMD也称为“时间延迟嵌入DMD”。它将每个快照与之前若干个时间步的快照堆叠起来形成一个增广状态向量。这种方法能有效捕捉某些非线性系统的高维线性表示Koopman可观测量是连接DMD与非线性系统Koopman算子理论的重要桥梁。3.4 控制输入DMD与非线性DMDDMDcDMD with control当系统存在已知的外部控制输入u时假设xₖ₊₁ ≈ A xₖ B uₖ。DMDc可以同时辨识出状态矩阵A和控制矩阵B这对于基于数据的控制系统设计至关重要。非线性DMDKernel DMD通过核技巧Kernel Trick将数据隐式地映射到更高维的特征空间然后在那个空间执行线性DMD。这相当于用线性方法去逼近原始空间中的非线性动力学对于处理强非线性问题有潜力。选择哪种变体取决于你的具体问题数据是否干净是否需要考虑控制系统是否强非线性动态是否多尺度理解这些变体的适用场景能让你在工具包中快速找到最趁手的那一个。4. 实战演练用Python实现DMD分析流体圆柱绕流理论说得再多不如亲手跑一遍。这里我以一个经典的流体力学示例——圆柱绕流为例展示完整的DMD分析流程。我们将使用一个公开的仿真数据集或自己用简单CFD代码生成假设我们已经有了流场速度u v随时间变化的数据矩阵。4.1 环境准备与数据加载首先确保你的Python环境安装了必要的库numpy,scipy,matplotlib。我们假设数据存储在一个.mat文件或.npy文件中其中包含了一系列时间步的流场切片。import numpy as np import scipy.io as sio import matplotlib.pyplot as plt from scipy import linalg # 1. 加载数据 # 假设数据文件为 cylinder_flow.mat里面变量 U_all 形状为 (ny, nx, 2, nt) # ny, nx 是网格尺寸2代表(u,v)两个速度分量nt是时间步数 data sio.loadmat(cylinder_flow.mat) U_all data[U_all] # 形状 (ny, nx, 2, nt) ny, nx, _, nt U_all.shape # 2. 数据预处理将时空数据重组为DMD需要的快照矩阵 # 我们将每个时间步的流场u和v展平成一个长列向量 snapshots [] for i in range(nt): # 提取第i个时间步的流场 u U_all[:, :, 0, i] # x方向速度 v U_all[:, :, 1, i] # y方向速度 # 展平并拼接 snapshot np.concatenate([u.flatten(), v.flatten()]) snapshots.append(snapshot) # 构建数据矩阵 X 和 Y # 每一列是一个快照 X np.column_stack(snapshots[:-1]) # 从第1个到倒数第2个快照 Y np.column_stack(snapshots[1:]) # 从第2个到最后一个快照 # 数据维度状态维度 n 2 * ny * nx 快照数量 m nt - 1 n, m X.shape print(f状态维度 n {n}, 快照数量 m {m})4.2 核心DMD算法实现接下来我们实现标准DMD算法。这里我会加入一些工程上的细节处理比如针对大规模数据的精简SVD计算。def standard_dmd(X, Y, dt, rNone, svd_threshold0.99): 标准DMD算法实现 参数 X, Y: 数据矩阵形状 (n, m) dt: 采样时间间隔 r: 截断秩若为None则根据svd_threshold自动确定 svd_threshold: 累积能量阈值用于自动确定r 返回 Phi: DMD模态形状 (n, r) Lambda: 连续时间特征值 μ形状 (r, ) 复数 b: 初始幅值形状 (r, ) r_used: 实际使用的秩 # 步骤1: 对X进行SVD U, s, Vh linalg.svd(X, full_matricesFalse) # 使用精简SVD节省内存 # s是奇异值向量 Vh是V的共轭转置 # 确定截断秩 r if r is None: # 基于累积能量百分比确定 energy_cumsum np.cumsum(s) / np.sum(s) r_used np.argmax(energy_cumsum svd_threshold) 1 else: r_used min(r, len(s)) # 截断SVD矩阵 U_r U[:, :r_used] s_r s[:r_used] Vh_r Vh[:r_used, :] # 构建奇异值矩阵的逆 Sigma_inv np.diag(1.0 / s_r) # 步骤2: 构建降维算子 A_tilde A_tilde U_r.conj().T Y Vh_r.conj().T Sigma_inv # 注意这里使用了Vh_rV的共轭转置所以公式略有调整但等价于 U* Y V Σ^{-1} # 步骤3: 求解 A_tilde 的特征值和特征向量 Lambda_tilde, W linalg.eig(A_tilde) # Lambda_tilde是离散特征值 λ # 步骤4: 重构DMD模态 (方法1: Phi U_r W) Phi U_r W # 步骤5: 计算连续时间特征值 μ ln(λ)/dt # 避免对零或负特征值取对数理论上DMD特征值应为复数但数值误差可能导致问题 Lambda np.log(Lambda_tilde) / dt # 步骤6: 计算初始幅值 b # 求解 Phi * b ≈ x1其中x1是X的第一列 x1 X[:, 0] b, _, _, _ linalg.lstsq(Phi, x1, lapack_drivergelsy) # 使用最小二乘 return Phi, Lambda, b, r_used # 应用DMD dt 0.1 # 假设采样时间间隔为0.1秒 Phi, Lambda, b, r_used standard_dmd(X, Y, dt, svd_threshold0.999) # 保留99.9%能量 print(f使用了 {r_used} 个DMD模式。)4.3 结果后处理与可视化得到DMD模态和特征值后我们需要解读它们。可视化是关键。# 1. 绘制特征值谱连续时间 plt.figure(figsize(10, 4)) plt.subplot(1, 2, 1) # 绘制所有特征值在复平面上的位置 plt.scatter(np.real(Lambda), np.imag(Lambda)) plt.axhline(y0, colork, linestyle--, linewidth0.5) plt.axvline(x0, colork, linestyle--, linewidth0.5) plt.xlabel(增长率 (Re(μ))) plt.ylabel(频率部分 (Im(μ))) plt.title(DMD特征值谱 (连续时间)) plt.grid(True, alpha0.3) # 2. 绘制模态能量初始幅值b的绝对值 plt.subplot(1, 2, 2) mode_energy np.abs(b) sorted_idx np.argsort(mode_energy)[::-1] # 从大到小排序 plt.bar(range(1, len(sorted_idx)1), mode_energy[sorted_idx]) plt.xlabel(DMD模式 (按能量排序)) plt.ylabel(初始幅值 |b|) plt.title(DMD模式能量分布) plt.yscale(log) # 通常能量分布跨度大用对数坐标 plt.grid(True, alpha0.3, whichboth) plt.tight_layout() plt.show() # 3. 可视化最重要的几个DMD模态的空间结构 # 假设我们想看看能量最大的前3个模态 num_modes_to_plot 3 fig, axes plt.subplots(num_modes_to_plot, 2, figsize(12, 4*num_modes_to_plot)) for i, idx in enumerate(sorted_idx[:num_modes_to_plot]): mode_idx idx freq_hz np.imag(Lambda[mode_idx]) / (2*np.pi) growth_rate np.real(Lambda[mode_idx]) # 提取该模态的u分量和v分量 phi_mode Phi[:, mode_idx] phi_u phi_mode[:ny*nx].reshape((ny, nx)) phi_v phi_mode[ny*nx:].reshape((ny, nx)) # 计算模态的涡量ω ∂v/∂x - ∂u/∂y这是一个常用的可视化量 # 这里需要网格坐标信息假设x, y是1D数组 # 为简化我们直接显示速度向量的实部或幅值 mode_magnitude np.sqrt(np.abs(phi_u)**2 np.abs(phi_v)**2) ax_u axes[i, 0] im_u ax_u.imshow(np.real(phi_u), cmapRdBu, aspectauto) ax_u.set_title(fMode {i1} (Energy Rank {i1}): u-component\nf{freq_hz:.3f} Hz, σ{growth_rate:.3f}) plt.colorbar(im_u, axax_u) ax_v axes[i, 1] im_v ax_v.imshow(np.real(phi_v), cmapRdBu, aspectauto) ax_v.set_title(fMode {i1}: v-component) plt.colorbar(im_v, axax_v) plt.tight_layout() plt.show() # 4. 使用DMD模式重构流场并与原始数据对比 time_points np.arange(m) * dt # 选择重构的时间点例如最后一个时间步 t_reconstruct time_points[-1] # 计算重构状态 x_reconstruct np.zeros(n, dtypecomplex) for j in range(r_used): x_reconstruct Phi[:, j] * b[j] * np.exp(Lambda[j] * t_reconstruct) # 将重构的状态向量重新组织为流场 u_recon np.real(x_reconstruct[:ny*nx]).reshape((ny, nx)) v_recon np.real(x_reconstruct[ny*nx:]).reshape((ny, nx)) # 获取原始最后一个时间步的流场 u_original U_all[:, :, 0, -1] v_original U_all[:, :, 1, -1] # 绘制对比 fig, axes plt.subplots(2, 2, figsize(12, 10)) axes[0,0].imshow(u_original, cmapviridis, aspectauto) axes[0,0].set_title(Original u at final time) axes[0,1].imshow(u_recon, cmapviridis, aspectauto) axes[0,1].set_title(DMD Reconstructed u) axes[1,0].imshow(v_original, cmapviridis, aspectauto) axes[1,0].set_title(Original v at final time) axes[1,1].imshow(v_recon, cmapviridis, aspectauto) axes[1,1].set_title(DMD Reconstructed v) for ax in axes.flat: ax.axis(off) plt.tight_layout() plt.show()通过以上步骤你就能完成一次完整的DMD分析。从特征值谱中你可以看到哪些模式是稳定的在左半平面哪些是不稳定的在右半平面以及它们的振荡频率。从模态图中你可以直观地看到每个模式对应的空间流动结构例如在圆柱绕流中能量最大的模式往往对应着卡门涡街的脱落频率和结构。5. 避坑指南与高级技巧来自实战的经验DMD用起来简单但想用好、用准需要注意很多细节。下面是我在多个项目中总结出的常见问题和解决技巧。5.1 数据质量是生命线数据必须“干净”DMD对噪声和异常值非常敏感。在应用DMD前务必进行数据预处理。这包括去中心化减去时间均值。这是关键一步DMD分析的是围绕平均态的波动。计算X_mean np.mean(X, axis1, keepdimsTrue)然后对X和Y都减去这个均值。分析完成后如果需要重构再把均值加回来。滤波对于明显的高频噪声可以考虑使用低通滤波器如Butterworth滤波器进行时域滤波。但需谨慎避免滤掉你关心的真实动态。归一化/标准化当状态向量各分量的物理单位和量级差异巨大时例如压力是10^5 Pa量级速度是10^0 m/s量级应对每个分量进行标准化减去均值除以标准差以防止量级大的分量主导SVD结果。分析完成后记得将结果变换回去。快照数量与维度经验法则是快照数量m应显著大于你期望提取的模式数量r通常m 5r是比较安全的。如果n m状态维度远大于快照数即“瘦高”的数据矩阵SVD会更容易捕捉到主要模式。反之如果m很大计算SVD可能会成为瓶颈此时需要考虑使用随机化SVD等算法。5.2 特征值解读与虚假模式识别DMD算出的特征值中经常混杂着一些没有物理意义的“虚假模式”。如何识别和剔除它们检查特征值模长对于离散特征值 λ其模长|λ|应接近1对应连续特征值 μ 的实部接近0。如果|λ|远大于1或远小于1意味着该模式在单个时间步 Δt 内就会剧烈增长或衰减这通常不符合物理实际除非系统极度不稳定或阻尼极大可能是数值误差或噪声导致的虚假模式。检查模态能量初始幅值b极小的模式即使特征值看起来合理其对系统演化的贡献也微乎其微可以视为噪声模式予以剔除。频谱混淆如果采样频率1/Δt不满足奈奎斯特采样定理即低于系统最高频率的两倍会导致高频模式被错误地识别为低频模式混叠。确保你的 Δt 足够小。共轭对检查对于实值数据有物理意义的振荡模式其特征值和模态应以共轭对的形式出现。如果一个振荡模式没有找到其共轭对需要警惕。一个实用的筛选策略是结合|λ|接近1、|b|大于某个阈值、以及模态空间结构的物理合理性是否光滑、是否符合已知物理来综合判断。5.3 处理非均匀采样与大数据非均匀采样标准DMD要求等间隔采样。如果数据是非均匀的有几种处理方式插值将数据插值到均匀的时间网格上。这是最直接的方法但要小心插值引入的误差。使用变体如“Variable Projection”方法的优化DMD可以直接处理非均匀采样数据。重构相空间使用时滞嵌入法TDMD将非均匀采样数据构建成Hankel矩阵有时也能奏效。大规模数据当n非常大如超过10^5时存储和计算U矩阵大小 n×r可能内存不足。此时可以采用随机化DMD使用随机投影算法来近似计算SVD大幅降低计算量和内存消耗。增量式DMD如果数据是流式到来的可以使用在线或增量式DMD算法无需存储所有历史快照。分块处理如果状态空间在物理上具有局部性如图像可以考虑分块进行DMD然后再合并结果但这需要谨慎处理块之间的耦合。5.4 DMD与POD的联系与区别初学者常混淆DMD和本征正交分解POD也叫PCA。理解它们的区别至关重要POD寻找一组最优的正交基空间模式使得用这组基表示数据时在能量意义下误差最小。POD模态是静态的不包含时间动力学信息。POD的时间系数需要通过投影得到其演化规律未知。DMD寻找一组动态模式每个模式都有其固有的频率和增长率。DMD模态不一定正交但它们直接刻画了系统的线性动力学。DMD同时给出了模态和其时间演化规律指数函数。简单说POD告诉你“是什么样子”而DMD告诉你“如何动起来”。在实践中两者常结合使用先用POD进行大幅度的降维因为POD的能量最优性然后在POD系数构成的时间序列上做DMD这被称为“POD-DMD”或“投影DMD”能有效提升计算效率和鲁棒性。6. 典型应用场景与案例拓展掌握了DMD的核心和技巧我们来看看它能用在哪些地方。其应用早已超越了流体力学扩展到诸多领域。6.1 流体力学与空气动力学这是DMD的发源地也是最成熟的应用领域。流场稳定性分析识别导致流动失稳如从层流到湍流转捩的主导模式及其增长率。气动噪声源识别从非定常流场数据中提取与特定频率噪声相关的相干结构。流动控制基于DMD建立的降阶模型设计控制器来抑制不利的流动模式如颤振。案例分析机翼尾迹DMD可以清晰地分离出卡门涡街的脱落频率、剪切层不稳定波等模式并量化它们对升阻力波动的影响。6.2 结构健康监测与振动分析模态参数识别从结构振动响应数据如加速度传感器数据中提取结构的固有频率、阻尼比和振型。相比传统的实验模态分析DMD是纯数据驱动的无需已知输入力。损伤检测对比健康结构和损伤结构的DMD模态及特征值损伤往往会导致局部振型改变或阻尼特性变化这些差异可以作为损伤指标。案例对桥梁在环境激励风、车流下的振动监测数据进行DMD可以实时识别出桥梁的前几阶主要振动模式及其阻尼为评估桥梁健康状况提供依据。6.3 金融时间序列分析市场模式分解将高维的金融市场数据如多只股票价格、多种资产收益率分解为若干具有不同频率长期趋势、中期周期、短期波动和增长/衰减率的动态模式。系统性风险分析识别那些增长率高、且涉及广泛资产组合的模式这些可能对应着市场整体的不稳定模式或传染性风险。案例对一篮子股票指数的成分股收益率序列进行DMD可能会提取出一个缓慢衰减的“市场整体趋势”模式、几个以月或季度为周期的“行业轮动”模式以及一些快速衰减的“短期噪声”模式。6.4 视频处理与动态纹理分析背景建模与前景提取将视频帧序列视为动态数据DMD可以分离出背景通常是低频或稳态模式和前景运动物体对应特定时空模式。动态纹理合成分析火焰、水流、烟雾等动态纹理的DMD模式可以用少数几个模式来高效地合成和渲染类似的动态效果。案例对监控视频做DMD背景静止的墙壁、道路会对应特征值实部接近零几乎不衰减的模式而行走的人或车辆会对应特定频率和方向传播的模式。6.5 电力系统与网络动力学电网振荡模式分析从广域测量系统WAMS获取的多点电压、相角数据中提取电网的低频振荡模式用于评估系统小干扰稳定性。社交媒体信息传播将社交网络节点用户的状态如活跃度、情感倾向随时间变化视为动力系统DMD可以识别信息传播的关键模式和影响者。要将DMD成功应用于一个新领域关键在于如何将你的数据合理地构造成“状态向量”。状态向量的每个元素应该代表系统在某个时刻的一个完整“快照”。对于图像就是展平的像素值对于传感器网络就是所有传感器的读数对于金融市场就是所有资产的价格或收益率。一旦构建好这个时空数据矩阵剩下的DMD分析流程就是通用的。最后关于那个“Dynamic Mode Decomposition (DMD).zip”资源包一个优秀的资源包应该至少包含标准DMD、精确DMD、优化DMD等核心算法的清晰实现用于数据预处理和后处理的工具函数如去均值、滤波、模态排序几个涵盖不同领域的示例脚本和数据集如流体、振动、金融以及一个简单的使用文档。在具体使用中我最看重的是代码的模块化程度和可读性这能让我快速将其整合到自己的分析流水线中或者根据特定需求修改其中的算法细节。本文还有配套的精品资源点击获取