我个人对基于物理的动画很感兴趣,最近在尝试阅读《Fluid Engine Development》,由于内容涉及太多的数学问题,而单纯学习数学又过于枯燥,难以坚持学习(我中途放弃好多次了),打算尝试通过编写博客总结知识的学习方法来学习。

在计算数值问题时,我们经常遇到线性方程,比如基于网格的流体模拟在求解扩散和压强,需要求解线性方程组。

线性方程组

线性方程组 \(\left\{ \begin{matrix} 2 * x - y =3 \\ -x + 2 * y = 6 \end{matrix}\right\}\)​

可以转换成形如 \(A \times x=b\) 的矩阵矢量形式,转换结果如下

$\left[
\begin{matrix}
2 & -1 \
-1 & 2
\end{matrix}
\right] \left[
\begin{matrix}
x \
y
\end{matrix}
\right] = \left[
\begin{matrix}
3 \
6
\end{matrix}
\right] $

其中A是系统矩阵,x 为所求解,b是一个矢量,也就是线性方程的常数项

至于如何求解x,通常我们是通过 是让等式两边乘以系统矩阵的逆矩阵

高斯消元法

求解线性方程组我们通常使用高斯消元法来求解逆矩阵,这种方法虽然足够直接,然而把高斯消元法作为一种算法来看待,这种算法的时间复杂度达到了惊人的 \(O(n^3)\),n是矩阵的尺寸,由此我们可以明确高斯消元法并不适合有着许多数值问题的较大系统。

如果不选用高斯消元法直接求解逆矩阵,如果不通过高斯消元法,我们又该通过什么方法计算逆矩阵呢?《Fluid Engine Development》给出了就4种不那么直接的方法。通过对解的猜测和多次迭代得到近似解

雅可比方法

雅克比方法(Jacobi方法)是用于确定对角占优的解的迭代算法。求解每个对角元素,并插入近似值。然后迭代该过程直到它收敛

使用雅克比方法,需要将\(A \times x=b\) 转换成 \((D + R) \times x=b\) (矩阵A被拆成对角矩阵D和矩阵R)

所以易得解\({x}^{(k+1)} = D^{-1} (\mathbf{b} - R \mathbf{x}^{(k)})\) k是迭代的次数

同样作为矢量的解的每一个元素可以通过$ x^{(k+1)}i = \frac{1}{a{ii}} \left(b_i -\sum_{j\ne i}a_{ij}x^{(k)}_j\right),\quad i=1,2,\ldots,n.$计算得到

Gauss-Seidel法

Gauss-Seidel方法和jacobi方法有些像

将\(A \times x=b\) 转换成 \((L + U) \times x=b\) (矩阵A被拆成包含对角部分的下三角形和又矩阵A上三角形部分构成的矩阵U)

具体如下

$\left[
\begin{matrix}
2 & -1 \
-1 & 2
\end{matrix}
\right]= \left[
\begin{matrix}
2 & 0 \
-1 & 2
\end{matrix}
\right]+ \left[
\begin{matrix}0 & -1 \
0 & 0
\end{matrix}
\right] $

通过这种形式的转换我们可以轻易的发现解的第一个元素能轻易的被计算出来

$ x^{(k+1)}1 = \frac{1}{a{11}} \left(b_1 -\sum_{j>1}a_{1j}x^{(k)}_j\right)$

将上式代入第二行,我们可以得到$ x^{(k+1)}2 = \frac{1}{a{22}} \left(b_i -a_{21}x_{1} ^{k+1}-\sum_{j>1}a_{1j}x^{(k)}_j\right)$

然后可以得到同样的迭代解 \(x^{(k+1)}_i = \frac{1}{a_{ii}} \left(b_i - \sum_{j=1}^{i-1}a_{ij}x^{(k+1)}_j - \sum_{j=i+1}^{n}a_{ij}x^{(k)}_j \right),\quad i=1,2,\dots,n.\)

梯度下降法

梯度下降法将线性方程组求解问题转换成求解最小值问题 \(F(x) = |Ax - b|^{2}\)

如果x有解,则F(x) = 0,如果无解,则可以一直迭代直到x有解,

如果从x1开始,沿着梯度下降,逐步迭代来靠近零点

共轭梯度法

相对梯度下降法,共轭梯度法不使用梯度方向迭代,而是使用共轭方向

何为共轭,如果 \(a *( A b) = 0\) 则我们称向量a,b关于矩阵A 共轭

预处理共轭梯度法

在此基础上,我们可以进一步加速: 这个方法称为预处理共轭梯度法。大体的思想是,引入一个preconditioning filter到系统中:

\(M^{-1}Ax = M^{-1}b\)

具体算法实现如下

d就是新的共轭方向,alpha的推导参考链接

