![]() |
【文章】**MATLAB 小技巧/转**
[COLOR="Blue"][SIZE="4"][FONT="楷体_GB2312"]
这里是几个Matlab的小提示,基本上是使用Matlab时碰到并解决了的问题,希望能使别人不要再碰钉子走弯路了。 1、循环变量 由于历史的原因,程序员们总是使用i,j,…为循环变量命名,但是在Matlab中这种习惯可能会导致一些很隐蔽的问题。因为i,j同时也是Matlab中的虚数单位,如果你给i赋值,就会覆盖掉原来虚数单位的定义,例如: 4+i*3 ans = 4.0000 + 3.0000i for i=1:10, end 4+i*3 ans = 34 在一段很长的程序中很难发现这个错误,因此不要用i,j作循环变量名,除非你确认在代码的作用域内不会和复数打交道;或者使用4+3i这样的复数记法;也可以换用j: for i=1:10, end i i = 10 j ans = 0 + 1.0000i 1i ans = 0 + 1.0000i 4+3i ans = 4.0000 + 3.0000i 2、循环 我经常看到一些Matlab初学者写出带有层层循环的代码,这些代码往往运行得很慢,而且非常难懂。Matlab提供了大量的命令来避免循环,我的建议是:在确定要写一个针对矩阵操作的2重循环之前,请仔细阅读帮助中的Maximizing MATLAB Performance一节。里面有很多例子,这里举一个我自己碰到的问题。 要统计数字图像的亮度最大值和最小值,由于数字图像可能是一个二维或三维的矩阵,开始我写出了如下的代码: switch ndims(img) case 2 m = max(max(img)); case 3 m = max(max(max(img))); end 后来我对这种做法很不满意,如果有一个8维的矩阵,难道我要写 max(max(max(max(max(max(max(max(x)))))))) 才行?后来我发现无论矩阵是什么维数,实际上 max( x( : ) ) 就够了。 3、符号运算 许多Matlab函数(特别是数值计算方面的)可以作为函数句柄(function handle)或内联对象(inline object)作为参数。我们以quad函数为例,这个函数使用Simpson算法求函数的数值积分。它的一种调用形式是: quad(fun, a, b) 其中,fun可以是指向被积函数的函数句柄,或者含有被积函数的内联对象;a和b分别是被积区间的上、下限。考虑以下积分: 使用函数句柄的方法: % 将下面到"% EOF"的代码保存为f.m function y = f(x) y = sin(x) ./ x; % EOF okok.org quad(@f, 1, 2) ans = 0.6593 使用内联对象的方法: quad( inline( 'sin(x)./x' )), 1, 2 ) ans = 0.6593 由于使用内联对象不需要另外建立m文件,所以比较方便,建议使用这种方法。 更加常见的应用是被积函数有不确定的参数,例如: 其中参数a,b,K运行时确定,这时,使用函数句柄将显得很麻烦,可以用以下的方法: a = rand; b = rand + 1; K = rand; y = subs('sin(K*x)/x', 'K', sym(K, 'd') ) quad( inline(vectorize(char(y))), a, b) y = sin(.79193703742703536185842949635116*x)/x ans = 0.8188 当然,由于a,b,K是随机数,结果是不确定的。 这里有有两点需要说明: 第一,请注意sym(K, 'd'),如果直接使用subs('sin(K*x)/x, 'K', K)或subs('sin(K*x)/x, 'K', sym(K))的话,高版本的符号工具箱会将K尽可能化为分数,有时这是十分恐怖的,也许会得到: sin(6649179754310225/9007199254740992*x)/x 这样的结果。 第二,注意vectorize函数。sym对象重载的char函数会把数组的乘除(.*, ./, .^)化成矩阵的乘除(*, /, ^),vectorize会将字符串里的*,/,^全化成.*, ./, .^,如果不这样做,quad函数将会出错,这个问题曾经困扰了我很长的时间: quad( inline(char(y)), a, b) ??? Index exceeds matrix dimensions. Error in ==> D:\MATLAB6p5\toolbox\matlab\funfun\quad.m On line 67 ==> if ~isfinite(y(7)) 3、隐藏的图形对象属性 Matlab的所谓句柄图形(handle graphics)对象的配置是通过许多属性的设置来完成的。有一些帮助文件中没有提到的确实存在的属性。 figure的Toolbar属性 有三个值:'none', 'auto', 'figure' 利用这个属性可以把figure变成没有菜单条却有工具栏的样式: figure('Menubar', 'none', 'Toolbar', 'figure') root object的Default属性 在我的Malab环境里,Root object有如下的默认值: get(0, 'Default') ans = defaultFigurePosition: [232 258 560 420] defaultTextColor: [0 0 0] defaultAxesXColor: [0 0 0] defaultAxesYColor: [0 0 0] defaultAxesZColor: [0 0 0] defaultPatchFaceColor: [0 0 0] defaultPatchEdgeColor: [0 0 0] defaultLineColor: [0 0 0] defaultFigureInvertHardcopy: 'on' defaultFigureColor: [0.8000 0.8000 0.8000] defaultAxesColor: [1 1 1] defaultAxesColorOrder: [7x3 double] defaultFigureColormap: [64x3 double] defaultSurfaceEdgeColor: [0 0 0] defaultFigurePaperType: 'A4' defaultFigurePaperUnits: 'centimeters' 实际上,还有一些默认值不会被显示出来: get(0, 'defaultUicontrolBackgroundColor') get(0, 'defaultUicontrolForegroundColor') get(0, 'defaultUicontrolFontName') get(0, 'defaultUicontrolFontSize') get(0, 'defaultUicontrolFontWeight') get(0, 'defaultUicontrolFontAngle') ans = 0.7725 0.7961 0.8118 ans = 0 0 0 ans = MS Sans Serif ans = 8 ans = normal ans = normal 这些默认值有助于在创建用户界面时遵循操作系统颜色,例如: figure('Color', get(0,'defaultUicontrolBackgroundColor')) system_dependent('getdata') system_dependent('getwinsys') 版本 使用version函数可以获得Matlab或工具箱的版本: v1 = ver('matlab') v1 = Name: 'MATLAB' Version: '6.5' Release: '(R13)' Date: '20-Jun-2002' v2 = ver('control') v2 = Name: 'Control System Toolbox' Version: '5.2' Release: '(R13)' Date: '28-Jun-2002' 如果工具箱不存在或没有安装返回空结构 v3 = ver('nonsense') v3 = 0x0 struct array with fields: Name Version Release Date 可以利用这个函数让自己的程序在不当的Matlab版本上运行时给出比较体面的警告。另外,有一个帮助中没有提及的内部函数system_dependent可以获得操作系统的版本: system_dependent('getos') ans = Microsoft Windows XP system_dependent('getwinsys') ans = Version 5.1 (Build 2600) uitools工具集 除了帮助中提及的一些GUI工具函数外,matlabroot\toolbox\matlab\uitools里还有不少帮助里没有提及的函数,建议仔细研究一下(help uitools),例如,makemenu函数可以从字符串中生成菜单: labels = str2mat( ... '&File', ... '>&New^n', ... '>&Open', ... '>>Open &document^d', ... '>>Open &graph^g', ... '>-------', ... '>&Save^s', ... '&Edit', ... '&View', ... '>&Axis^a', ... '>&Selection region^r' ... ); calls = str2mat( ... '', ... 'disp(''New'')', ... '', ... 'disp(''Open doc'')', ... 'disp(''Open graph'')', ... '', ... 'disp(''Save'')', ... '', ... '', ... 'disp(''View axis'')', ... 'disp(''View selection region'')' ... ); handles = makemenu( figure('Menubar', 'none'), labels, calls); [/FONT][/SIZE][/COLOR] |
谢谢楼主经验的分享啊,避免大家少走弯路
|
不错!顶!
|
:) :cool:
|
:) 谢谢
|
楼主好利害啊!呵呵,我和matlab 才打了一个多星期交道 , 以后还请多多指教,谢谢!!!:)
|
谢谢啦 :)
|
我在今天刚刚遇到这个问题,还发蒙呢,怎么算出来的是复数呢。真是谢谢啦!!!
|
顶
值得借鉴 |
回复
我刚接触这个软件,觉得挺强的,前辈的经验对我很由帮助,谢谢了
|
所有时间均为北京时间。现在的时间是 12:33。 |
Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.