我个人对基于物理的动画很感兴趣,最近在尝试阅读《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. E:nth-child(n)

    E:nth-child(n) 语法: E:nth-child(n) { sRules } 说明: 匹配父元素的第n个子元素E,假设该子元素不是E,则选择符无效.大理石构件维修 要使该属性生效,E元素必 ...

  2. MongoDB 查看集合是否分片

    MongoDB会把分片过的集合保存在config.collection集合中,若需要查看分片键,则需要根据该集合进行查找.官方的其他很多分片快捷命令也都处于config库 三种方式 1.去config ...

  3. learning java 获取键盘输入

    通过Scanner类,获取键盘的输入 var sc = new Scanner(System.in); // while (sc.hasNext()){ // System.out.println(& ...

  4. linux系列(十五):tail命令

    1.命令格式: tail[必要参数][选择参数][文件] 2.命令功能: 用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理.常用查看日志文件. 3.命令参数: -f 循环读取 -q 不显示 ...

  5. NetworkX系列教程(1)-创建graph

    小书匠Graph图论 研究中经常涉及到图论的相关知识,而且常常面对某些术语时,根本不知道在说什么.前不久接触了NetworkX这个graph处理工具,发现这个工具已经解决绝大部分的图论问题(也许只是我 ...

  6. 洛谷P1021邮票面值设计

    题目 一道很经典的搜索题,可以锻炼搜索的能力,比如可以用dfs覆盖加dp的方式来寻找+更新答案.而且还可以通过在递归中增加数组的方式来辅助搜索. #include <bits/stdc++.h& ...

  7. python math.asin

    import mathmath.asin(x) x : -1 到 1 之间的数值.如果 x 是大于 1,会产生一个错误. #!/usr/bin/pythonimport math print &quo ...

  8. HDU 6129 Just do it ——(找规律)

    思路见:http://blog.csdn.net/qq_32506797/article/details/77206167. 利用二进制讲m次转化成log次然后进行转移. 代码如下: #include ...

  9. HDU 6041 I Curse Myself ——(仙人掌图,tarjan,转化)

    题解见这个博客:http://blog.csdn.net/ME495/article/details/76165039. 复杂度不太会算..这个经典问题的解法需要注意,维护队列里面只有k个元素即可.另 ...

  10. 判断声明出来的list为空的时候,list!=null

    判断声明出来的list为空的时候,listjcxm!=null&&listjcxm.size()==0: 有时候list不为null但是size为0 map也是类似