Euler 方程组的 Riemann 问题精确解
Euler方程组是典型的双曲守恒律方程组,Riemann问题是为探究双曲守恒律模型的间断问题所设置的模型,我们考虑一维Euler方程组的Riemann问题精确解求解。 \[ \begin{aligned} \begin{pmatrix} \rho \\ \rho u \\ E \end{pmatrix}_t + \begin{pmatrix} \rho u \\ \rho u^2 + p \\ u(E + p) \end{pmatrix}_x = 0,\,\,\, E = \frac12 \rho u^2 + \frac{p}{\gamma-1} \end{aligned} \] Riemann问题介绍 对于无界计算区域 \(x \in \mathbb{R}\),Riemann问题指的是初值在\(x=0\)两侧取不同的常数值,在\(x=0\)存在一个间断,即 \[ \mathbf{U}(x,0) = \left\{ \begin{aligned} &\mathbf{U}_l, x < 0\\ &\mathbf{U}_r, x >...
MATLAB 绘图速查笔记
MATLAB的语法学习曲线很特别:入门时用起来特别简单舒服,但是深入学下去就会感觉到语法非常混乱,无所适从。 尤其在绘图部分,MATLAB杂揉了命令式语句和面向对象的语句,存在太多的语法糖,毫无逻辑性可言。 记录一些关于绘图的代码吧,便于查找。 绘制多条曲线 绘制多条曲线 1234567891011121314151617181920212223x = linspace(0, 2*pi, 100);y1 = sin(x);y2 = cos(x);y3 = sin(2*x);figure;hold on;plot(x, y1, 'r-', LineWidth=2, DisplayName='sin(x)');plot(x, y2, 'b--', LineWidth=2, DisplayName='cos(x)');plot(x, y3, 'g:', LineWidth=2, DisplayName='sin(2x)');hold...
MATLAB 并行计算
整理一下关于MATLAB并行计算的内容,主要是Parallel Computing Toolbox工具包的内容,本文内容暂不涉及集群层面的并行,也不涉及GPU的使用。 本文部分参考了下列官方文档: parfor、spmd和parfeval的对比。 后台处理。 parfor 将for循环改成parfor循环是最简单直接的并行方式,它会启动不同的进程/线程来同步执行循环,这对循环中的内容有一定的要求: 每次迭代相互独立,结果不依赖于其他迭代 不支持某些动态操作变量的函数,如 eval 和 assignin 循环次数必须明确,不能依赖于运行时的计算结果 不支持嵌套的parfor循环 对于简单的循环体,可以尝试直接用矢量化的语法,因为parfor在启动和结束过程中也会带来额外的时间成本。 在parfor循环体内部,变量被大致分为如下几类: 循环变量,对它的限制是在循环内不能对循环变量再次赋值,并且不要在循环体外部再次使用,因为并行会导致无法确定循环变量的具体值 1234parfor i = 1:n i = i + 1; % not allowed a(i) =...
Git 使用规范
...
Python 命令行参数解析
Python经常被用来写一下简化操作的脚本,并且要求脚本支持一定的选项,有必要整理一下Python命令行参数解析的用法。 Python自带的argparse模块功能已经非常强大,使用非常便捷。 Python其实还有另外两个模块可以完成同样的任务:getopt和optparse,但是前者过于简单,后者已经被弃用,目前只推荐使用argparse。 与之形成鲜明对比的是,C/C++对这种基础的需求通常都是直接手写的,或者去下载一些第三方提供的纯头文件库,为这种简单的任务引入外部依赖其实也并不合算,不如直接自己写了。 极简例子 从最简单的例子开始 test.py123import argparseparser = argparse.ArgumentParser()parser.parse_args() 这两行的含义为:设置一个参数解析器,解析参数。 直接运行脚本,无事发生 1python test.py 空的参数解析器为我们提供了--help(-h)参数,可以打印使用帮助,例如 1python test.py -h 输出形如 1234usage: test.py...
MATLAB 函数参数检查
为了得到健壮的代码,我们非常有必要对函数的参数进行检查,除了最基础的参数个数,还需要关注参数的类型和数据范围等,下面介绍几个MATLAB提供的用于参数检查的内置函数。 assert + isXXX 最简单的做法就是基于 assert 和 isXXX 检查函数的形参是否满足要求,例如 1234567891011function func(u, t, f, n, b, flag, params) assert(isnumeric(u) && (isvector(u) || ismatrix(u)), 'u must be a numeric vector or matrix.'); assert(isscalar(t) && t >= 0, 't must be a non-negative scalar.'); assert(isa(f, 'function_handle'), 'f must be a function handle.'); ...
MATLA B面向对象学习笔记——2. 进阶
现在我们关注一些进阶的内容,这部分内容并不是标准的面向对象编程内容, 而是MATLAB的特殊机制所带来的,在面向对象编程中必须考虑的问题,更具体地说,是由MATLAB内存管理机制所带来的问题。 与Java的垃圾收集机制不同,在MATLAB的内存管理机制中,内存的释放发生在确定的时刻。 句柄类和全值类 在MATLAB中实际上有两种类型: 继承自handle基类的类型,可以称为handle类、句柄类或引用类; 其他情况下的默认类型,可以称为Value类、值类型或全值类。 下面以两个自定义类型作为对比 1234567891011classdef demo1 properties data endendclassdef demo2 < handle properties data endend 在创建对象时两者都需要开辟内存来存储数据属性,但是对象和属性的关系是不一样的: 对于句柄类,对象和属性之间相当于指针指向的关系; 对于全值类,对象和属性之间是彻底的包含关系。 例如下面的赋值语句会触发对象的拷贝行为...
MATLAB 面向对象学习笔记——1. 基础
随着代码越来越复杂,我实在是无法忍受修改完全面向过程的混乱程序了,急需引入面向对象的语法进行重构。 MATLAB面向对象的笔记主要参考的是《MATLAB面向对象编程——从入门到设计模式》(徐潇,李远),书中使用的估计是2015左右的版本。 MATLAB的面向对象语法从整体上看,既不像C++和java那样严格,也没有Python那样过于灵活,而是具有自身的特点。 虽然面向对象机制不可避免地会带来一些运算效率的损失,但是我认为这是值得的,只是需要避免在涉及大量计算的性能瓶颈中使用,对于一些辅助的部分,使用面向对象所带来的简化还是非常舒服的。 简单示例 从最简单的一个自定义类型开始 point2d.m1234567891011121314151617181920212223242526classdef point2d properties x y end methods function obj = point2d(x0,y0) if nargin == 0 obj.x =...
MATLAB 学习笔记——7. 运算符
不知道为啥,之前的笔记把运算符给漏掉了,还是有必要整理一下的,因为 MATLAB 的运算符还是和其它语言有很多差异的。 算术运算符 运算符 说明 示例 + 加法 a + b - 减法 a - b + 正号 + a - 负号 - a .* 按元素乘法 A .* B .\ 按元素左除 A .\ B ./ 按元素右除 A ./ B .^ 按元素幂运算 A .^ n * 乘法 (矩阵乘法) A * B \ 左除 (矩阵) A \ B / 右除 (矩阵乘法) A / B ^ 幂运算 (矩阵) A ^ n 说明:矩阵的左除 A\B 被设计用于求解如下方程组,(在 A 可逆时)相当于 inv(A) * B, 1A * x = B -> x = A\B 矩阵的右除 B/A 被设计用于求解如下方程组,(在 A 可逆时)相当于 B * inv(A) 1x * A = B -> x = B/A 在 A 不可逆时通常会返回最小二乘解。 左除和右除具有如下转换关系('代表矩阵转置) 1B/A =...
MATLAB 学习笔记——6. 输入输出
虽然MATLAB将字符数组和字符串,字符串数组进行了区分,但是出于兼容性考虑,在下面的各种输入输出方式中无论是使用字符数组还是字符串都是一样的效果。 显示变量的值 disp函数可以用来显示一个变量的值,如果这个变量是字符串的话,也可以达到输出信息的效果,但是会自动添加一个回车。 例如 12disp('hello,world!');% hello,world! 这里的disp(X)语句加不加;都是一样的。 disp函数只接受一个参数,我们可以将字符数组拼接起来进行显示 12disp(['hello', ',', 'world']);% hello,world 在很多默认行为中都会调用disp函数,例如一个普通的赋值语句如果不以;结尾,可能会对赋值结果调用disp函数以展示它的值。 对于自定义类型也可以通过定义...