数值数组及向量化运算.docx
《数值数组及向量化运算.docx》由会员分享,可在线阅读,更多相关《数值数组及向量化运算.docx(43页珍藏版)》请在冰豆网上搜索。
![数值数组及向量化运算.docx](https://file1.bdocx.com/fileroot1/2023-2/21/8269e84a-8a56-4d46-b8f1-6355129bfe68/8269e84a-8a56-4d46-b8f1-6355129bfe681.gif)
数值数组及向量化运算
第三章数值数组及向量化运算
数值数组(NumericArray)和数组运算(ArrayOperations)始终是MATLAB的核心内容。
本书从第3章起,全部注意力将集中于数值数组及其运算。
本章系统阐述:
数组浮点算法的特点;一、二维数值数组的创建和寻访;数组运算和向量化编程;实现数组运算的基本函数;常用标准数组生成函数和数组构作技法;非数NaN、“空”数组概念和应用;关系和逻辑操作。
3.1数值计算的特点和地位
【例3.1-1】已知
,求
。
(1)符号计算解法
symstx%定义符号变量
ft=t^2*cos(t)%定义函数
sx=int(ft,t,0,x)%符号积分
ft=
t^2*cos(t)
sx=
x^2*sin(x)-2*sin(x)+2*x*cos(x)
说明:
1.符号计算可以得到和手工数学推导相同的结果;
2.可以得到精确的解析结果
(2)数值计算解法
dt=0.05;%定义采样间隔
t=0:
dt:
5;%定义数值积分的计算区域,数值计算只在有限的区间的采样点进行
Ft=t.^2.*cos(t);%定义计算的函数
Sx=dt*cumtrapz(Ft);%数值积分,计算从0开始到每个采样点位置的区间内,Ft曲线%下的面积,此面积由宽度为t的小梯形面积累加而成;
%下面分步看一下计算结果:
whos
bar(t,Ft)%Ft函数的数值
holdon
plot(t,Sx,'.r','MarkerSize',12)%数值积分结果
axis(0,6,-25,10)
holdoff
NameSizeBytesClass
Ft1x101808doublearray
Sx1x101808doublearray
dt1x18doublearray
t1x101808doublearray
xqxqxq12341x11logicalarray
Grandtotalis305elementsusing2433bytes
说明:
1.进行数值计算,必须首先确定一组自变量采样点,即确定一个自变量的取值区间,并设定取样间隔;
2.数值计算的表达式都是在意志的数值采样点进行计算;
3.数值计算的结果也是离散的;
4.再将数值计算的结果扩展到更大的计算区域时不一定成立;
5.直接观察计算结果的离散数值难以看出函数关系,但图形有利于加深对函数的认识。
【例3.1-2】已知
,求
。
(1)符号计算解法
symstx
ft=exp(-sin(t))
sx=int(ft,t,0,4)
ft=
exp(-sin(t))
Warning:
Explicitintegralcouldnotbefound.
>Insym.intat58
sx=
int(exp(-sin(t)),t=0..4)
说明:
符号计算的能力有限,不是在任何情况下都可以得到计算结果;
(2)数值计算解法
dt=0.05;
t=0:
dt:
4;
Ft=exp(-sin(t));
Sx=dt*cumtrapz(Ft);
Sx(end)
bar(t,Ft)
holdon
plot(t,Sx,'.r','MarkerSize',15)
holdoff
xlabel('x')
legend('Ft','Sx')
holdoff
ans=
3.0632
说明:
数值计算的应用非常广泛,只要给定计算区间、采用点和计算表达式,总是可以得到数值计算的结果。
3.2数值数组的创建和寻访
3.2.1一维数组的创建
1递增/减型一维数组的创建
主要特征:
(1)数组元素值的大小按照递增或者递减的顺序排列,元素之间的“差”是固定的或者“等步长”的。
(2)主要用作函数的自变量,for循环中的自变量等。
创建方法:
(1)“冒号”生成法
格式:
x=a:
inc:
b
说明:
x----变量名称;
a/b-----起点/终点
inc-----步长(正数或者负数)
例子:
(1)i=0:
1:
10
i=
012345678910
(2)i=0:
10
i=
012345678910
说明:
缺省的步长是1;
(3)i=0:
1:
8.5
ans=
012345678
(4)i=0.5:
1:
10
i=
0.50001.50002.50003.50004.50005.50006.50007.50008.50009.5000
说明:
当abs(b-a)不能被inc整除,生成的最后一个元素将小于b;
(5)i=10:
-1:
0
i=
109876543210
(6)i=10:
-1:
20
i=
Emptymatrix:
1-by-0
说明:
步长可以为负数,但此时前面的元素必须大于后面的。
(2)线性(或者对数)定点法
格式:
x=linspace(a,b,n)%以a,b为左右端点,产生线性等间隔的(1*n)行数组;
x=logspace(a,b,n)%以10^a,10^b为左右端点,产生对数等间隔的(1*n)行数组;
xl=linspace(0,10,9)
xl=
01.25002.50003.75005.00006.25007.50008.750010.0000
说明:
x=linespace(a,b,n)<===>x=a:
(b-a)/(n-1):
b
xl=logspace(1,4,4)
xl=
10100100010000
说明:
logspace(x1,x2,N)用于在10^x1and10^x2之间产生N个对数均匀间隔的点。
2通用型一维数组的创建
(1)逐个元素输入法,最简单而通用的方法。
如:
y=[1,2,sin(pi/5),-exp(-3)]
y=
1.00002.00000.5878-0.0498
(2)使用Matlab函数生成,如rand(1,n),ones(1,n)
rand(1,10)%在[0,1]之间产生(1*10)的向量;
ans=
0.95010.23110.60680.48600.89130.76210.45650.01850.82140.4447
rand(5,5)
ans=
0.61540.40570.05790.20280.0153
0.79190.93550.35290.19870.7468
0.92180.91690.81320.60380.4451
0.73820.41030.00990.27220.9318
0.17630.89360.13890.19880.4660
rand(5,5)
ans=
0.55480.27310.90840.64080.9943
0.12100.25480.23190.19090.4398
0.45080.86560.23930.84390.3400
0.71590.23240.04980.17390.3142
0.89280.80490.07840.17080.3651
补充说明:
为了让前面出现过的随机数再次重复出现,需要对随机数生成器的“状态state”或者“种子seed”进行设置。
rand('state',0)%设置随机数生成器的状态
rand(1,5)
ans=
0.95010.23110.60680.48600.8913
rand('state',0)%设置随机数生成器的状态
rand(1,5)
ans=
0.95010.23110.60680.48600.8913
ones(3,8)
ans=
11111111
11111111
11111111
思考题、练习题:
(1)如何生成在(60,100)之间均匀随机分布的(5*8)的矩阵?
如何取整数呢?
(2)产生列数组x2=(1:
6)'x2=linspace(0,pi,4)'
思考题答案:
(1)round(60+rand(5,8).*40)
ans=
9765836184838866
8768787584626387
6984628761757888
9485616461857889
8575736168897479
(2)
x2=(1:
6)'
x2=
1
2
3
4
5
6
x2=linspace(0,pi,4)'
x2=
0
1.0472
2.0944
3.1416
其他函数说明:
rand()%生成均匀分布的随机数组;
randn()%生成正态分布的随机数组;
round()%四舍五入取整数
zeros()%产生0
eye(N)%产生N*N的单位矩阵
eye(5)
ans=
10000
01000
00100
00010
00001
3.2.2二维数组的创建
一种方法是采用手工输入法,另外还有如下方法。
1小规模数组的直接输入法
【例3.2-2】在MATLAB环境下,用下面三条指令创建二维数组C。
a=2.7358,b=33/79
C=[1,2*a+i*b,b*sqrt(a);sin(pi/4),a+5*b,3.5+i]
a=
2.7358
b=
0.4177
C=
1.00005.4716+0.4177i0.6909
0.70714.82443.5000+1.0000i
2中规模数组的数组编辑器创建法
在数组规模比较大了之后,就不适合采用直接手工输入方法了,可以采用数组编辑器。
【例3.2-3】根据现有数据创建一个
的数组。
图3.2-1利用数组编辑器创建中规模数组
3中规模数组的M文件创建法
(1)对于常用的数组,可以保存在一个mat文件中,然后就可以在后面调用了。
举例:
clear
a=(1:
10);
b=(11:
20);
c=(21:
30);
d=[a;b;c]
savemyMatrixd;
clear
loadmyMatrix
d=
12345678910
11121314151617181920
21222324252627282930
如果要通过运行m文件产生数组,可以在m文件中编辑数组,然后再运行m文件即可。
如:
在myMatirx.m文件中输入如下内容,然后运行myMatrix.m就可以载入该数组。
%Construct2Dmatrix
d=[12345678910
11121314151617181920
21222324252627282930]
【例3.2-4】创建和保存数组AM的MyMatrix.m文件。
(1)打开文件编辑调试器,并在空白填写框中输入所需数组(见图3.2-2)。
(2)最好,在文件的首行,编写文件名和简短说明,以便查阅(见图3.2-2)。
(3)保存此文件,并且文件起名为MyMatrix.m。
(4)以后只要在MATLAB指令窗中,运行MyMatrix.m文件,数组AM就会自动生成于MATLAB内存中。
图3.2-2利用M文件创建数组
4利用MATLAB函数创建数组
用于产生特殊二维数组/矩阵的函数如下:
diag()%产生对角数组
eye()%产生单位数组
magic()%产生魔方数组
rand()%产生随机数
randn()
random()
3.2.3二维数组元素的标识和寻访
【例3.2-6】本例演示:
数组元素及子数组的各种标识和寻访格式;冒号的使用;end的作用。
A=zeros(2,6)
A(:
)=1:
12
A=
000000
000000
A=
1357911
24681012
A(2,4)
A(8)
ans=
8
ans=
8
A(:
[1,3])
A([1,2,5,6]')
ans=
15
26
ans=
1
2
5
6
A(:
4:
end)%双下标,显示从第四列到最后一列的所有元素。
end表示最后一列
ans=
7911
81012
A(2,1:
2:
5)=[-1,-3,-5]
A=
1357911
-14-38-512
A(2,[1:
2:
5])=[-1,-3,-5]
A=
1357911
-14-38-512
A(2,[1,2,5])=[-1,-3,-5]
A=
1357911
-1-3-38-512
B=A([1,2,2,2],[1,3,5])
B=
159
-1-3-5
-1-3-5
-1-3-5
L=A<3
A(L)=NaN
L=
100000
101010
A=
NaN357911
NaN4NaN8NaN12
3.2.4数组构作技法综合
下面的指令完成数组的反转、提取、插入、收缩、重组等操作,用于对已经生成的数组进行修改、扩展。
指令
含义
diag
提取对角元素,或者生成对角阵
repmat
在指定的行数和列数铺方模块数足,以形成更大的数组
reshape
在总元素数量不变的前提下,改变数组的行数和列数
flipud
以数组的水平中线为对称轴,交换上下对称位置的数组元素
fliplr
以数组的垂直中线为对称轴,交换上下对称位置的树族元素
rot90
数组按照逆时针旋转90度。
【例3.2-7】数组操作函数reshape,diag,repmat的用法;空阵[]删除子数组的用法。
a=1:
8
A=reshape(a,4,2)
A=reshape(A,2,4)
a=
12345678
A=
15
26
37
48
A=
1357
2468
b=diag(A)
B=diag(b)
b=
1
4
B=
10
04
D1=repmat(B,2,4)
D1=
10101010
04040404
10101010
04040404
D1([1,3],:
)=[]
D1=
04040404
04040404
【例3.2-8】函数flipud,fliplr,rot90对数组的操作体现着“矩阵变换”。
A=reshape(1:
9,3,3)
A=
147
258
369
B=flipud(A)
B=
369
258
147
C=fliplr(A)
C=
741
852
963
D=rot90(A)%旋转一次
D=
789
456
123
D=rot90(A,2)%旋转2次
D=
963
852
741
3.3数组运算
1.数组运算的由来和规则
函数关系数值计算模型的分类
提高程序执行性能的三大措施
数组运算规则
A=reshape(1:
9,3,3)
A=
147
258
369
B=reshape(10:
18,3,3)
B=
101316
111417
121518
转置运算
A'
ans=
123
456
789
A.'
ans=
123
456
789
A+B
ans=
111723
131925
152127
A.+B
?
?
?
Error:
UnexpectedMATLABoperator.
A-B
ans=
-9-9-9
-9-9-9
-9-9-9
A.-B
?
?
?
Error:
UnexpectedMATLABoperator.
说明:
对于数组运算,.+与+相同,.-与-相同
A.*B%数组计算
ans=
1052112
2270136
3690162
A*B%矩阵计算
ans=
138174210
171216261
204258312
说明:
注意数组计算与矩阵计算的差别。
A./B
ans=
0.10000.30770.4375
0.18180.35710.4706
0.25000.40000.5000
B.\A
ans=
0.10000.30770.4375
0.18180.35710.4706
0.25000.40000.5000
A.\B
ans=
10.00003.25002.2857
5.50002.80002.1250
4.00002.50002.0000
B./A
ans=
10.00003.25002.2857
5.50002.80002.1250
4.00002.50002.0000
说明:
注意\,/的差别:
A.^B
ans=
1.0e+017*
0.00000.00000.0003
0.00000.00000.0225
0.00000.00001.5009
B.^A
ans=
1.0e+011*
0.00000.00000.0027
0.00000.00000.0698
0.00000.00011.9836
a=5;
a+A
ans=
6912
71013
81114
a.+A
?
?
?
Error:
UnexpectedMATLABoperator.
说明:
对于一个标量和一个数组的运算,不需要使用“.”运算符。
a-A
ans=
41-2
30-3
2-1-4
a.-A
?
?
?
Error:
UnexpectedMATLABoperator.
说明:
对于一个标量和一个树组的加,减运算,不需要使用“.”运算符。
例子:
数组乘法运算:
a.*A
ans=
52035
102540
153045
A.*a
ans=
52035
102540
153045
例子:
数组除法运算
a./A
ans=
5.00001.25000.7143
2.50001.00000.6250
1.66670.83330.5556
a.\A
ans=
0.20000.80001.4000
0.40001.00001.6000
0.60001.20001.8000
A./a
ans=
0.20000.80001.4000
0.40001.00001.6000
0.60001.20001.8000
说明:
对于数组和标量得乘法和除法运算,必须使用“.”,注意\,/的差别。
a.^A
ans=
562578125
253125390625
125156251953125
A.^a
ans=
1102416807
32312532768
243777659049
注意:
下面进行的是矩阵运算,不是数组运算。
a*A
ans=
52035
102540
153045
A*a
ans=
52035
102540
153045
a/A
?
?
?
Errorusing==>mrdivide
Matrixdimensionsmustagree.
a\A
ans=
0.20000.80001.4000
0.40001.00001.6000
0.60001.20001.8000
说明:
这里进行的不是数组运算,而是矩阵运算。
总结:
(1)数组运算中,两个数组的加减乘除等都需要使用“.”运算;
(2)数组运算中,一个标量和一个数组的加减运算可以省略“.”运算;
(3)数组运算中,一个标量和一个数组的乘除运算不可以省略“.”运算,否则变成了矩阵运算。
思考题:
1为了对班级50名同学的学年综合测评的智育成绩进行统计,假设共有Eng,PE,Phy,Chn,Mth五门课程,分别用5*10的数组表示,学号为k的同学(k=1:
50)的课程成绩存储在五个数组中的第k个元素上,任何一门课程的成绩都在(60,100)之间均匀分布且为整数。
五门课程的学分为credit=[3,5,4,2,4[,请完成如下统计:
(1)统计各门课程的平均分,存入变量meanScore中,;
(2)统计班级学生的加权平均分;
(3)统计加权平均分为60~69分的同学的数量,存入数组a;
(4)统计加权平均分为70~79分的同学的数量,存入数组b;
(5)统计加权平均分为80~89分的同学的数量,存入数组c;
(6)统计加权平均分为90分及以上的同学的数量,存入数组d;
(7)将如上四个分数段的同学的数量存入数组E中。
Eng=round(60+(rand(5,10)*40))
Eng=
98908