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.'); ...
MATLAB 面向对象学习笔记——2. 进阶
现在我们关注一些进阶的内容,这部分内容并不是标准的面向对象编程内容,而是MATLAB的特殊机制所带来的,在面向对象编程中必须考虑的问题。 更具体地说,是由MATLAB内存管理机制所带来的问题。与Java的垃圾收集机制不同,在MATLAB的内存管理机制中,内存的释放发生在确定的时刻。 句柄类和全值类 在MATLAB中实际上有两种类型: 继承自handle基类的类型,可以称为handle类、句柄类或引用类; 其他情况下的默认类型,可以称为Value类、值类型或全值类。 下面以两个自定义类型作为对比 1234567891011classdef demo1 properties data endendclassdef demo2 < handle properties data endend 在创建对象时两者都需要开辟内存来存储数据属性,但是对象和属性的关系是不一样的: 对于句柄类,对象和属性之间相当于指针指向的关系; 对于全值类,对象和属性之间是彻底的包含关系。 例如下面的赋值语句会触发对象的拷贝行为 123>&g...
MATLAB 面向对象学习笔记——1. 基础
随着代码越来越复杂,我实在是无法忍受修改完全面向过程的混乱程序了,急需引入面向对象的语法进行重构。 笔记主要参考的是《MATLAB面向对象编程——从入门到设计模式》(徐潇,李远),书中使用的估计是2015左右的版本。 MATLAB的面向对象语法从整体上看,既不像C++和java那样严格,也不像Python那样过于灵活,而是具有自身的特点。 虽然面向对象机制不可避免地会带来一些运算效率的损失,但是我认为这是值得的,只是需要避免在涉及大量计算的性能瓶颈中使用,对于一些辅助的部分,使用面向对象所带来的代码简化还是非常舒服的。 简单示例 从最简单的一个自定义类型开始 point2d.m1234567891011121314151617181920212223242526classdef point2d properties x y end methods function obj = point2d(x0,y0) if nargin == 0 obj.x = 0; ...
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 = (A'...
MATLAB 学习笔记——6. 输入输出
虽然MATLAB将字符数组和字符串,字符串数组进行了区分,但是出于兼容性考虑,在下面的各种输入输出方式中无论是使用字符数组还是字符串都是一样的效果。 显示变量的值 disp函数可以用来显示一个变量的值,如果这个变量是字符串的话,也可以达到输出信息的效果,但是会自动添加一个回车。 例如 12disp('hello,world!');% hello,world! 这里的disp(X)语句加不加;都是一样的。 disp函数只接受一个参数,我们可以将字符数组拼接起来进行显示 12disp(['hello', ',', 'world']);% hello,world 在很多默认行为中都会调用disp函数,例如一个普通的赋值语句如果不以;结尾,可能会对赋值结果调用disp函数以展示它的值。 对于自定义类型也可以通过定义 disp 方法来达到自定义输出效果的目的。 格式化字符串 MATLAB支持和C语言几乎一样的字符串格式化函数,包括fprintf和sprintf。 fprintf格式化输出到控制台或文件中,返...
MATLAB 学习笔记——5. 脚本与函数
.M 文件 MATLAB 的.m文件可以分成两类: 脚本文件,不接受输入参数,它们处理工作区中的变量和数据。 函数文件,可接受输入参数,并且可以有返回值,内部变量是函数的局部变量。 MATLAB 对于 .m 文件的文件名有一些特殊要求: 文件名允许由字母、数字、下划线(_)和点(.)组成,注意不包括-和空格; 文件名必须以字母开头; 文件名区分大小写。 较新版本的MATLAB提供了后缀为.mlx的实时脚本/函数文件,大致就是对Jupyter Notebook的模仿,但是用起来并没有后者那么好用,各种操作不够自然。由于.mlx文件不是纯文本文件,如果我们需要在.m文件和.mlx文件之间转换,必须通过MATLAB专门提供的工具进行转换,vscode等编辑器也并不支持.mlx文件的显示。 脚本文件 载入脚本文件会依次执行所有命令,在重复执行大量命令时,可以整理为一个脚本进行执行。 对于当前目录下的myfile.m脚本文件,在命令行窗口可以输入脚本的名称来执行脚本(不含文件后缀), 执行结果会输出到命令行窗口。脚本文件可以访问当前工作区的所有变量,对变量的创建和修改也会留在当...
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...
MATLAB 学习笔记——3. 结构体数组和元胞数组
在编程实践中,仅仅只靠浮点数数组还是不够的,我们还需要其他更灵活的数据结构(运行效率也会更慢),最常见的数据结构是结构体数组和元胞数组。 结构体数组 虽然MATLAB官方将其称为结构体数组,但是实际上不管是从使用还是实现的角度,将其称为字典都更合适。在C++的语境中,结构体约等于自定义类型,而对于MATLAB,自定义类型和结构体数组是截然不同的。 结构体数组(struct)是 MATLAB 中一种非常灵活的具名数据类型,可以将不同类型的数据直接组合在一起,每个字段具有名称,可以包含不同类型和大小的数据,结构体数组使得组织和管理复杂数据更加方便。 结构体数组的使用非常灵活,可以使用点符号直接创建 12345% 此前person未定义% 创建一个结构体数组并添加字段person.name = 'John Doe';person.age = 30;person.height = 1.75; 需要注意的是,这里的person变量尚未定义,否则上述语句只有在person已经是一个结构体数组时才会成立,此时的效果是创建或修改对应的字段。 甚至支持下面这种多层结构体的直...
MATLAB 学习笔记——2. 矩阵
概述 MATLAB 对于矩阵的支持非常好,以矩阵运算为代表的基本运算功能一直是 MATLAB 引以为自豪的核心与基础。我们可以把向量和矩阵都视作矩阵进行统一的操作。在下文中我们默认讨论二维矩阵,但 MATLAB 支持多维矩阵。行向量即行数为 1 的矩阵,列向量即列数为 1 的矩阵。 在内存中,MATLAB 使用列主序进行连续存储,与 Fortran 相同,与 C 语言是反的。在下标的使用中,MATLAB 默认下标从 1 开始,与 Fortran 相同,与 C 语言等绝大部分编程语言都不同。 矩阵的尺寸信息可以通过下面的语句获取: size(A) 行数和列数,返回一个1x2的行向量; size(A,1) 行数; size(A,2) 列数。 注意: MATLAB 对于矩阵的支持是非常彻底的,甚至标量都是被视作 1 行 1 列的矩阵。 MATLAB 的很多内置函数对于行/列向量有特殊处理,在语义上并不能自然地推广到矩阵,可能是为了用户的便利,也可能是历史兼容性。例如不建议通过length获取尺寸信息,为了兼容行列向量的长度语义,这个函数只会返回矩阵的行数和列数之间的最大值。 下面...
MATLAB 学习笔记——1. 基础
之前对 MATLAB 的使用都是轻量级的,因此总是不太熟,趁着必须要用 MATLAB 的机会,小结一下 MATLAB 的基本语法,便于查阅。(2022年9月) 之前的MATLAB笔记还是太简陋了,必须加上面向对象等部分组成更完整的系列笔记。因为现在手上的代码还是太乱了,必须彻底重构一下,先把笔记补上。(2024年6月) 基本语法 注释:MATLAB 使用百分号%进行单行注释,使用%{...%}进行多行注释(不常见),使用%%开头的内容不仅是注释,而且会被视作节标题。(在字符数组中%仍然被用于占位符) 分号:; MATLAB 并不需要强制使用分号作为语句的结尾,以空格或回车结尾即可。不使用分号结尾时会把计算结果显示出来,使用分号结尾则会抑制计算结果的显示。 续行符:在第一行的结尾使用...可以把命令接续到第二行。(如果直接把...接在数字后面会报错,可以加空格) 命令补全:Tab 键。 对命令行窗口清屏:clc MATLAB 几乎所有数据都是矩阵:行向量是行数为 1 的矩阵,数是行数列数均为 1 的矩阵,甚至一个无效命令,它的返回值[]都是一个 0 行 0 ...