计算机应用
COMPUTER APPLICATIONS
1999年 第19卷 第9期 Vol.19 No.9 1999



Matlab的几则程序设计经验
陈以新
　　摘　要　本文向读者简介了Matlab强大的数值计算功能与数据可视化功能，阐述了使用Matlab进行程序设计的几则经验，并介绍了Matlab4.0与Matlab5.0的一些差别。
　　关键词　Matlab，数值计算，符号计算，可视化
　　　　Matlab是一种数值计算型科技应用软件。其全称是Matrix Laboratory, 亦即矩阵实验室。与Basic、Fortran、Pascal、C等编程语言相比，Matlab具有编程简单直观，用户界面友善，开放性强等优点，因此其自面世以来，在国际上很快得到了推广利用，被IEEE称为国际公认最优秀的科技应用软件。
1　强大的数值计算与符号计算功能
1.1　数值计算功能
　　Matlab以矩阵为运算单元，除非特殊需要，矩阵不必事先定义维数大小。Matlab还提供了丰富的矩阵运算函数，如求逆矩阵的inv函数，求方阵行列式的det函数，求矩阵特征值及特征向量的eig函数等等。正因为如此，在矩阵运算上，Matlab体现出比Basic、 Fortran、Pascal、C等语言要高得多的编程效率，而且程序可读性强，调试简单，容易维护。许多含有矩阵运算的复杂的源程序如果用Matlab编写，只要寥寥几行就可结束，就象在草稿纸上进行演算一样简捷直观，故Matlab又被称为“演算纸式的程序设计语言”。
1.2　符号计算功能
　　除了数值计算，Matlab4.0以上版本还提供了Basic、 Fortran、Pascal、C等语言所没有的符号计算功能，当然你必须安装了符号计算工具箱。在数值计算中，所有运作的变量都是被赋值的数值变量，而在符号计算中，所运作的都是符号变量。在高等数学中的级数、微分、积分，甚至微分方程组通过Matlab的符号计算工具箱都可以方便地求解。
2　强大的科学数据可视化能力
　　作为一个优秀的科技应用软件，Matlab不仅在数值计算方面无与伦比，而且在数据可视化方面也有上佳表现。Matlab 有两个层次的绘图命令：一组是直接对句柄进行操作的底层绘图指令；另一组是在底层指令基础上建立起来的高层绘图指令。
2.1　高层绘图指令实现默认的图形表现方式
　　用高层绘图指令可以实现Matlab中默认的图形表现方式，这些指令简单明了，极易为用户掌握。例如调用plot函数可绘制直角坐标二维曲线，调用plot3函数可绘制直角坐标三维曲线。另外还有其他许多简便的高层绘图指令，可用于绘制一些特殊的平面图形（如统计频数直方图），实现对图的注释等等。
2.2　底层绘图指令更改图形属性
　　如果用户对默认的图形表现方式不甚满意，可用底层绘图指令如set函数更改图形句柄对象的属性。例如可以更改图形窗口的背景色，轴的位置，纵横轴的比例，绘图的线型、线宽等。
2.3　符号函数的可视化
　　对于符号函数，Matlab也可简便地实现可视化。定义符号函数后，调用ezplot函数即可绘制符号函数的曲线，而且图名及横坐标名都将自动生成。
3　Matlab程序设计经验
　　. 在使用Matlab编程时，若要利用现成的Fortran或 C的软件包，常会遇到接口问题。通常可采用以下几种方法：
　　在Matlab的M文件中调用由Fortran或 C子程序编译生成的MEX可执行文件，此法将降低Matlab的执行速度。
　　用剪贴板将Fortran或 C产生的数据文件考贝到Matlab的M文件中。此法虽然简单，但若遇到大型质量矩阵或刚度矩阵，将使源程序冗长。
　　用fopen 、fread 、fscanf 等Matlab的底层I/O指令将Fortran或 C产生的数据文件读入Matlab的M文件中。
　　. 用fscanf语句输入矩阵变量或简单变量的数值时，一句fscanf语句只能读入一个变量（包括矩阵变量或简单变量）的数值，而在C语言中，一句fscanf语句可以读入多个简单变量的数值。还要注意的是当用A＝fscanf(FP,′%d′,1)读入简单变量A的数值时，（）内的′1′必不可少，否则该语句会将指针FP在所对应的文本文件中当前所指的数据及其后所有的数据全部读入并赋给变量A，使A成为一列向量。这是因为在Matlab中默认的基本数元为矩阵。
　　. 用循环语句对一列向量赋值时，例如要产生一个3×1的“0”矩阵A，应用：
　　for J=1:1:3 /A(J,1)=0.0; /end。若用：for J=1:1:3 / A(J)=0.0;/end (“/”表示回车键) ,则A={0 0 0},产生的是一个1×3的矩阵，即行向量。在编程中若忽视了这个问题常会造成数组的维数不匹配。
　　. Matlab中严格区分大小写，用户在Command Window中若遇到提示“???Undefined function or variable ′A′.”，可检查一下是否错按了大小写字母切换键。
　　. Matlab当中的指令用的都是英文标点，用户如果在中文之星或RichWin状态下输入指令，要注意不要错用了中文标点，否则将给出出错信息。
　　. Matlab 具有丰富的函数库，用户自己编写的函数应避免与Matlab函数库中的函数同名，否则Matlab会优先执行函数库中的同名函数。
　　. Matlab启动后的缺省目录是c:\matlab\bin，用户若不建立自己的工作目录，那么在Matlab环境下所产生的数据文件以及用户自己编写的可执行文件就很可能登录在这缺省目录上，造成用户文件与Matlab自身函数文件混杂在一起。因此用户应在Dos环境或Windows环境下建立自己的工作目录，并将其设置为当前工作目录。可用cd命令进入用户自己的工作目录。
　　. 假定用户用书写器(记事本或写字板等)编写好了一个m文件(Matlab中的可执行文件)，可用Command Window 中File 下拉菜单中的Run M-file选项来执行该文件。或者先设置好该文件的搜索路径，然后在Command Window 中键入该文件名，回车即可。设置搜索路径的方法除了3.7中提到的cd命令外，还可用path指令扩展搜索路径。或者在Matlabrc.m中添加该文件所在的路径，重新启动Matlab使该搜索路径生效。需要注意的是用path指令扩展的搜索路径仅在当前Matlab工作环境中有效，而在Matlabrc.m中添加的路径只要不被删除，将永远有效。
　　. 虽然Matlab中提供了正无穷大变量Inf，但在数值积分中调用quad8积分指令时若用+Inf或-Inf作为积分的上限或下限，将使结果成为不定值。请看下面一个例子：
　　求标准正态分布的概率函数值

