MATLAB 并行计算
整理一下关于MATLAB并行计算的内容,主要是Parallel Computing
Toolbox工具包的内容,本文内容暂不涉及集群层面的并行,也不涉及GPU的使用。
parfor
将for循环改成parfor循环是最简单直接的并行方式,它会启动不同的进程/线程来同步执行循环,这对循环中的内容有一定的要求:
每次迭代相互独立,结果不依赖于其他迭代
不支持某些动态操作变量的函数,如 eval 和
assignin
循环次数必须明确,不能依赖于运行时的计算结果
不支持嵌套的parfor循环
对于简单的循环体,可以尝试直接用矢量化的语法,因为parfor在启动和结束过程中也会带来额外的时间成本。
在parfor循环体内部,变量被大致分为如下几类:
循环变量,对它的限制是在循环内不能对循环变量再次赋值,并且不要在循环体外部再次使用,因为并行会导致无法确定循环变量的具体值
1234parfor i = 1:n i = i + 1; % not allowed a(i) = i;end
切片变量,是指每个循环只访问该变量的特定位置,具体访问位置跟循环变量有关。在每一个循环中访 ...
Git 使用规范
分支规范
分支的命名习惯上使用小写字母、数字、连字符-以及斜杠/组成。
这里建议使用斜杠/因为它会被Git自动识别,并且在.git/中为其创建目录结构,例如.git/refs/heads/feature/xxx。
复杂项目
对于使用多个平行分支进行版本管理的复杂项目,分支的命名和使用通常遵循如下规范:
两个长期分支:
主分支:包括项目的所有正式版本,名称为main或master;
开发分支:包括项目的最新版本,名称为develop、dev或next;
几种短期分支:(向长期分支合并完成后即可删除)
功能分支:拆分为多个独立功能进行同步开发,名称例如feature/login-page,feature/user_module;
预发布分支:在正式版本发布之前的准备,名称例如release/xxx,xxx代表日期;(改为pre-release可能更合适)
快速修复分支:名称例如hotfix/xxx,xxx代表修复的问题编号或描述。
关于长期分支的使用:
主分支和开发分支作为一组平行线长期存在;
主分支上的结点主要是发布的稳定版本,在结点上加上对应的版本标签(例如v1.0);
...
Python 命令行参数解析
Python经常被用来写一下简化操作的脚本,并且要求脚本支持一定的选项,有必要整理一下Python命令行参数解析的用法。
Python自带的argparse模块功能已经非常强大,使用非常便捷。
Python其实还有另外两个模块可以完成同样的任务:getopt和optparse,但是前者过于简单,后者已经被弃用,目前只推荐使用argparse。
与之形成鲜明对比的是,C++对这种基础的需求通常都是直接手写的,或者去下载一些第三方提供的纯头文件库,为这种简单的任务引入外部依赖其实也并不合算,不如直接自己写了。
极简例子
从最简单的例子开始 test.py123import argparseparser = argparse.ArgumentParser()parser.parse_args()
这两行的含义为:设置一个参数解析器,解析参数。
直接运行脚本,无事发生 1python test.py
空的参数解析器为我们提供了--help(-h)参数,可以打印使用帮助,例如
1python test.py -h
输出形如 1234usage: test.py [-h]options: - ...
MATLAB 函数参数检查
为了得到健壮的代码,我们非常有必要对函数的参数进行检查,除了最基础的参数个数,还需要关注参数的类型和数据范围等,下面介绍几个MATLAB提供的用于参数检查的内置函数。
validateattributes
validateattributes函数可以为我们检查某个具体参数的类型以及是否满足某些要求,不满足要求会抛出错误。
假设我们有一个函数func1,它接受两个输入参数a和b,我们要求:a是一个非空的标量,b是一个非空的向量。
1234567function result = func1(a, b) validateattributes(a, {'numeric'}, {'nonempty', 'scalar'}); validateattributes(b, {'numeric'}, {'nonempty', 'vector'}); result = a + sum(b ...
MATLAB面向对象学习笔记——2. 进阶
现在我们关注一些进阶的内容,这部分内容并不是标准的面向对象编程内容,
而是MATLAB的特殊机制所带来的,在面向对象编程中必须考虑的问题,更具体地说,是由MATLAB内存管理机制所带来的问题。
与Java的垃圾收集机制不同,在MATLAB的内存管理机制中,内存的释放发生在确定的时刻。
句柄类和全值类
在MATLAB中实际上有两种类型:
继承自handle基类的类型,可以称为handle类、句柄类或引用类;
其他的类型,可以称为Value类、全值类。
下面以两个自定义类型作为对比 1234567891011classdef demo1 properties data endendclassdef demo2 < handle properties data endend
在创建对象时两者都需要开辟内存来存储数据属性,但是对象和属性的关系是不一样的:
对于句柄类,对象和属性之间相当于指针指向的关系;
对于全值类,对象和属性之间是彻底的包含关系。
例如下面的赋值语句会触发对象的拷贝行为 123>> s1 = dem ...
MATLAB面向对象学习笔记——1. 基础
随着代码越来越复杂,我实在是无法忍受修改完全面向过程的混乱程序了,急需引入面向对象的语法进行重构。
MATLAB面向对象的笔记主要参考的是《MATLAB面向对象编程——从入门到设计模式》(徐潇,李远),书中使用的版本不清楚,估计是2015左右的版本。
简单示例
从最简单的一个自定义类型开始 point2d.m1234567891011121314151617181920212223242526classdef point2d properties x y end methods function obj = point2d(x0,y0) if nargin == 0 obj.x = 0; obj.y = 0; elseif nargin == 2 obj.x = x0; obj.y = y0; else error ...
MATLAB 绘图笔记
MATLAB的语法学习曲线很特别:入门时用起来特别简单舒服,但是深入学下去就会感觉到语法非常混乱,无所适从。
尤其在绘图部分,MATLAB杂揉了命令式语句和面向对象的语句,存在太多太多的语法糖,毫无逻辑性可言。
基本作图
MATLAB可以非常容易地画一个曲线图,只需要三行代码即可(下面的figure;语句可以省略)
12345x=linspace(0,5);y=sin(x);figure;plot(x, y);
MATLAB将会弹出一个绘图窗口,在其中绘制曲线。
我们可以在曲线图中加上常见的绘图元素 1234567891011121314% 标题title('Sine Wave');% 轴标签xlabel('x');ylabel('sin(x)');% x轴和y轴范围axis([0 2*pi -1.5 1.5]);% 或者单独设置x轴范围% xlim([xmin xmax])% 添加网格grid on;
我们可以一次性使用plot绘制多条曲线 123456x = linspace(0, 2*pi, 100);y1 = sin( ...
MATLAB 学习笔记——6. 输入输出
虽然MATLAB将字符数组和字符串,字符串数组进行了区分,但是出于兼容性考虑,在下面的各种输入输出方式中无论是使用字符数组还是字符串都是一样的效果。
显示变量的值
disp函数可以用来显示一个变量的值,如果这个变量是字符串的话,也可以达到输出信息的效果,但是会自动添加一个回车。
例如 12disp('hello,world!');% hello,world!
这里的disp(X)语句加不加;都是一样的。
disp函数只接受一个参数,我们可以将字符数组拼接起来进行显示
12disp(['hello', ',', 'world']);% hello,world
在很多默认行为中都会调用disp函数,例如一个普通的赋值语句如果不以;结尾,可能会对赋值结果调用disp函数以展示它的值。
格式化字符串
MATLAB支持和C语言几乎一样的字符串格式化函数,包括fprintf和sprintf。
fprintf格式化输出到控制台或文件中,返回值只是输出的字节数,没什么用,例如
12345fprintf('He ...
MATLAB 学习笔记——5. 脚本与函数
.M 文件
MATLAB 的.m文件可以分成两类:
脚本文件,不接受输入参数,它们处理工作区中的变量和数据。
函数文件,可接受输入参数,并且可以有返回值,内部变量是函数的局部变量。
除此之外,MATLAB也提供了.mlx格式的实时脚本(实时函数)文件,大致就是Jupyter
Notebook的模仿,但是用起来并没有后者那么好用,各种操作不够自然。如果我们需要在.m文件和.mlx文件之间转换,直接改文件后缀的做法是不安全的,可能会导致格式错误,需要用MATLAB专门提供的工具进行转换。
脚本文件
载入脚本文件会依次执行所有命令,在重复执行大量命令时,可以整理为一个脚本进行执行。
对于当前目录下的myfile.m脚本文件,在命令行窗口可以输入脚本的名称来执行脚本(不含文件后缀),
执行结果会输出到命令行窗口。脚本文件可以访问当前工作区的所有变量,对变量的创建和修改也会留在当前工作区中。
例如,脚本文件
myfile.m123456789sum=0;n=0;while sum<100 n=n+1; sum=sum+n;endsum=sum-n;n=n-1;n,sum
执行结 ...
MATLAB 学习笔记——4. 流程控制
在划分控制结构所对应的代码块时,编程语言通常采用如下三种做法:
基于大括号{}:例如C/C++,Java
基于end标记:例如FORTRAN,MATLAB
基于缩进:Python
MATLAB受到FORTRAN的影响很大,也采用基于end的代码块标记。
if 条件语句
提供例子即可
123if x>1 x=1;end
12345if x>1 y=x;else y=1;end
1234567if x>10 y=x;elseif x>0 y=1;else y=0end
switch 条件语句
MATLAB支持基本的switch语句,我们可以判断表达式的值以进入不同的分支,不需要在分支结束使用break,因为不会进入下一个分支,默认分支为otherwise。MATLAB并不要求case后面的结果是常量。
12345678switch x case 1 z=1 case 2 z=2 otherwise z=3end
对于更复杂的switch情况,我们还 ...