Board logo

标题: 快速学习和高效使用MATLAB的几个建议 [打印本页]

作者: yumuzi    时间: 2010-8-19 18:22     标题: 快速学习和高效使用MATLAB的几个建议

快速学习和高效使用MATLAB的几个建议


MATLAB是我们常用的工具。而快速学习和熟练掌握MATLAB对于高效完成工作很有意义。本文从亲身的经验出发,介绍一下怎样学习和使用MATLAB,这些办法都是已经被若干人证明很不错的。
1.
学习MATLAB的基础语法略过了。如果你不太确定,可以在command下边用一些简单的数字试一试。如果你习惯用C,那么注意要将运算矩阵化,什么叫运算矩阵化呢?就是尽量将循环,尤其是带if的循环用矩阵代替。举个例子:比如把数组中所有大于1000的数据置为1000,而其它的数据不变,可以写作x(x>100)=100;如果采用for循环加if来做,那么效率是它的1/4。有时候似乎必须用for解决了,比如将一个1x6的数组改成23列,那么不妨可以找找库函数,此例用reshape就可以解决。如果必须要用循环,且对某数组x的若干下标依次赋值,则一定要先定义x这个数组,例如可以用x=zeros(1,1000)。否则等于声明了一个不定长度的数组,效率十分低下。这是绝大多数程序效率损失的原因,当然是有办法进行检查的。查的办法是用MATLAB提供的profiler工具。位于tools->open profiler,工具栏也有图标。在这个工具上写入你想运行的函数名或者m文件名,程序就开始运行,运行完毕后,会将其每个语句的执行时间统计出来,一下子就可以找到症结。如果是循环体内数组赋值类的操作,一般是不正常的,你应该看看是否犯了没有初始化的错误。有时候一些函数会占用掉很多时间,你可以想想有没有办法替代它们,如果没有就进到这个函数内部再去找一找,有时候会有优化的空间。最后的结果往往是绝大部分时间已经耗费在了你很清楚的地方,比如调用的底层C函数、卷积运算、矩阵运算等等。
2.
MATLAB常用的函数中,clearclcfigure等等要牢记。另外,有时候需要注意某些库函数的第二个返回值,往往就是你想要的,比如max函数的第一个值时最大的数值,而第二个就是数组的角标,直接用[value index]=max(x)就可以同时获得,如果你把第二个数丢了,再用find去找,那就累死了。
3.
学习MATLABtoolbox函数及其用法不需要看杂七杂八的书,它的帮助足够了。打开help->product help,左侧列出了很多toolbox,每个toolbox都有几个子项,Getting Started里边具有最权威的上手示例,如果需要长期使用,应该把User’s Guide看一遍,没有多少内容,一般一两天时间就够了。里边具有很多示例的代码,有用的部分一定亲手试一下。另外对于典型应用,它都有Examples,虽然对于前沿领域来讲,这些算法有点“老”,但是其精炼和高效是其他教材无可比拟的。它会给你展示在这个领域的专家最起码的实验技能和讨论的主题,甚至可以当做所学专业可能的实验课本。如果你对上述过程中的具体函数及其实现感兴趣,可以到s里边找,那里对每个函数都有详细的解释。如果你对这个函数的实现很感兴趣,那么直接在command中写
edit 函数名”,你就可以看到它的实现的源代码。甚至某些图形工具,例如fdatoolimtoolbertool等等。函数内部有可能嵌套更深层的函数,那么请你用一个你最熟悉的数据调用它,通过调试+单步跟踪的方式一步一步查下去,由于数据你是熟悉的,因此你可以很快搞定其内部工作方式。
有两种例外,其一是MATLAB新的函数启用的object类型,对其源码进行了封装,通过edit可能看不到什么东西,那么怎么找到它的源代码呢?有两个办法,其一是单步跟踪,如果还解决不了,那么可以用上文提到的profiler工具,它会把调用到的函数一一列写,很有可能是最顶层的某个函数进不去,可以在其下的函数上定一个断点,看看数据跑过来怎样,再往下一步步跟踪,基本上就不会有单步跟不到的地方了。
另一个例外是遇到了MATLABbuildin函数或者C函数,那就真的没办法了,因为这两个函数是没有源代码的。
MATLAB库函数有统一的结构,第一部分是帮助信息,help可以看到的部分,之后是变量检查,最后是实现过程。由于很多函数为了通用,实现的细节不是最优的,并且对参数做了太多的检查,如果你需要更好的性能,可以将其关键的语句提炼出来,或者用纯粹的矩阵运算表述出来,往往可以起到提速的作用。另外,你也可以把自己的注释写在最前边,这样就可以通过help查到。
4.
有几个在源代码编辑器中的快捷键很管用,推荐掌握,ctrl+R注释选定代码,ctrl+T取消注释,调试的F5F10F11之类,终止运行中的程序ctrl+C。另外,如果你在源码编辑器中阅读源代码时遇到一个函数想查看,直接在函数上点右键,选择open selection即可。MATLAB保存之后的代码也是可以撤销的,甚至可以撤销到打开MATLAB时最原始时候的状态。因此应该常保存,以便于防止文档丢失。源码中可以通过两个百分号“%%”分割源码,甚至只执行一部分,十分有利于比较长的源码。
如果在command中想调用函数或者变量,敲写前几个字母再按tab键就可以得到匹配提示。如果需要查看变量,尤其是二维的数组,可以用workspace找到它并双击,打开Variable Editor,这个编辑器可以和Excel互相复制粘贴,很是方便。另外,各种窗体的字体和颜色大多是可以改的,在Preferences中有fonts及其他项目,可以关注一下。最后值得一提的是plot画出的图像由于是矢量图,如果数据点很多的话,复制到word中很可能会显示卡壳或很慢,可以先拷贝到画图里边,然后再贴到word,这样就是位图了。
5.
如果遇到了大运算量,建议不要运算结束后直接绘图或者打印结果,而应该采用运算和结果显示独立的程序架构。运算是一个程序,计算后的结果通过save语句存储成mat文件,再用另一个程序通过load读取此文件,这样的好处是可以防止结果丢失和篡改。另外,为了显示直观和调试的方便,可以实时的将计算的进度显示在command中,比如:


