MATLAB程序设计语言(1)---入门
公众号:理念世界的影子
文不可无观点,观点不可无论据。
转载请注明出处
MATLAB功能强大,编程方便,是国际广泛使用的计算软件。目前已有很多书籍介绍其在工程上的应用,但很少有从程序设计语言的角度写的书或文章。
MATLAB是什么
+
20世纪70年代末MATLAB诞生了,新墨西哥州大学计算机系主任Cleve Moler为了让学生方便地进行矩阵计算,封装了当时代表矩阵计算最高水平的线性代数计算库LINPACK和EISPACK的接口,建立了交互式计算平台MATLAB,作为免费软件向公众开放。
80年代初,Steve Bangert主持开发了解释器程序,Steve Kleiman完成了图形功能设计,John Little和Cleve Moler主持开发了数学分析模块,编写了用户指南,形成了MATLAB的第一个商业版。
5.0版后,MATLAB引入了更多的数据结构,如多维矩阵等,使其更易于使用。5.3版本后,MATLAB核心由Fortran转为了C语言。
7.2版本后,MATLAB版本采用R2006a命名,至此,MATLAB版本每年发布两次并按后缀a和b命名。
如今MATLAB既是一门编程语言,也指一种编程环境,它是一成套集成的软件体系,并具有如下特点:
一切皆为数组的数据类型设计,语言抽象能力大幅跨越,大大提升了代码简洁性和可读性;
动态类型(无需显式数据类型声明)、弱类型(变量获得类型后仍可赋值为另一种数据类型)的解释型语言。MATLAB采用了一种运行期间才去确定数据类型,而且数据类型可变的语言,以程序执行效率为代价,大大解放了编程的学习成本和人力成本;
方便、强大的图形绘制功能。MATLAB内置强大、易于使用、具备自动化控制能力的数据图形和交互界面制作功能,达到数据计算、数据展示的一体化;
丰富、强大的工具箱支持。MATLAB始终跟踪最新的数值计算库(BLAS、LAPACK等),保证了矩阵计算函数的正确和高效;同时MATLAB吸收了工业界,尤其是控制领域的大量成果,形成了完善的工具箱支持;Simulink的引入更进一步释放了其威力。发展至今基本上可以说,对于日常工作,MATLAB内部的函数和功能,几乎没有缺的,而只有你不知道的;
堪称典范的强大的帮助系统。
正是以上特点的综合作用,MATLAB业已发展为国际广泛使用的计算软件。
受众和体例
+
本公众号不会对MATLAB基础操作做太多介绍,由于在大多数情况下,可将MATLAB视为一种更方便的C语言,特别是针对数学运算高度优化的C语言。因此公众号着重阐述MATLAB的不同之处,较适用于有一定C语言或MATLAB语言基础,特别是对C语言感兴趣的读者。
为了提高兴趣(和阅读量),所有篇均有至少一个示例。示例均为笔者原创编制,简单示例不超过20行,复杂示例不超过50行,并对重要行有所解释。读者可以拷贝示例运行。示例内会包含本篇重要知识点,如果对知识点熟悉可以不读。但仍建议一读,因为里面有笔者自己的理解和体会,可以不夸张地说,有着不同于任何教科书的描述。
后续文章由于要用到数据结构的二进制解析,为表达方便,使用的是MATLAB 2010b的32位版本。几乎为10年前版本,因此和很多读者的界面可能不一致,但笔者坚信,界面再新,编程理念和核心应该不会变。
拼图游戏示例
+
pintu.m
1 function pintu
2 pintu=[2 4 3;1 0 6;7 5 8];
3 pintudone=[1 2 3;4 5 6;7 8 0];
4 disppintu();
5 assignin('caller', 'move', @move); % 点击时需使用函数
6
7 function move(m, n) % 嵌套函数中可使用父函数中的参数
8 [i, j, ~]=find(pintu==0);% 找到为0的格子坐标
9 if(norm([m-i n-j])==1)% 移动相邻格子
10 [pintu(m, n) pintu(i, j)]=deal(pintu(i, j), pintu(m, n)); % 交换两个值
11 disppintu();
12 end
13 end
14
15 function disppintu()
16 clc; % 清空屏幕
17 disp('拼图游戏');
18 [m, n]=size(pintu);
19 str=[];
20 for i=1:m
21 for j=1:n
22 v=pintu(i,j);
23 if(v) str=[str sprintf('<a href="matlab: move(%d, %d)">%d</a> ', i, j, v)]; % 增加超链接
24 else str=[str ' '];end
25 end
26 if(i~=m) str=[str sprintf('\n')];
27 end
28 end
29 disp(str);
30 if(all(pintu==pintudone)) disp('完成!');end % 判断是否完成
31 end
32
33 end
第2行,3×3排列的矩阵,其中0处为空格,可将任意数字移至空格,此数字处变为空格;
第3行,为矩阵的完成形式;
第4行,显示拼图,拼图中每个数字带有超链接,点击后运行move函数;
第5行,由于超链接中的move函数无法访问函数内部,因此将其作为句柄导出。此处的函数句柄除可以访问move函数外,还可以访问pintu函数中的变量,它是一个带环境的闭包(后面描述);
第7行,嵌套的move函数可以直接使用父函数中的pintu变量,而不需要传递;
第8行,查找pintu为0的坐标,其中~表示占用符,表示这个变量不需要使用,但需要知道这儿有个变量,除了~外,也可以使用ans(MATLAB默认输出变量名);
第9行,求n-i和n-j的平方和,确保移动的格子与空的格子相邻;
第10行,将换空格和移动格位移,此处使用了deal函数,后续会进行说明;
第11行,交换顺序后,再次画出拼图;
第15行,拼图嵌套子程序,清除之前的拼图并重新绘制;
第23行,插入超链接,点击后执行move函数,每个数字对应不同参数值,即本数字所在的坐标位置;
第30行,如果图形对应,则输出完成。其中==返回的为矩阵,使用all保证所有矩阵元素均为1。
运行上述程序即可进行拼图游戏,游戏中,显示的数字带有下划线,鼠标移动至其上后,MATLAB状态栏会显示点击本链接执行的命令,点击后,图形刷新显示。
知识点(入门篇,待续...)
+
性能分析函数
性能分析一般是熟悉语言后的进阶功能,但由于在进行程序分析时常会用到,因此放到最前面,它的使用很简单,使用两套函数基本就够了。
tic/toc:TIC 启动计时器。TIC 和TOC 函数一起工作来计量逝去的时间。TIC自身存储当前时间,稍后使用TOC来计算当前与之前存储时间的间隔。可以使用tic;toc对来获取两者之间时间,也可以使用t1=tic;toc(t1)来获取当前到t1时间。
profile:分析程序执行时间。PROFILE ON启动分析器并清除之前记录。PROFILE VIEWER图形化显示记录结果。
数据类型
MATLAB内部使用15种数据类型,这些类型最终组成矩阵或向量,矩阵或向量最低维数为0×0。
在MATLAB中,所有变量都是数组,如a=3,代表a为1×1数组。MATLAB内部大多数函数均是操作数组并返回数组,如[3 4]==[3 4]并不是返回1,而是[1 1]。
变量赋值与字符显示
1 a=3 % 赋值3到变量a并显示结果到命令窗口
2 b=4; % 赋值4到变量b,输入分号后结果不显示
3 disp(b) % 显示变量b的值
MATLAB自带了一些基本命令。
who显示当前变量,含更多信息的形式为whos。 如b=whos('a')
clear清除工作空间变量,后可接一些控制参数。如clear global
length显示数值各维度大小的最大值,含更多信息的形式为size。如b=length(a)
vertcat/horzcat/cat垂直/水平/根据需要拼接矩阵。如前两者[a;b]/[a,b]等价,cat(2,a,b)与[a,b]等价,cat(1,a,b)与[a;b]等价
exist变量或函数等是否存在。如exist(‘a’)
isempty变量是否为空。如isemtpy([])
disp显示变量值,更具有定制化的形式为sprintf。如disp('abc')
disp有个特殊的功能,它可以显示超链接,包括HTML链接、FTP链接,以及MATLAB命令(使用matlab:前缀)。如
1 disp('<a href="matlab:a=3, b=4">hyperlink</a>')
将在窗口显示hyperlink,点击后会执行a=3, b=4命令。
速查手册
+
常用操作符
操作符是语言中最多使用的方法的助记符,对操作符掌握的程序代表了对一种语言掌握的程度。MATLAB自身定义了丰富的操作符,且不少操作符含有多重含义。需要在MATLAB使用中反复体会。
操作符 | 名称 | 含义 |
@ | 生成λ函数/类文件夹 | |
: | 冒号 | 生成矩阵、矩阵切片等 |
, | 逗号 | 元素分隔/数组列分隔符 |
! | 感叹号 | 调用操作系统命令 |
() | 圆括号 | 数组下标/函数 |
+ | 加号 | 正数/包文件夹 |
[] | 中括号 | 数组生成、拼接 |
; | 分号 | 不显示变量/数值行分隔符/分隔多条命令 |
' ' | 单引号 | 字符串 |
* | 星号 | 在某些命令中用于模式匹配 |
. | 点号 | 小数/结构体/类方法 |
.. | 点点 | 上层文件夹 |
… | 省略号 | 续行 |
.() | 结构体动态访问 | |
% | 百分号 | 注释/输出格式控制 |
%{%} | 多行注释 | |
~ | 波浪号 | 函数调用中忽略的参数 |
{} | 大括号 | 元胞数组生成 |
空格字符 | 行中元素分隔符/函数输出分隔符 | |
/或\ | 斜杆或反斜杆 | 访问文件夹 |
MATLAB中:
单行注释符号是“%”,多行注释为%{ %}(但相信大多数人不会用它,因为还有什么比选中行,然后按ctrl+R快捷键更方便的呢);
续行符号是“…”;
字符串使用单引号',而不是双引号”;
在命令后使用分号;可关闭显示变量;
数字采用()访问,下标从1开始。
MATLAB帮助下,Programming Fundamentals/Basic Program Components/Symbol Reference可以看到关于MATLAB这些符号的帮助。
常用运算符
运算符 | 含义 |
[]/()/{} | 数组生成、访问 |
; | 不显示变量 |
: | 生成矩阵、矩阵切片 |
+ | 加 |
- | 减 |
* | 乘(矩阵运算) |
.* | 点乘(逐元素运算) |
/ | 除(矩阵运算) |
./ | 点除(逐元素运算) |
\ | 左除(矩阵运算) |
.\ | 左点除(逐元素运算) |
^ | 指数(矩阵运算) |
.^ | 点指数(逐元素运算) |
' | 转置/字符串 |
. | 结构体访问 |
, | 分隔 |
< | 小于 |
> | 小于 |
<= | 小于等于 |
>= | 大于等于 |
== | 等于 |
~= | 不等于 |
& | 与(逐元素运算) |
| | 或(逐元素运算) |
~ | 非(逐元素运算) |
&& | 标量与 |
|| | 标量或 |
注:由于判断矩阵相等时返回矩阵,因此判断算符常联合any(所有都为0则返回0),all(所有都为1则返回1)使用。
操作符和运算符优先级
优先级(从大到小) | 符号 | 备注 |
1 | () | |
2 | . ' .^ ' ^ | |
3 | + - ~ | +-分别代表正负号,为单目运算符 |
4 | .* ./ .\ * / \ | |
5 | + - | |
6 | : | |
7 | < <= > >= == ~= | |
8 | & | |
9 | | | |
10 | && | |
11 | || |
其中,冒号操作符优先级比加减乘除都要小,在使用时需尤其注意。
微信扫一扫
关注“理念世界的影子”
版权声明:
本文是"洞穴之外"作者原创文章,欢迎转载,须署名并注明来自“理念世界的影子”公众号。