前言
自己在学习这个工具的时候是由点及面的,而不是从头到尾按照顺序进行学习,这样的话不知道自己的需求是什么,学习起来就显得非常的乏味,这样就感受不到工具所带来的简便性所带来的乐趣。 仅仅收藏一些自己感觉有用的技巧以及遇到的错误及其解决方法,因为matlab能做的事太多了,网络上教程又那么多,不想画蛇添足, 另外吐槽的一点就是关于matlab的中文书籍(有不少),书中错误挺多,像是半成品,匆忙完成,虽说是工具吧,但是体现了认真负责的态度,而不是简单的堆砌文字,算了自己也没资格去评论。 这个写的太晚了,但是对于未来几十年,这恰恰不晚。另外matlab的程序,百分之95的代码都可以octave中运行的,而且octave是免费开源的,可以避免不必要的版权纠纷,尤其是在公司里上班,可以带来不必要的麻烦, 因此在本文最后会有一部分octave配置方面的内容。 另外个人感觉最重要的就是学会使用 help和搜索技巧, 不光是matlab, 其他编程语言也是如此。
matlab有大量的资源在文件交换那,如果是想搜中文的话,进入matlab中文论坛去文件交换那搜索下载就好,或者是搜索 File Exchange 关键字也可以找到文件交换的入口。
命名方式
因为命名方式对于程序而言是非常重要的,自己对此感触颇深,以前写出的代码,以为只有天知道我知道,如今工作了再看那些代码,只有鬼知道。
1,变量名应该能够反映该变量的含义或用途,以小写字母开头,采用大小写混用模式或下画线分割模式, 如:areYouOk,are_you_ok等。
2,临时变量的变量名尽量短小。
3,布尔变量禁止使用否定式的变量名。比如使用areYouOk,而不使用areYouNotOk,一是因为~areYouNotOk相当于双重否定,感觉会有些别扭,二是前者感觉会更加的简介。
4,缩写形式即使全部为大写字母,在变量命名名时也应该与小写字母混合使用。
5,常数名、全局变量名、永久变量名应该全部采用大写字母,且用下画线分割单词。
6,结构体命名应该以大写字母开头
7,结构体的字段名不需要包含结构体名的含义
8,所有的函数命名应该采用英文形式,禁止使用汉语拼音
编程规范
总体原则:避免使用含糊代码。代码不是越简洁越好,而是越清楚越好,一开始写的时候还是需要注意些的,不能图一时爽,修改维护的时候就知道难受了,下面主要是写给自己看的。
1) 在内存充足的情况下,变量尽量不要重复使用,赋予每个变量唯一的含义,可以增强代码的可读性。
2) 在文件开始的注释,为重要变量编写文档。
3) 在常量定义处,为该常量编写注释。
4) 尽量少地使用全局变量。全局变量过多,不利于代码的维护和阅读。
5) 浮点数的逻辑运算要当心系统误差。
6) 函数头部的注释应该支持help和lookfor对该函数的查询,因此,该行注释中应尽可能包含可能的搜索关键字。
7) 函数头部的注释应描述该函数的功能,并列出输入参数不同时该函数的语法和功能。
函数定义
function 定义 M 文件函数 |
这里nargin可以分解为n+arg+in,即Number+ argument+ input,输入参数的个数。其他类似。 函数体中的nargin与nargout 函数 ,能够在调用一个函数时,指明函数有几个输入和输出参数。比如
n = nargin 返回所在函数的输入参数个数。 |
这样在输入参数不够或者多的时候抛出异常。
varargin 和 varargout 传送或返回不定数目的参数。有一些函数,输入的参数或返回到调用函数的参数个数不确定,这就需要用到varargin 和 varargout 函数。比如
function out = myFun(varargin) |
如果在函数声明行将 varargin 作为最后一个输入参数,则函数在调用时可接受任意个变量。函数 myFun 接受任意个输入参数,组成一个单元数组,varargin 为单元数组名。该单元数组第 i 个单元就是从 varargin 位置算起的第 i 个输人参数。类似的,比如定义
function out = myFun(a,varargin) |
当调用格式为myFun(a,b,c)时,varargin 是长度为 2 的单元数组,并且 varargin{1} = b, varargin{2} = c。
技巧
0, 从自己学习的角度来说,最重要的就是学会使用help, 从自带的例子就可以学到很多,网上的一些说明和教程也不见得是对的,从自带的帮助里面也可以学习到一些编程技巧等等。
1,set(0,’RecursionLimit’,N) 修改最大递归限制,这个是自己寻找合适的参数时,有时需要跑很久才能找到自己需要的参数,限制就是递归到500次就停止了,这样修改可以使得留下更多的时间冲一杯咖啡再回来看看结果有没有出来。 (忘记说一件事了,如果把N改的很大,内存溢出别来打我),当然另外一种极端的方法就是设置类似于控制里面的思路,设置误差函数,误差也就是你期待的值减去实际的值,当满足所给精度要求后,退出循环(简单的实现就是利用while循环),输出相关参数,这个对于给定输入并给出特定输出的时候比较适用(类似于函数关系)。这个可以应用于离线仿真的寻找比较好的参数的时候使用,这样就无须手动调整了。
2,若a为一个向量,则命令 b = a(:) 可以保证b为列向量。即无论a为行向量或列向量,b均是列向量, 这个在设计程序的时候非常有用。 要有预分配内存的习惯,这样会使得程序的运行效率高一些。
3,在程序的主函数或者在运行函数前写上dbstop if error, 十分有助于调试; strfind 可以作用于数值数组用于查找子串的位置。
4,如果可以, 请使用 octave 来替代matlab,因为以后matlab毕竟是商业数学软件,而且价格还很贵,在mac上使用可以在配置文件中加上 alias octave=’octave-cli’,这样退出的话,就不会有多余的命令行界面了, 等有时间的话去测试下linux上是不是也是这样的。
5,就运行效率来说,逻辑索引要高于数值索引。 A(sub2ind(size(A),i,j))=[], 删除A的第i行、第j列的元素。
6,evalin 和 assignin 两个函数可以实现函数工作空间和基本工作空间中的变量的相互使用, 对于实验室小伙伴们在使用别人的代码去绘图或者是提取一些变量的时候非常有用,因为局部函数的值如果不去调试,一般来说是不会出现在工作空间中的。
7,MATLAB 中的 import 语句作用与 Python 中不同。Python使用 import 语句加载代码并使之能够访问。MATLAB使用 import 函数是为了不用包名就可以直接使用类或函数。
8,deal函数的使用可以使得程序简洁起来。 将输入分别分配给每个输出。
9,学会使用try,catch函数,一来可以避免程序因为错误或其他缘故而中止,二来可以很好的简化代码量。
10,在matlab中尽量避免使用for循环,有如下的替代方法,(1)优先考虑用向量化的运算来代替循环操作。(2)在必须使用多重循环时,循环次数少的放在外层,循环次数多的放在内层。
11, 逻辑数组和标量用.*, 这样会使得效率提升的非常快,下面举个栗子。
octave配置
从matlab转到octave其实就花了几天的时间,因为长期在命令行下工作,所以在命令行下玩octave当然不在话下。 如果你喜欢交互式的,那目测玩这个会有点费劲的,毕竟是开源的,没有matlab调试什么什么的那么方便了。
自己octave配置文件内容(.octaverc), 前提是这些包要安装上,不然就报错了,退出的话别直接ctrl+z了,不然后台还是在运行,在命令行中exit就行。
如果通过ctrl+z退出了,其后台依旧在运行,如果通过top指令查看进程并结束掉octave那个进程,可以使用如下方式 ‘ps aus|grep octave-cli’, 会想为什么会是这个指令呢?是不是有好奇心去探索下,哈哈~。
这里是自己配置文件里的内容,就像vim或者shell一样,换任何台linux/macos系统电脑,只需把之前的配置文件复制到新的电脑中即可,这样可以大大的简化繁琐的配置,这个是受用终身的。所以这里又一次的啰嗦了下。(最好把配置文件放在github或其他非常容易获取到的地方,放心,这个配置文件别人获取了也没什么用,属于私人订制)
展开
setenv("GNUTERM","qt") |
后记
2023年8月评: 已经有好几年没有用MATLAB了,好多东西只有印象,好多技巧都给忘记了。。。。MATLAB这篇几乎一直没有更新过,曾几何时最熟悉的工具被自己遗忘的差不多了,惭愧;
参考
[1] 《MATLAB GUI学习手记第二版》