type={
'AACH'
'BSCH'
'TCH/4.8_1' };

i=3;a=1;

fprintf('Calculating Logical Channel %s using %d antennas\n',cell2mat(type(i)),a);

则可以显示出

Calculating Logical Channel TCH/4.8_1 using 1 antennas

如果制作了日志文件,那就更好了,首先打开一个文件,写入时间戳clock,它是个数组,代表年月日时分秒之类。


logfid=fopen(
'log7-26.txt','a+');


fprintf(logfid,
'time ');


fprintf(logfid,
'%d.',clock);


fprintf(logfid,
'\n');

之后依然用fprintf来打印,只不过需要加入logfid句柄。

fprintf(logfid,'Calculating Logical Channel %s using %d antennas\n',cell2mat(type(i)),a);

最后fclose(logfid);
用以关闭日志文件,幸运的是,如果由于终止运算而没有执行到这个语句,大多数日志结果也是存盘了的。

如果需要运算完毕后自动关闭计算机,可以加入这么一句

!shutdown -s

叹号代表执行一个外部命令,后边是windows默认的关机程序,可以在运行对话框实验一下,如果需要停止已经关机,那么再运行shutdown a

6.
MATLAB功能实在很多,新功能层出不穷,最好使用新的版本,MATLAB不一定总是对的,很多细节是有失偏颇的,我就遇到了几次,最严重的一次是gaussfir函数出来的结果整个就是不对的,后来发现高版本已经修正了,因此尽量使用更高的版本。有时随着版本更新,会对你的代码提出新的要求,比如用1i代替j代表复数,或者用strcmp而不是~=比较字符串等等,它都会用红线提醒,你可以根据它的提示予以更正。
7.
对于是否使用Simulink,我认为它很直观,但是缺点是效率不高(主要针对通信物理层仿真),尤其是蒙特卡洛仿真这种需要大数据量的循环仿真。当时曾经尝试过,学长用Simulink去做,跑5万点就慢死了,我自己用代码来写,跑到50万点比他的快很多,后来又通过提取函数内部实现和矩阵优化等方法又有了很大的提升。有时发现循环和判断太多了,只能用C来做。这是MATLAB的很多库函数的选择,因此如果你需要更高的效率,也可以这样来做。MATLAB-C联合编程虽然有利于提高运算效率(甚至可以利用好多核),但是很难调试C代码,在编写时一定要注意缓冲区溢出之类的问题,因为它会使整个MATLAB崩溃而重启。因此最好先在VC调试好,再跟接口连接起来。当然,调试的时候C代码部分没法单步,但是printf还是可以用的。另外,MATLAB的界面制作工具很好用,而且做出来的东西很赞,建议花点时间学一学,能够操纵按钮,读取复选框和文本的数值基本上就够用了,它会使你的结果汇报变得很直观。

很抱歉,由于思路未加整理,十分凌乱,谨此献给常常使用MATLAB的同志们,希望能够起到一点作用,使大家能善于利用MATLAB开展自己的研究工作。





欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0