声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 14287|回复: 43

[综合讨论] [转帖]MATLAB 小技巧

[复制链接]
发表于 2005-9-5 23:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
这里是几个Matlab的小提示,基本上是我使用Matlab时碰到并解决了的问题,希望能使别人不要再碰钉子走弯路了。如果有建议或发现其中有错误,请与我联系。

Kotaimen.Cao, kotaimen_c@citiz.net

循环变量

由于历史的原因,程序员们总是使用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

循环

我经常看到一些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(:) )

就够了。

符号运算


许多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

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

这样的结果。

[ 本帖最后由 eight 于 2007-4-6 12:47 编辑 ]
回复
分享到:

使用道具 举报

 楼主| 发表于 2005-9-5 23:21 | 显示全部楼层
第二,注意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))

隐藏的图形对象属性

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);

[ 本帖最后由 eight 于 2007-4-6 12:50 编辑 ]

评分

1

查看全部评分

发表于 2005-11-10 17:26 | 显示全部楼层

谢谢了

看了你的文章很受启发!我是第一次来!请多关照!
发表于 2005-11-26 13:17 | 显示全部楼层
知识就是力量啊,少走很多弯路
发表于 2005-12-11 20:56 | 显示全部楼层
<P>good</P>
发表于 2006-7-8 22:08 | 显示全部楼层
楼主的确是老手了啊。
发表于 2006-7-9 10:14 | 显示全部楼层
谢谢
发表于 2006-7-12 09:50 | 显示全部楼层
谢谢
发表于 2006-7-13 11:25 | 显示全部楼层

谢谢!

很有收获!
发表于 2006-8-17 10:04 | 显示全部楼层
发表于 2006-8-17 16:37 | 显示全部楼层
不错的东西
3q
发表于 2006-8-17 17:08 | 显示全部楼层

谢谢!

认识matlab也有几年了,不过一直都没怎么注意它,最近要开始学了,虽然发现它比C之类的编程语言要好懂一些,不过我想要真正的搞明白还不是一朝一夕的事,希望大家多多交流,共同进步!!
发表于 2006-8-21 22:41 | 显示全部楼层
谢谢LZ!
发表于 2006-8-24 11:23 | 显示全部楼层
有心之人。
发表于 2006-8-24 17:36 | 显示全部楼层
总结经验,好帖
希望大家积极分享经验
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-11-26 01:35 , Processed in 0.062926 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表