线性方程求解器的矩阵分裂

大概思路是对的,但是查老师可能会出现幻觉,小心食用 😃

这段代码是在初始化迭代法求解器,构建迭代矩阵和分裂矩阵。以下是详细解释:

python 复制代码
if init_from_func or init_from_input:
    # 1. 存储刚度矩阵
    self.stiff_p = stiff_p
    
    # 2. 矩阵分裂:将刚度矩阵分解为下三角、对角、上三角部分
    l_p = np.tril(self.stiff_p, -1)  # 严格下三角部分
    d_p = np.diag(np.diag(self.stiff_p))  # 对角部分
    u_p = np.triu(self.stiff_p, 1)  # 严格上三角部分
    
    # 3. 组合常用矩阵块
    lu_p = l_p + u_p  # 非对角部分(L+U)
    ld_p = l_p + d_p  # 下三角+对角(L+D)
    
    # 4. 根据求解方法选择分裂方式
    if self.solver_method in ['Jacobi', 'CG', 'MG-J']:
        self.m_p = d_p      # Jacobi方法:M = D
        self.n_p = lu_p     # N = L + U
    elif self.solver_method in ['GS', 'MG-GS']:
        self.m_p = ld_p     # Gauss-Seidel方法:M = L + D
        self.n_p = u_p      # N = U
    else:
        raise ValueError('Incorrect solver method')
    
    # 5. 计算 M⁻¹N(迭代矩阵的关键组成部分)
    self.m_inv_n_p = np.linalg.solve(self.m_p, self.n_p)
    
    # 6. 构造完整的迭代矩阵 G
    self.g_mat = (np.eye(stiff_p.shape[0]) - configs.OMEGA *
                np.linalg.solve(self.m_p, self.stiff_p))

🔍 关键概念说明:

1. 矩阵分裂(Matrix Splitting)

迭代法的核心思想:A = M - N,其中:

  • M 是容易求逆的矩阵
  • N 是剩余部分

2. 不同方法的分裂方式

Jacobi方法
复制代码
A = D - (L + U)
M = D, N = L + U
迭代矩阵:G = I - ω·D⁻¹·A
Gauss-Seidel方法
复制代码
A = (L + D) - U  
M = L + D, N = U
迭代矩阵:G = I - (L + D)⁻¹·A

3. 变量含义

  • self.m_p: 预处理矩阵 M
  • self.n_p: 剩余矩阵 N
  • self.m_inv_n_p: M⁻¹N,用于迭代更新
  • self.g_mat: 完整的迭代矩阵 G

🎯 迭代矩阵的作用:

迭代公式:

复制代码
u^{(k+1)} = G·u^{(k)} + M⁻¹·f

其中 G = I - ω·M⁻¹·A 是迭代矩阵

收敛性分析:

  • G 的谱半径 ρ(G) < 1 时,迭代收敛
  • 特征值分析可以预测收敛速率

📊 应用场景:

  • 'Jacobi': 标准Jacobi迭代
  • 'CG': 可能用于预处理共轭梯度法
  • 'MG-J': 多重网格中的Jacobi光滑器
  • 'GS': Gauss-Seidel迭代
  • 'MG-GS': 多重网格中的Gauss-Seidel光滑器

这段代码为后续的迭代求解和收敛性分析准备了必要的矩阵组件。


这段代码实现了在迭代过程中更新各种误差指标的功能。以下是详细解释:

python 复制代码
def update_metrics(self, u_approx, index):
    # 1. 计算残差
    residual = utils.compute_residual(self.stiff_p, self.f_p, u_approx,
                                      non_bc=self.solvers[0].non_bc)
    self.residuals[index, :] = residual
    
    # 2. 计算误差
    error = u_approx - self.u_true
    self.errors[index, :] = error
    
    # 3. 计算残差范数和误差范数
    self.residual_norms[index] = np.sqrt(np.mean(residual ** 2))
    self.error_norms[index] = np.sqrt(np.mean(error ** 2))
    
    # 4. 计算模态误差(将误差投影到特征模态上)
    if configs.DIMENSIONS == 1:
        scores = np.linalg.solve(self.eigenvectors, self.errors[index, 1:-1])
    else:
        scores = np.linalg.solve(self.eigenvectors,
                                 self.errors[index, self.solvers[0].non_bc])
    self.modes_errors[index, :] = \
        scores[np.array(self.modes_of_interest)-1]

