MatLab讲义 2002年9月版
z=fun1(X,Y);mesh(z)
subplot(2,2,4);alpha=0.8;beta=0.5; z=fun1(X,Y);mesh(z)
function z=fun1(x,y) global alpha beta
z=alpha*(X-1).^2+beta*(Y+1).^2
4.13 命令/函数的双重性
在使用Matlab命令时,我们一般使用如下的格式:命令 参数 例如 load August17.dat help mesh
有时我们也可以使用如下的方式: load(?August17.dat‘) help(?mesh‘)
这就是Matlab中的命令/函数双重性,即 命令 参数 也可以写成函数形式 命令(’参数’) 从下面的例子里我们可以看出这种写法的好处:
例:有一批数据文件,文件名分别为:August1.dat, August2.dat,......august31.dat.希望分别对这些文件做相应的处理:
for i= 1:31
s=[?August‘ int2str(i) ?.dat‘]
load(s) %process the contents of the ith file end
注:int2str为把数值变换为字符串。
4.14 执行字符串命令
? eval 函数
eval是一个非常有用的函数,相当于一个命令解释器,能够解释一个字符串表达式,即计算以字符串表示matlab表达式。
形式为:
1.eval(?表达式?) 计算出表达式的值
2.[a1,a2,....an]=eval(?表达式?) 当表达式可产生多个结果时,分别存入a1,a2,....an等变量中。
3.eval(字符串,选择字符串) 例:
a=‘4*5-3‘ eval(a)
ans= 17
例:生成12个随机矩阵,M1-M12, 阶数从1-12
for n = 1:12
eval(['M' num2str(n) ' = rand(n)']) end
? feval函数
可以把用户的输入和函数结合起来执行。 基本语法如下:
feval(函数名称,数值或变量列表); [y1,y2,...]=feval(function,x1,...,xn)
如果函数名称存在则将用给定的参数执行函数。 例:a=magic(4)
[v,d]=feval('eig',a)
31
MatLab讲义 2002年9月版
feval函数可以用于使一个函数接收设定为要调用的函数名的字符串变量,执行灵活的功能。 例:为多种函数画出输入输出图。 function plotf(fun,x) y=feval(fun,x); plot(x,y)
4.15时间和日期
MATLAB提供的时间和日期函数有四类: 函数简解:
? 返回当前时间的函数:
now:返回当前日期与时间的数字序列。 date:返回当前日期字符串。
clock:返回当前日期与矢量时间。 ? 时间数据转换函数:
datenum:将字符串日期转换成数字序列日期。 datestr:将数字序列日期转换成字符串形式。 datevec:将数字序列日期转换成矢量形式。 ? 计时函数:
cputime:返回MATLAB使用的CPU时间(秒)。 tic、toc:计时秒表。 etime:计算时间间隔。 ? 其它常用函数: calendar:日历。
weekday:查询某日为星期几。 eomday:月的最后一天。 ? 时间日期格式:
字符串日期:02-0ct-1996 数字序列日期:729300 矢量日期(系统内部格式):1996 10 2 0 0 0
格式转换函数:datenum(日期格式变数字),datestr(日期格式变字符串),datevec(日期格式变矢量)。
4.12 向量化
MATLAB的实际使用中,有些循环可直接转换成向量操作,这样可大大提高程序执行速度,这种技术称为循环的向量化,在编写程序时,应尽量避免采用循环,将它转变为向量进行处理。以便最大限度地提高用Matlab编写的程序的效率。
如何将循环变量变换成向量操作是一个比较复杂的问题。简单问题很容易转换为向量操作,但复杂的问题不易直观转换,视实际问题而定。
例:比较如下两个算法: (1)(t1.m)
tstart=clock; x=0.01;
for k=1:1000
y(k) = log10(x); x = x + 0.01; end
tend=clock;
interval = tend – tstart
(t2.m)
tstart = clock;
32
MatLab讲义 2002年9月版
x=0.01:0.01:10; y=log10(x); tend = clock;
interval = tend – tstart
t2.m的执行速度远远低于t1.m的执行速度。
例:产生一个由A矩阵重复产生的矩阵B function B=repmat1(A,M,N) if nagin<2
reeor(?Requires at least 2 inputs.‘) elseif nagin == 2 N=M end
[m,n]=size(A);mind(1:m)‘; mind(mind(;ones(1:M)); nind(nind(:,ones(1,N));disp(mind),disp(nind) B=A(mind,nind);
函数输入为:A[1 23;4 56]; b=repmat1(a,3,2)
4.13 字符数组和字符串操作
1.MATLAB的字符数组
在MATLAB中,字符串都被视作字符数组。
字符串的建立:s=‘字符串‘,即用‘‘将输入的字符串括起来。注意:不是‖ ―,这点与其它高级语言不同。而要建立一个字符串矩阵,则可以这样建立:
sa=[?string1‘,‘string2‘......]
与数组不同,字符串矩阵的每一行字符元素的个数可以不同,但是每一行的所有字符串中的字符的总个数必须相同,如果不满足这个条件,即使每行中字符串的个数相同,也会出错。事实上,MATLAB将一个行内的所有字符串都合并起来,构成一个字符串,单个字符串之间不加空格,这正是每行中输入的字符串的个数可以不同的原因。
char()函数自动将最短的字符串添加空格,使各行长度相等。 例: a=['aaa' 'bbb';'cc' 'dd'] 系统报错,必须为
a=['aaa' 'bbb';'cc' 'dddd']
利用这个特点,可以用[]将任意字符串连接起来。 例:sa=[?aa ?bb ?cc‘;‘dd‘ ?ee‘ ?f‘ ?k‘]
sa=
aabbcc ddeefk
例:[sa(1,:) sa(2,:)]
sa=
aabbccddeefk
注:字符串的每个字符(包括空格)都是矩阵的一个元素。 处理字符矩阵时当作数据矩阵来处理 2.字符串的比较
函数strcmp(str1,str2):比较两个字符串是否相同,若相等则返回1值,若不相等则返回0值。 函数strncmp(str1,str2,n):比较两个字符串的前n个字符是否相同,若相等则返回1值,若不相等则返回0值。
3.字符串的归类
函数isletter(S):判断串中元素是否为字母。 函数isspace(S):判断串中元素是否为空格。
这二个函数的返回结果为与字符串长度相等的矢量,1表示结果为真,0表示结果为假。 4.字符串的查找与替换
函数findstr(?str1‘,‘str2‘):在字符串str1中查找子串str2,返回str2在str1中的起始位置。
33
MatLab讲义 2002年9月版
函数strrep(?str1‘,‘str2‘,‘str3‘):字符串替换 5.字符串运算
字符串及字符串矩阵可以进行加、减、乘、除四则运算和其它数字运算(利用ASCII码)。 例:‘e‘+‘f‘=203
6.一般通用字符串操作
通用字符串操作包括字符串与ABCII间的转换、字符与数据间的相互转换,字符串大小写间的转换、字符串中空格的删除等。 函数名 函数功能 string(A) 将一个整数数组转换成字符串矩阵 abs(S) 将字符串转换成ASCII码 double(S) 将字符串转换成相应的ASCII码(双精度) isstr(S) 确认是否为字符串 deblank(C) 删除字符串结尾处的空格 disp(n) 输入n个空格 str2mat(s1,s2,s3,...) 将字符串变为字符串矩阵 upper(S) 将字符串进行大写转换 lower(S) 将字符串进行小写转换 将字符串作为命令执行 a=eval(?‘) strmatch(?substr‘,S) 匹配字符串操作 得到指定的子串 strtok(?string‘,d) int2str(A) 将整数转换为字符串 num2str(A) 将浮点数转换为字符串 str2num(S) 将字符串转换为浮点数 dec2hex(A) 把十进制整数转换为十六进制字符串 hex2dec(S) 把十六进制字符串转换为十进制整数 hex2num(S) 把十六进制字符串转换为浮点数 dec2bin(A) 把十进制数转换为二进制字符串 例:打印出ASCII码从32-126之间所有可显示的字符。 char(32:126) char(48:126)
4.14 类与对象
由于引进了类和对象,MATLAB允许用户增加新的数据类型和操作,变量的类型描述变量的数据结构,指示数据的操作。对象是类的实现。 MATLAB内建5种数据类。
数据类 说明 double 双精度浮点数数组或矩阵 sparse 二维实数(复数)稀疏矩阵 char 字符数组 struct 结构数组 cell 单元数组 要定义一个MATLAB类,需经过下面几方面工作: 1.建立类路径:
类路径下包含描述类的所有方法的M文件。类路径的名称由字符“@”加类名称构成。例如,定义类ploynom的M文件都放置在一个名为@polynom的路径下面,我们用此类来描述多项式,通过调用函数构造函
3
数,由多项式的系数来确定多项式。如:p=polynom([1 0 -2 -5]),表示多项式p(x)=x-2x-5。 2.定义数据结构:
所有对象均存储在MATLAB结构中,结构的每一个字段以及字段的详细操作仅对操作类的方法是可见的。如上例,将各次幂的系数以降幂的顺序作为一个行矢量来描述多项式。类polynom的对象p就成了一个仅有一个字段p.c的结构。而这个字段仅有@polynom路径下的函数可以使用。 3.定义构造函数:
34
MatLab讲义 2002年9月版
类的方法路径下必须包含构造函数,构造函数的名称与类名称相同,构造函数的主要作用是为对象初始化数据结构,并指定类标记。
下面是类polynom的构造函数@polynom/polynom.m: function p=polynom(a) if nargin==0 p.c=[];
p=class(p,'polynom'); elseif isa(a,'polynom') p=a; else
p.c=a(:);
p.class(p,'polynom'); end
4.定义类型转换函数:
转换函数的调用形式为:b=class_name(a)
这里a是一个非class_name类的对象。在MATLAB中最为重要的两个转换函数是double和char。这里,我们为polynom类建立这样两个转换函数。建立M文件@polynom/double.m,实现从polynom类到double类的转换。格式如下:
function c=double(p) c=p.c
要实现类polynom到类char的转换,相对来说要麻烦得多。 function s=char(p) c=p.c;
if all(c==0) s='0'; else
d=length(p.c)-1; s=[]; for a=c; if a~=0;
if ~isempty(s) if a>0
s=[s '+']; else
s=[s '-']; a=-a; end end
if a~=1|d==0
s=[s num2str(a)]; if d>0
s=[s '*']; end end end if d>=2
s=[s 'x^' int2str(d)]; elseif d==1 s=[s 'x'];
35