《Fluid Engine Development》 学习笔记1-求解线性方程组的更多相关文章

  1. 《Fluid Engine Development》 学习笔记4-预测校正不可压缩SPH-PCISPH

    传统SPH方案的主要问题之一是时间步长限制.在原始的SPH中,我们首先从当前设置计算密度,使用EOS计算压强,应用压力梯度,然后运行时间积分.这个过程意味着只需要一定的压缩量就可以触发内核半径内的压力 ...

  2. 《Fluid Engine Development》 学习笔记2-基础

    断断续续花了一个月,终于把这本书的一二两章啃了下来,理解流体模拟的理论似乎不难,无论是<Fluid Simulation for Computer Graphics>还是<计算流体力 ...

  3. 《Fluid Engine Development》 学习笔记3-光滑粒子流体动力学

    用粒子表示流体最热门的方法就是就是光滑粒子流体动力学(Smoothed Particle Hydrodynamics (SPH).) 这种方法模糊了流体的边界,用有限数量的粒子代表流体,该方法的基本思 ...

  4. matlab学习笔记之求解线性规划问题和二次型问题

    一.线性规划问题 已知目标函数和约束条件均为线性函数,求目标函数的最小值(最优值)问题. 1.求解方式:用linprog函数求解 2.linprog函数使用形式: x=linprog(f,A,b)  ...

  5. Foundations of Qt Development 学习笔记 Part1 Tips1-50

    1. 信号函数调用的时候仅仅会发送出信号,所以不需要执行 ,所以对于信号声明就行,但是不需要进行定义. 2. 只有槽函数可以声明为public,private,或者是protected的,而信号不行. ...

  6. 扩展中国剩余定理(EXCRT)学习笔记

    扩展中国剩余定理(EXCRT)学习笔记 用途 求解同余方程组 \(\begin{cases}x\equiv c_{1}\left( mod\ m_{1}\right) \\ x\equiv c_{2} ...

  7. Sparse Filtering 学习笔记(三)目标函数的建立和求解

      Sparse Filtering 是一个用于提取特征的无监督学习算法,与通常特征学习算法试图建模训练数据的分布的做法不同,Sparse Filtering 直接对训练数据的特征分布进行分析,在所谓 ...

  8. GMM高斯混合模型学习笔记(EM算法求解)

    提出混合模型主要是为了能更好地近似一些较复杂的样本分布,通过不断添加component个数,能够随意地逼近不论什么连续的概率分布.所以我们觉得不论什么样本分布都能够用混合模型来建模.由于高斯函数具有一 ...

  9. Chrome development tools学习笔记(5)

    调试JavaScript 随着如今JavaScript应用的越来越广泛,在面对前端工作的时候,开发人员须要强大的调试工具来高速有效地解决这个问题.我们文章的主角,Chrome DevTools就提供了 ...

随机推荐

  1. vue app.xxx.js 较大问题

    线上build之后发现app.XXX.js 文件特别大. 包我都改为cdn了 其他空间就是路由改为懒加载了. { path: '/a/b', name: 'ab', component: () =&g ...

  2. js中int和string数据类型互相转化实例

    今天做项目的时候,碰到一个问题,需要把String类型的变量转化成int类型的.按照常规,我写了var i = Integer.parseInt("112");但控制台报错,说是“ ...

  3. CF620E New Year Tree 线段树+dfs序+bitset

    线段树维护 dfs 序是显然的. 暴力建 60 个线段树太慢,于是用 bitset 优化就好了 ~ code: #include <bits/stdc++.h> #define M 63 ...

  4. 1069 The Black Hole of Numbers(20 分)

    For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in ...

  5. Spring Cloud Gateway(九):网关过滤器 GatewayFilter

    本文基于 spring cloud gateway 2.0.1 1.简介 GatewayFilter 网关过滤器用于拦截并链式处理web请求,可以实现横切的与应用无关的需求,比如:安全.访问超时的设置 ...

  6. Delphi BASE64单元EncdDecd的修改

    Delphi BASE64单元EncdDecd的修改 EncdDecd.pas两个函数声明: procedure EncodeStream(Input, Output: TStream);proced ...

  7. Interacted Action-Driven Visual Tracking Algorithm

    文章来源:Attentional Action-Driven Deep Network for Visual Object Tracking   博士论文(2017年8月份完稿) http://s-s ...

  8. linux物理内存与虚拟内存

    http://www.360doc.com/content/14/0123/14/14450281_347336709.shtml 1.查看内存占用情况 $ free -m -h total used ...

  9. 【Java】线程需要独立的Connection,那对已经配好session的Spring/Mabatis工程该怎么办?

    方法一:让线程从配置中取DataSource. 方法二:从配置中取出SessionFactory,然后交给线程去创建session和Connection,举例如下: // Get Session Fa ...

  10. Bitmap: 使用Bitmap作为绘图缓冲时设置抗锯齿

    android上绘图时常用的抗锯齿方法是: paint.setAntiAlias(true); 但是在以Bitmap作为绘图缓冲绘制时,绘制出来的Bitmap可能仍然有锯齿,此时可以在绘制开始前加上下 ...