　　先用编辑器建立被积函数f.m文件。
　　function prob=f(x)
%函数文件以function作为文件头
prob=1/sqrt(2*pi)*exp(-(x.^2)/2);
%被积函数表达式 
　　将写好的f.m文件存放在自己的工作目录中。当调用积分指令quad8时，结果出现不定值NaN。
u=-1:0.5:1
%形成由-1到1，间隔为0.5的行向量
for I=1:1:5
P(I)=quad8(′f′,-Inf,u(I));
% f为被积函数文件名,-Inf、u(I)分别为积分的上、下限
end 
　　结果如下：
　　u =-1.0000　　-0.5000　　0　　0.5000　1.0000
P =NaN　　NaN　　NaN　　NaN　　NaN 
　　其实只要采用一个小小的技巧就能求出标准正态分布的概率函数值。
　　注意到

改用如下程序即可得到正确的答案。
　　u=-1:0.5:1;
for I=1:1:5
P(I)=0.5-quad8(′f′,u(I),0);
end 
　　结果如下：
　　P =0.1587　0.3085　0.5000　0.6915　0.8413 
　　读者可与标准正态分布的概率函数值表对照一下。
　　. 在符号微积分中用+Inf或-Inf作为积分的上限或下限能得到正确的解答，但是计算的速度比用积分指令quad8慢得多。仍采用同一例子，程序如下：
　　prob=′1/sqrt(2*pi)*exp(-(x^2)/2)′; 
%定义概率密度函数的符号函数
u=-1:0.5:1;
for I=1:1:5　%int对符号函数求积分,
%numeric将符号变量转化为数值变量
P(I)=numeric(int(prob,-Inf,u(I))); 
end 
P =0.1587　0.3085　0.5000　0.6915　0.8413 
　　. 在符号表达式的变量替换中，不少Matlab的参考书都提到了subs指令，并介绍了它的具体使用格式：subs(f,NEW,OLD)，即用新字符串NEW代替符号表达式f中的旧字符串OLD。笔者经过多次试验，发现这种格式有误。事实上，当新字符串是数字字符时，或者新字符串是字母字符且在表达式中未出现，用subs(f,NEW,OLD)与用subs(f,OLD，NEW)的结果是一样的。请看如下例子：
　　新字符串是数字字符
　　f=′a*u^3+b*u^2+c*u+d′
%定义符号函数f　　
　　f1=subs(f,′a′,′3′) 
%用′3′替换f中的′a′
　　f2=subs(f,′3′,′a′) 
%用′3′替换f中的′a′ 
　　输出结果：
　　f =a*u^3+b*u^2+c*u+d
　　f1 =3*u^3+b*u^2+c*u+d
　　f2 =3*u^3+b*u^2+c*u+d 
　　新字符串是字母字符且在符号表达式中未出现
　　f=′a*u^3+b*u^2+c*u+d′
%定义符号函数f　　
f1=subs(f,′s′,′u′) 
%用′s′替换f中的′u′
f2=subs(f,′u′,′s′) 
%用′s′替换f中的′u′ 
　　输出结果：
　　f =a*u^3+b*u^2+c*u+d
　　f1 =a*s^3+b*s^2+c*s+d
　　f2 =a*s^3+b*s^2+c*s+d 
　　如果新字符串是字母字符且在符号表达式中有出现，则替换格式应为subs(f,OLD，NEW)
　　
　　f=′a*u^3+b*u^2+c*u+d′
f1=subs(f,′a′,′u′)
%用′u′替换f中的′a′
f2=subs(f,′u′,′a′) 
%用′a′替换f中的′u′ 
　　输出结果：
　　f =a*u^3+b*u^2+c*u+d
f1 =u^4+b*u^2+c*u+d
f2 =a^4+b*a^2+c*a+d 
　　建议初学者均采用subs(f,OLD，NEW)的格式，以免出错。
4　Matlab4.0与Matlab5.0的一些差别
　　. Matlab 4.0在Win 98环境下不能运行，Matlab5.0在Win95及Win98环境下都能运行。
　　在Win98环境下安装Matlab4.0，安装过程中一切正常，安装完毕后双击Matlab4.0图标无法启动Matlab4.0，并提示“该程序执行了非法操作，将被关闭”。而在Win95下安装Matlab4.0则可正常运行。假如你在Win95下安装了Matlab4.0，以后又将Win95升级为Win98，这时候Matlab4.0同样不能运行。解决的办法有两个：一是卸载Win98回到Win95界面，则Matlab4.0恢复正常运行。另一个是改装Matlab5.0或5.1，它们在Win98下可以正常运行。原因在于Matlab4.0是16位应用程序，而Matlab5.0是32位应用程序。Win95使用的是16位的文件分配表，而Win98使用的是32位的文件分配表。
　　. 在Matlab4.0中可以用Command Window 中File下拉菜单中的Open M-file选项打开目录来设置路径，在Matlab5.0中用Open选项打开目录后，搜索路径还是原默认路径。但是在Matlab4.2及以上版本都提供了永久性修改搜索路径的专用工具pathtool指令。而Matlab5.0以上版本在File的下拉菜单中还设了与pathtool指令同样功能的set path选项。
　　. 在Matlab4.0中图形窗口默认的背景色是黑色；在Matlab5.0中坐标轴包围的区域内默认的背景色是白色，坐标轴包围的区域外默认的背景色是灰色。在Matlab4.0中whitebg指令没有输入参量，它的作用是使当前及以后绘制的所有图形窗口的背景色为白色，再次whitebg图形窗口的背景色仍然保持白色。在Matlab5.0中whitebg指令可以没有输入参量，也可以输入一个或两个参量。当没有输入参量时它的作用是使当前及以后绘制的所有图形窗口的背景色为黑色，再次whitebg将使图形窗口的背景色恢复为上述默认的背景色；当调用格式为whitebg(′color′)时它的作用是使当前及以后绘制的所有图形窗口的背景色为设定的颜色，′color′可以为′w′─默认的背景色，′r′─红色，′g′─绿色，′y′─黄色，′b′─蓝色，′black′─黑色；当调用格式为whitebg(gcf)时它的作用是使当前绘制的图形窗口的背景色为黑色(gcf函数返回当前图形窗口的句柄值)；当调用格式为whitebg(gcf,′color′)时它的作用是使当前绘制的图形窗口的背景色为设定的颜色。
5　结语
　　Matlab随着版本的不断升级，其功能也越来越完善，除了文中提到的符号工具箱外，它还拥有控制系统、信号处理、优化、神经网络、模糊推理等专业工具箱。Matlab及其工具箱将一个优秀软件包的易用性与可靠性，通用性与专业性近乎完美地结合在一起，使其逐渐成为国际性的计算标准为世界各地的科学家和工程师所广泛地采用。在西方，Matlab的应用已经遍及现代科学界和工程界，各主要大学，政府研究部门和各大公司。相比之下，我国科技人员对其的了解和应用就少得多了。Matlab强大的功能与先进的技术等待我们去发掘和应用。本文旨在引起国内各界研究人员对Matlab的重视，以促进Matlab在教育界、科技界和工程界的推广应用。
作者简介：陈以新　硕士。主要研究方向：结构抗震。
作者单位：华侨大学土木工程系　福建.泉州(362011)
参考文献
［1］　张志涌，刘瑞桢，杨祖樱.掌握和精通MATLAB. 北京：北京航空航天大学出版社，1998
［2］　张培强.MATLAB语言. 北京：中国科学技术出版社，1995
［3］　Duane Hanselman，Bruce Littlefield，著. 精通MATLAB综合辅导与指南. 李人厚，张平安，等译校.西安：西安交通大学出版社，1998
收稿日期:1999-05-26