🔍 详细步骤说明:

1. 计算残差

python 复制代码
residual = utils.compute_residual(self.stiff_p, self.f_p, u_approx, non_bc=self.solvers[0].non_bc)
  • 计算当前解的残差:r = f - A·u
  • non_bc 参数排除边界点(只考虑内部点)

2. 计算误差

python 复制代码
error = u_approx - self.u_true
  • 计算与真实解的误差:e = u_approx - u_exact

3. 计算范数

python 复制代码
self.residual_norms[index] = np.sqrt(np.mean(residual ** 2))  # L2范数
self.error_norms[index] = np.sqrt(np.mean(error ** 2))        # L2范数
  • 计算残差和误差的L2范数(均方根)

4. 计算模态误差(核心部分)

python 复制代码
# 1D情况:排除边界点
if configs.DIMENSIONS == 1:
    scores = np.linalg.solve(self.eigenvectors, self.errors[index, 1:-1])
# 多维情况:使用non_bc掩码
else:
    scores = np.linalg.solve(self.eigenvectors,
                             self.errors[index, self.solvers[0].non_bc])

# 提取感兴趣模态的误差
self.modes_errors[index, :] = scores[np.array(self.modes_of_interest)-1]

🎯 模态误差计算原理:

数学基础:

误差向量可以表示为特征模态的线性组合:

复制代码
e = Σ c_i · φ_i

其中 c_i 是模态系数(即模态误差)

计算方法:

通过求解线性系统:

复制代码
Φ · c = e

其中:

  • Φ: 特征向量矩阵(列是特征模态)
  • c: 模态系数向量
  • e: 误差向量

结果:

scores[i] 就是第 i+1 个模态的误差幅度

📊 在文献中的应用:

这正好对应了Zhang等(2024)论文图2C第四列,用于显示:

  • 模态1(低频):收敛最慢,DeepONet重点处理
  • 模态5(中频):中等收敛速度
  • 模态10(高频):收敛最快,Jacobi处理效果好

💡 索引调整:

python 复制代码
scores[np.array(self.modes_of_interest)-1]
  • -1 是因为Python索引从0开始,而模态编号从1开始
  • 例如:模态1对应 scores[0],模态5对应 scores[4]

这个函数是分析迭代法频谱特性的核心工具,帮助理解不同频率分量的收敛行为。

相关推荐
YuTaoShao21 小时前
【LeetCode 每日一题】1277. 统计全为 1 的正方形子矩阵
算法·leetcode·矩阵
打螺丝否1 天前
稠密矩阵和稀疏矩阵的对比
python·机器学习·矩阵
人机与认知实验室1 天前
人机环境系统智能矩阵理论
线性代数·矩阵
fFee-ops3 天前
73. 矩阵置零
线性代数·矩阵
星逝*3 天前
LeetCode刷题-top100( 矩阵置零)
算法·leetcode·矩阵
码界奇点3 天前
豆包新模型矩阵与PromptPilot构建企业级AI开发的体系化解决方案
人工智能·线性代数·ai·语言模型·矩阵·硬件工程
酸奶乳酪3 天前
矩阵和向量的双重视角
线性代数·矩阵
阿维的博客日记3 天前
LeetCode 240: 搜索二维矩阵 II - 算法详解(秒懂系列
算法·leetcode·矩阵
桐果云4 天前
解锁桐果云零代码数据平台能力矩阵——赋能零售行业数字化转型新动能
大数据·人工智能·矩阵·数据挖掘·数据分析·零售