MATLAB 技术论坛
电子期刊
编辑:xiezhh
制作:MATLAB 技术论坛
版权:MatlabSky©版权所有
网址:http://www.matlabsky.com
第 7 期 2011.03 No.7
中国权威 MATLAB 论坛核心期刊
MATLAB 技术论坛简介
Matlab 技术论坛 | Simulink 仿真论坛 | ——打造优秀、专业和权威的 Matlab 技术交流平台!
http://www.matlabsky.com /cn/net/org
论坛拥有 40 多个专业版块,内容涉及资料下载、视频教学、数学建模、科学计算、程序设计、GUI
开发、simulink 仿真、统计概率、拟合优化、扩展编程、算法研究、控制系统、信号通信、图像处理、经
济金融、生物化学、航空航天、人工智能、汽车设计、机械自动化、毕业设计等几十个方面!
论坛特色:
1.拥有强大的技术人员、热情严谨的管理团队
2.丰富多彩的Matlab电子资源免费共享
3.免费提供技术交流和在线解答
4.首个推出MATLAB函数百科中文帮助系统
5.国内唯一提供Matlab汉化包的团队
联系方式:
客服 QQ:1341692017
服务邮箱:matlabsky@gmail.com
支付宝账号:yuthreestone@163.com 郁磊
互动QQ群:http://www.matlabsky.com/thread-3-1-1.html
开通业务:
技术论坛:http://www.matlabsky.com
函数百科:http://wiki.matlabsky.com
官方博客:http://blog.matlabsky.com
读书频道:http://book.matlabsky.com
视频教程:http://video.matlabsky.com
有偿编程:http://paid.matlabsky.com
目 录
1 高质量MATLAB&C&C++编程风格指南.........................................................................................1
2 WRITING FAST MATLAB CODE[如何优化你的程序,让其跑的更快] ............................................3
3 在高版本MATLAB下重新认识循环................................................................................................4
4 在MATLAB中发送电子邮件(支持附件) .....................................................................................7
5 GUI新手之教你读懂GUI的M文件..................................................................................................9
5.1 什么是子程序........................................................................................................................................ 9
5.2 M文件的数据管理模式 ...................................................................................................................... 10
5.3 M-FILE里的各个函数代表什么意思.................................................................................................. 10
5.3.1 Opening Function................................................................................................................................................... 11
5.3.2 Output Function ..................................................................................................................................................... 11
5.3.3 Callbacks(回调函数)........................................................................................................................................12
6 MATLAB在GUI中实现多标签页的方法 .......................................................................................12
6.1 TABPANEL CONSTRUCTOR V2.6.1 (2009) ............................................................................................. 12
6.2 MULTIPLE TAB GUI .............................................................................................................................. 12
6.3 TAB PANEL COPY .................................................................................................................................. 13
6.4 GUI简单标签页程序........................................................................................................................... 13
6.4.1 Simple Tab with GUIDE.......................................................................................................................................14
6.4.2 Simple tab panel....................................................................................................................................................14
6.4.3 a new way to tab for GUIDE..................................................................................................................................14
6.4.4 Tab Axes Gui..........................................................................................................................................................15
6.4.5 Simple Tab Example ..............................................................................................................................................15
6.5 自己编写相关M函数,然后调用 ...................................................................................................... 16
6.5.1 Tab panel example.................................................................................................................................................16
6.5.2 tabpanel,This tool allows the creation of tab panels within MATLAB...............................................................16
6.6 高亮显示多页标签(HIGHLIGHT TAB OBJECTS) ................................................................................... 16
7 EXCEL、LISTBOX、EDIT和INPUTDLG之间的交互操作 .........................................................17
8 在GUI中查询并选择MATLAB工作空间(WORKSPACE)中的变量...............................................19
8.1 在GUI中查询并选择MATLAB工作空间(WORKSPACE)中的变量....................................................... 19
8.2 将保存在WORKSPACE里的数据导入到GUI中绘图 ........................................................................... 21
8.3 将保存在WORKSPACE里的数据导入到GUI中绘图 ........................................................................... 22
9 绘制两圆公切线的MATLAB代码 .................................................................................................23
MATLAB 技术论坛电子期刊 第 7 期 ·1·
在此向本期内容涉及代码的原作者们表示最衷心的感谢!同时祝福版友们
身体健康!万事如意!
MATLAB 编程技巧版块
1 高质量 Matlab&C&C++编程风格指南
贴子地址:http://www.matlabsky.com/thread-9344-1-1.html
作者:faruto
和大家分享一些经典的关于编程风格的电子书,对于养成一个好的编程习惯和风格有一定的启示作
用。
==============外一篇: faruto 浅谈编程风格 ==========================
我要说的关于编程的第一个主要思想:先整体,后具体;分块把握大的算法再实现。其实这也比较
符合一些生活常识,要解决一个大问题,首先我们需要从整体上把握这个问题,然后再从细节上处理相
关问题。编程也是一样的,当有一个大的算法需要实现,你需要做的事整体上把握一下算法脉络,然后
再分块实现,这样是好的习惯,因为每一个人对于代码的掌控能力是有限的,也就是说当一个函数的代
码长度多长的话,最终你会失去掌控能力的,到后面你会连一些变量名字都会弄混的。我个人的对于单
个函数的代码的掌控能力为 1000 行左右,所以当一个函数过于太大,超过我个人的掌控能力的时候,我
就会把这个函数再进行分块,进而每个字块函数的代码行数让其在我的掌控能力之内,这样做的好处是
一则对于单个子函数调试找 bug 方便,二则对于整体的大函数项目,最后整体做一个接口把各个子函数
2011 年 03 月 Matlab 技术论坛各版块问题集锦 ·2·
链接到一起就行了,大函数出错的话,很容易找到是哪个子函数出的问题,若都放到一起来实现,调试
起来会让人疯掉的。所以说,编程的时候需要:先整体,后具体;分块把握大的算法再实现。这个说起
来做起来难,需要个中体会。
第二个我想谈的是:编程风格问题。无论学习什么编程语言,最开始的基础是很重要的,一个好的
编程习惯和代码风格会使你往后的编程道路很顺利,否则的话往后进展会出现瓶颈。从代码的质量也就
能看出你本身的编程能力了,如果你平时的编程习惯好,在最终代码成型时出现的 bug 就会少很多,所
以说平时的编程习惯是很很重要的,少量的代码无所谓的(200 行以内),但当代码量多起来,如果你平时
编程习惯不好,到时你连前后的变量名称定义自己都会搞混的。说了这么多,到底怎么是一个好的编程
风格呢?这个没有十分统一的标准,以前看过一本书《C++编程高手》里面详细讲了一些同认的好的编程
习惯风格,包括变量的合理命名,恰当使用空格和换行符使得代码看起来更舒服等等。
比如下面这段普通简单的 A+B Problem 的代码(MATLAB):
function solve_AplusB_problem
disp('This is a programme for solving A+B problem');
A=input('Please input the fist number A:');
B=input('Please input the second number B:');
C=A+B;
str=['The result of A+B is:',num2str(C)];
disp(str);
这段代码再简单不过,当年的我可能也差不多类似于上面那样写代码,但现在的我就会这样来写:
function solve_AplusB_problem
% by faruto
% a test programme for solving A+B problem
disp('This is a programme for solving A+B problem');
A = input('Please input the fist number A:');
B = input('Please input the second number B:');
C = A + B;
str = ['The result of A+B is:', num2str( C )];
disp( str );
两段代码几乎没有差别,实现内容也一样,后者的代码段就像“神经病”一样多了很多空格和空白
行,但我敢说后者的代码风格习惯更好,代码和别人交流起来也更容易,这就是一个非常非常简单的例
子,如果代码很长很复杂,你会发现好的代码风格超级重要的!个中感觉还望看官您自己体会。O(∩_
∩)O~
回想自己学习 MATLAB 的过程(或者说学习其他编程语言的过程),感受最深的一点就是一定要自
己多多动手,遇到不会的东西先要查看帮助文件或者通过网络搜索来找到相应的答案,也就是说需要有
自我帮助能力,这样才能不断提高自己的能力。当然有些非常棘手的问题是需要向高人请教的。
============== rocwoods 的回复 ==========================
嗯,好的代码风格非常重要,各个公司对需要编码的人员都非常强调好的编程风格习惯的培养。我
再补充一点,变量命名很重要,对于重要的变量应该“望名生义”就是看到变量名,大致猜到什么意
思。推荐使用大小写混合形式命名,譬如:SegmentLength,ColorOrder 等命名方式,让人一目了然。
经常见到初学者用汉语拼音命名变量,这是非常不好的一个习惯,别的不说,让你的代码非常“山
寨”,而且代码复杂后会让人莫名其妙的,应该摒弃。
MATLAB 技术论坛电子期刊 第 7 期 ·3·
2 Writing Fast Matlab Code[如何优化你的程序,让其跑的更快]
贴子地址:http://www.matlabsky.com/thread-9457-1-1.html
作者:faruto
很不错的一个 Ebook 交易如何优化 matlab 代码提升其速度。当然里面也有一些速度提升理念是落后
的,去糟取精即可~O(∩_∩)O~
matlab 以其强大的功能在科学领域有不可替代的位置,用了 matlab 多年,唯一感觉的遗憾就是在速度上
matlab 有时是拼不过 C(C++)的,前一阵子在我们院的 FTP 上看到下面这个电子书(Writing Fast Matlab Code),
挺有感想,对如何提升 matlab 的速度上有了一定认识,如果你对 matlab 的速度方面也有要求,不妨看看,它会
对你如何写出更高效的 matlab 代码有一点的启示!
看过这个电子书我个人的核心理解就是 preallocation,预先定义,虽说 matlab 中的变量都不用预先定义,
但当你的程序中有维数很大的矩阵时,预先定义会使你的程序跑起来的速度比原来快两倍多!!
因为在 Matlab 中如果你不对某一矩阵或向量预先定义,则在跑循环时 Matlab 会重复对这个矩阵或向量
扩容,直到满足大小为止,所以你如果预先定义了,这样会使得程序在跑循环时不再对矩阵或向量重复进行扩
容,从而省去很多时间...
个中详细原由你可以自己细看,电子书中做了测试,时间可省去一半之多.我自己也也过相关测试,的确
能提升 Matlab 代码的速度!
[当然小问题没有预先定义的必要]
Ebook下载:请自行去原帖下载。
2011 年 03 月 Matlab 技术论坛各版块问题集锦 ·4·
3 在高版本 MATLAB 下重新认识循环
贴子地址:http://www.matlabsky.com/thread-9249-1-1.html
作者:rocwoods
高版本 MATLAB 对循环结构的优化
从 MATLAB6.5 版开始,MATLAB 引入了 JIT(just in time)技术和加速器(accelerator),并在后续
版本中不断优化。到了 R2009a,很多情况下,循环体本身已经不是程序性能提高的瓶颈了,瓶颈更多的
来源于循环体内部的代码实现方式,以及使用循环的方式。循环就是多次重复做一件事,如果这件事本
身代码写得不优化,放在循环体内多次实现后必造成运行时间过长。
老版本的 MATLAB 对循环机制的支持不好,所以我们提倡避免循环,而高版本的 MATLAB 对循环
机制的支持大大提高了,我们就不能像过去那样谈“循环”色变,非得千方百计避免循环。当使用了循
环,造成程序运行时间过长时,我们不要武断地将代码运行效率低归结到使用了循环。有的时候我们千
方百计的把一段代码矢量化了,凭自己编程经验(很多是从老版本遗留下来的经验)和常识(从老的教
科书得到的)觉得程序很标准,很优化,殊不知实际测量时会发现性能不比采用很自然的想法实现的程
序效率高多少,甚至还会降低。我们看下面这个例子:
【例 1】 运行下面的测试 JIT/ accelerator 的代码,体会高版本的 MATLAB 对循环的加速。
function JITAcceleratorTest
u = rand(1e6,1);%随机生成一个 1*1000000 的向量
v = zeros(1e6,1);
tic
u1 = u + 1;
time = toc;
disp(['用向量化方法的时间是:',num2str(time),'秒!']);
tic
for ii = 1:1000000
v(ii) = u(ii)+1;
end
time = toc;
disp(['循环的时间是:',num2str(time),'秒!']);
feature jit off;
tic
for ii = 1:1000000
v(ii) = u(ii)+1;
end
time = toc;
disp(['只关闭 jit 的时间是:',num2str(time),'秒!']);
feature accel off;
tic
for ii = 1:1000000
v(ii) = u(ii)+1;
end
time = toc;
disp(['关闭 accel 和 JIT 的时间是:',num2str(time),'秒!']);
MATLAB 技术论坛电子期刊 第 7 期 ·5·
feature accel on;%测试完毕重新打开 accelerator 和 JIT
feature jit on;
end
我的电脑上结果如下:
用向量化方法的时间是:0.0095308 秒!
循环的时间是:0.010176 秒!
只关闭 JIT 的时间是:0.084027 秒!
关闭 accel 和 JIT 的时间是:1.2673 秒!
自从引入 JIT 和 accelerator 后,MATLAB 对这两项功能默认都是打开的,这也是为什么高版本的
MATLAB 对循环的支持好。关闭 JIT 和 accelerator 需要用到 MATLAB 一个未公开(undocumented)的函
数:feature。feature accel on/off 即为打开/关闭 accelerator,类似的打开/关闭 JIT 是 feature jit on/off。
上面代码算一个长向量与一个标量的和,我们会发现,JIT 和 accelerator 都打开的状态下,循环和矢
量化运算所需要的时间从统计意义上来讲,已经没有显著差别了。关闭 JIT 后,运行时间变为原来的 8 倍
左右。而再关闭 accelerator,运行时间立刻变为原来的 100 多倍。
我们再来看一个例子:
【例 2】 由一个 m*n 的矩阵构造一个 m*(m+n-1)的矩阵,构造方式如下:以 4*4 矩阵 A 为例,目的
构造 B:
A =
1 2 3 4
3 4 5 6
2 3 4 5
1 3 4 6
B =
1 2 3 4 0 0 0
0 3 4 5 6 0 0
0 0 2 3 4 5 0
0 0 0 1 3 4 6
这个例子用循环解决非常容易实现,我们这里想要讨论的就是用向量化的方法解决该问题和用循环
解决该问题之间的时间对比(还不考虑写出矢量化的代码比用循环实现多花的时间)。
向量化思路:我们观察 B,发现如果按行数的话,B 的元素排列顺序是原来 A 中的每一行和下一行
之间以 4 个 0 相隔。这样我们可以计算出 A 中的元素在 B 中相应的索引值(当然是按行)I。这样我们可
以生成一个和 A 大小一样的全 0 矩阵 B,然后 B(I) = a(:);最后注意到 MATLAB 是按列的顺序遍历元素
的,所以最后再转置一下 B。写成代码就是:
function B=rowmove(A)
[m,n]=size(A);
I=repmat(1:n,m,1)+repmat((0:m-1)'*(m+n),1,n);
B=zeros(m+n-1,m);
B(I(:))=A(:);
B=B';
循环的代码如下:
function C = LoopRowMove(A)
[m,n] = size(A);
C = zeros(m,m+n-1);