范文一:MATLAB编程(第二版) 第七章
第七章 稀疏矩阵 单元阵列 结构 ................................................................................................. 3 7.1 稀疏矩阵............................................................................................................................ 3
7.1.1 sparse数据类型 ....................................................................................................... 4
例7.1 ................................................................................................................................. 6
7.2 单元阵列(cell array) .......................................................................................................... 8
7.2.1 创建单元阵列 ......................................................................................................... 9
7.2.2 单元创建者——大括号({})的应用 .................................................................... 10
7.2.3 查看单元阵列的内容 ........................................................................................... 10
7.2.4 对单元阵列进行扩展 ........................................................................................... 11
7.2.5 删除阵列中的元素 ............................................................................................... 12
7.2.6 单元阵列数据的应用 ........................................................................................... 12
7.2.7 字符串单元阵列 ................................................................................................... 12
7.2.8 单元阵列的重要性 ............................................................................................... 13
7.2.9 单元阵列函数总结 ............................................................................................... 16 7.3 结构数组.......................................................................................................................... 16
7.3.2 增加域到结构 ....................................................................................................... 17
7.3.3 删除结构中的域 ................................................................................................... 18
7.3.4 结构数组中数组的应用 ....................................................................................... 18
7.3.5 函数getfield和函数setfield ................................................................................ 20
7.3.6 对结构数组应用size函数 ................................................................................... 20
7.3.8 struct函数总结 ...................................................................................................... 21
测试7.1 ........................................................................................................................... 21
7.4 总结.................................................................................................................................. 22
7.4.1 好的编程习惯总结 ............................................................................................... 22
7.4.2 MATLAB函数命令总结 ...................................................................................... 22 7.5 练习.................................................................................................................................. 23
7.1.................................................................................................................................... 23
7.2.................................................................................................................................... 23
7.3.................................................................................................................................... 23
7.4.................................................................................................................................... 23
7.5.................................................................................................................................... 24
7.6.................................................................................................................................... 24
第七章 稀疏矩阵 单元阵列 结构
在本章中我们要学习三种数据类型:稀疏矩阵,单元阵列和结构。稀疏矩阵是矩阵的一
种特殊形式,在这个矩阵中只对非零元素分配内存。单元阵列也是一种矩阵,它的每一个元
素可以是MATLAB任何一种数据类型。它们广泛应用于MATLAB用户图象界面(GUI)
函数。最后,结构提供了一种在单个变量中存储了不同类型的数据的方法,在这个变量中的
每一个数据项目都有一个独立的名字。
7.1 稀疏矩阵
我们在第二章中已经学过了普通的MATLAB数组。当一个普通的数组被声明后,
MATLAB将会为每一个数组元素分配内存。例如函数a = eye(10)要创建了100个元素,按
10×10的结构分配,对角线上的元素均为1,其余的元素为0。注意这些数组其中的90个元
素为0。这个包含有一百个元素的矩阵,只有10个元素包含非零值。这是稀疏矩阵或稀疏
数组的一个例子。稀疏矩阵是指一个很大的矩阵,且大多数的元素为0。
>> a=2*eye(10)
a =
2 0 0 0 0 0 0 0 0 0
0 2 0 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0
0 0 0 0 2 0 0 0 0 0
0 0 0 0 0 2 0 0 0 0
0 0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 2 0 0
0 0 0 0 0 0 0 0 2 0
0 0 0 0 0 0 0 0 0 2
现在假如我们要创建一个10×10的矩阵,定义如下
b =
1 0 0 0 0 0 0 0 0 0
0 2 0 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
若a,b两矩阵相乘得到的结果为
>> c = a * b
c =
2 0 0 0 0 0 0 0 0 0
0 4 0 0 0 0 0 0 0 0
0 0 4 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0
0 0 0 0 10 0 0 0 0 0
0 0 0 0 0 2 0 0 0 0
0 0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 2 0 0
0 0 0 0 0 0 0 0 2 0
0 0 0 0 0 0 0 0 0 2
这两个稀疏矩阵相乘需要1900次相加和相乘,但是在大多数时侯相加和相乘的结果为
0,所以我们做了许多的无用功。这个问题会随着矩阵大小的增大而变得非常的严重。例如,
假设我们要产生两个200×200的稀疏矩阵,如下所示
a = 5 * eye(200);
b = 3 * eye(200);
每一个矩阵有20000个元素,其中19800个元素是0。进一步说,对这两个矩阵相乘需
要7980000次加法和乘法。
我们可以看出对大规模稀疏矩阵进行存储和运算(其中大部分为0)是对内存空间和cpu
资源的极大浪费。不巧的是,在现实中的许多问题都需要稀疏矩阵,我们需要一些有效的方
示来解决这个问题。
大规模供电系统是现实世界中涉及到稀疏矩阵一个极好的例子。大规模供电系统可以包
括上千条或更多的母线,用来产生,传输,分配电能到子电站。如果我们想知道这个系统的
电压,电流和功率,我们必须首先知道每一条母线的电压。如果这个系统含有一千个母线,
这就要用到含有1000个未知数的联立方程组,包括一个方程,也就是说我们要创建含有
1000000个元素的矩阵。解出这个矩阵,需要上百万次的浮点运算。
但是,在这个系统中,一条母线平均只它的三条母线相连,而在这个矩阵中每一行其他
的996个元素将为0,所以在这个矩阵的加法和乘法运算中将会产生0。如果在求解的过程
中这些0可以忽略,那么这个电力系统的电压和电流计算将变得简单而高效。
7.1.1 sparse数据类型
在MATLAB中有一个专门的数据类型,用来对稀疏进行运算。sparse数据类型不同于
doulbe数据,它在内存中只存储非零元素。实际上,sparse数据类型只存储每一个非零元素
的三个值:元素值,元素的行号和列号。尽管非零元素这三个值必须存储在这内存,但相对
于存储稀疏矩阵的所有元素来说要简单高效得多。
我们用10×10的方阵来说明稀疏矩阵的应用。
>> a = eye(10)
a =
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
如果这个矩阵被转化为稀疏矩阵,它的结果是
>> as = sparse(a)
as =
(1,1) 1
(2,2) 1
(3,3) 1
(4,4) 1
(5,5) 1
(6,6) 1
(7,7) 1
(8,8) 1
(9,9) 1
(10,10) 1
注意在稀疏矩阵存储的是行列地址和这一点所对应的非零数据值。只要一个矩阵的大部分数都是0,这种方法用来存储数据就是高效的,但是如果非零元素很多的话,那么用占用更多的空间,因为稀疏矩阵需要存储蓄地址。函数issparse通常用作检测一个矩阵是否为稀疏矩阵。如果这个矩阵是稀疏的,那么这个函数将会返回1。
稀疏矩阵的优点可以通过下面的描述体现出来,考虑一个1000×1000的矩阵平均每一行只有4个非零元素。如果这个矩阵以全矩阵的形式储存,那么它要战胜8000000个字节。从另一方面说,如果它转化为一个稀疏矩阵,那么内存的使用将会迅速下降。
7.1.1.1 产生稀疏矩阵
MATLAB可以通过sparse函数把一个全矩阵转化为一个稀疏矩阵,也可以用MATLAB函数speye,sprand和sprandn直接产生稀疏矩阵,它们对应的全矩阵为eye,rand,和randn。例如,表达式a = speye(4)将产生一个4×4的稀疏矩阵。
>> a = speye(4)
a =
(1,1) 1
(2,2) 1
(3,3) 1
(4,4) 1
表达式b = full(a)把稀疏矩阵转化相应的全矩阵。
>> b = full(a)
b =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
7.1.1.2 稀疏矩阵的运算
如果一个矩阵是稀疏的,那么单个元素可以通过简单的赋值语句添加或删除,例如下面的语句产生一个4×4的稀疏矩阵,然后把其他的非零元素加入其中。
>> a = speye(4)
a =
(1,1) 1
(2,2) 1
(3,3) 1
(4,4) 1
>> a(2,1) = -2
a =
(1,1) 1
(2,1) -2
(2,2) 1
(3,3) 1
(4,4) 1
MATLAB允许全矩阵与稀疏的混合运算。它们产生的结果可以是全矩阵也可以是稀疏矩阵,这取决于那种结果更高效。更重要的是,任何的适用全矩阵算法同样地也适合稀疏矩阵。
表7.1 列出的是一些普通的稀疏矩阵。
表7.1 普通的MATLAB稀疏矩阵函数
类别 函数 描述
speye 创建一个稀创建一个单位稀疏矩阵
sprand 疏矩阵 创建一个稀疏矩阵,元素是符合平均分布的随机数
sprandn 创建一个稀疏矩阵,元素是普通的随机数
sparse 全矩阵和稀把一个全矩阵转化为一个稀疏矩阵
full 疏矩阵的转把一个稀疏矩阵转化为全矩阵
find 换函数 找出矩阵中非零元素和它对应的上下标
nnz 对稀疏矩阵非零元素的个数
nonzeros 进行操作的返回一个向量,其中的元素为矩阵中非零元素
spones 函数 用1代替矩阵中的非零元素
spalloc 一个稀疏矩阵所占的内存空间
issparse 如果是稀疏矩阵就返回1
spfun 给矩阵中的非零元素提供函数
spy 用图象显示稀疏矩阵
例7.1
用稀疏矩阵解决联立方程组
为了解说明稀疏矩阵在MATLAB中应用,我们将用全矩阵和稀疏矩阵来解决下面的联
立方程组。
1.0x + 0.0x + 1.0x + 0.0x + 0.0x + 2.0x + 0.0x - 1.0x = 3.0 12345678
0.0x + 1.0x + 0.0x + 0.4x + 0.0x + 0.0x + 0.0x + 0.0x = 2.0 12345678
0.5x + 0.0x + 2.0x + 0.0x + 0.0x + 0.0x - 1.0x + 0.0x = -1.5 12345678
0.0x + 0.0x + 0.0x + 2.0x + 0.0x + 1.0x + 0.0x + 0.0x = 1.0 12345678
0.0x + 0.0x + 1.0x + 1.0x + 1.0x + 0.0x + 0.0x + 0.0x = -2.0 12345678
0.0x + 0.0x + 0.0x + 1.0x + 0.0x + 1.0x + 0.0x + 0.0x = 1.0 12345678
0.5x + 0.0x + 0.0x + 0.0x + 0.0x + 0.0x + 1.0x + 0.0x = 1.0 12345678
0.0x + 1.0x + 0.0x + 0.0x + 0.0x + 0.0x + 0.0x + 1.0x = 1.0 12345678
答案
为了解决这一问题,我们将创建一个方程系数的全矩阵,并用sparse函数把他转化为稀
疏矩阵。我们用两种方法解这个方程组,比较它们的结果和所需的内存。
代码如下:
% Script file: simul.m
%
% Purpose:
% This program solves a system of 8 linear equations in 8
% unknowns (a*x = b), using both full and sparse matrices.
%
% Record of revisions:
% Date Programmer Description of change % ==== ======== =============== % 10/14/98 S. J. Chapman Original code %
% Define variables:
% a --Coefficients of x (full matrix)
% as --Coefficients of x (sparse matrix)
% b --Constant coefficients (full matrix)
% bs --Constant coefficients (sparse matrix)
% x --Solution (full matrix)
% xs --Solution (sparse matrix) % Define coefficients of the equation a*x = b for % the full matrix solution.
a = [
1.0 0.0 1.0 0.0 0.0 2.0 0.0 -1.0; ...
0.0 1.0 0.0 0.4 0.0 0.0 0.0 0.0; ...
0.5 0.0 2.0 0.0 0.0 0.0 -1.0 0.0; ...
0.0 0.0 0.0 2.0 0.0 1.0 0.0 0.0; ...
0.0 0.0 1.0 1.0 1.0 0.0 0.0 0.0; ...
0.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0; ...
0.5 0.0 0.0 0.0 0.0 0.0 1.0 0.0; ...
0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0
];
b = [ 3.0 2.0 -1.5 1.0 -2.0 1.0 1.0 1.0]'; % Define coefficients of the equation a*x = b for % the sparse matrix solution.
as = sparse(a);
bs = sparse(b);
% Solve the system both ways
disp ('Full matrix solution:');
x = a\b
disp ('Sparse matrix solution:');
xs = as\bs
% Show workspace
disp('Workspace contents after the solutions:') whos
运行这个程序,结果如下
>> simul
Full matrix solution:
x =
0.5000
2.0000
-0.5000
-0.0000
-1.5000
1.0000
0.7500
-1.0000
Sparse matrix solution:
xs =
(1,1) 0.5000
(2,1) 2.0000
(3,1) -0.5000
(5,1) -1.5000
(6,1) 1.0000
(7,1) 0.7500
(8,1) -1.0000
Workspace contents after the solutions:
Name Size Bytes Class
a 8x8 512 double array
as 8x8 276 double array (sparse)
b 8x1 64 double array
bs 8x1 104 double array (sparse)
x 8x1 64 double array
xs 8x1 92 double array (sparse)
Grand total is 115 elements using 1112 bytes
两种算法得到了相同的答案。注意用稀疏矩阵产生的结果不包含x,因为它的值为0。4
注意b的稀疏形式占的内存空间比全矩阵形式还要大。这种情况是因为稀疏矩阵除了元素值之外必须存储它的行号和列号,所以当一个矩阵的大部分元素都是非零元素,用稀疏矩阵将降低运算效率。
7.2 单元阵列(cell array)
单元阵列是MATLAB中特殊一种数组,它的元素被称为单元(cells),它可以存储其它类型的MATLAB数组。例如,一个单元阵列的一个单元可能包含一个实数数组或字符型数组,还可能是复数组(图7.1所示)。
在一个编程项目中,一个单元阵列的每一个元素都是一个指针,指向其他的数据结构,而这些数据结构可以是不同的数据类型。单元阵列为选择问题信息提供极好的方示,因为所有信息都聚集在一起,并可以通边一单个名字访问。单元阵列用大括号{}替代小括号来选择和显示单元的内容。这个不同是由于单元的内容用数据结构代替了内容。假设一单元阵列如图7.2所示。元素a(1,1)是数据结构3×3的数字数组。a(1,1)的含义为显示这个单元的内容,它是一个数据结构。
cell 1,2 cell 1,1
13-7,,,,'This is a string' 206 ,,,,051
cell 2,2 cell 2,1
[] 3+i4-5,, ,,-i103-i4
图7.1 一个单元阵列的一个单元可能包含一个实数数组或字符型数组,还可能是复数组
13-7,,,,206 ,,,,051
'This is a
text string.' a(1,1) a(1,2)
a(2,1) a(2,2)
[]
3+i4-5,, ,,-i103-i4
图7.2 单元阵列中的每一个元素都是指向其他数据结构的指针,指向的数据结构可能都不相
同
>> a(1,1)
ans =
[3x3 double]
相对地,a{1,1}的含义为显示这个数据结构的内容。
>> a{1,1}
ans =
1 3 -7
2 0 6
0 5 1
总起来说,标识a{1,1}反映的是数据结构a(1,1)内容,而标识a(1,1)是一个数据结构。
好的编程习惯
当你访问一单元阵列时,不要把()与{}混淆。它们完全不同的运算。
7.2.1 创建单元阵列
创建单元阵列有两种方法
, 用赋值语句
, 用函数cell创建
最简单的创建单元阵列的方法是直接把数据结构赋值于独立的单元,一次赋一个单元。但用cell函数创建将会更加地高效,所以我们用cell创建大的单元数组。 7.2.1.1 用赋值语句创建单元阵列
你可以用赋值语句把值赋于单元阵列的一个单元,一次赋一个单元。这里有两种赋值的方法,即内容索引(content indexing)和单元索引(cell indexing)。
内容索引要用到大括号{},还有它们的下标,以及单元的内容。例如下面的语句创建了一个2×2的单元阵列,如图7.2所示。
a{1,1} = [1 3 -7; 2 0 6; 0 5 1];
a{1,2} = 'This is a text string.';
a{2,1} = [3+4*i -5; -10*i 3-4*i];
a{2,2} = [];
索引的这种类型定义了包含在一个单元中的数据结构的内容。
单元索引把存储于单元中的数据用大括号括起来,单元的下标用普通下标标记法。例如下面的语句将创建一个2×2的单元阵列,如图7.2所示。
a(1,1) ={[1 3 -7; 2 0 6;0 5 1]};
a(1,2) = {'This is a text string.'};
a(2,1) = {[3+4*i -5; -10*i 3-4*i]};
a(2,2) = {[]};
索引的这种类型创建了包含有指定值的一个数据结构,并把这个数据结构赋于一个单元。
这两种形式是完全等价的,你可以在你的程序任选其一。
常见编程错误
不要创建一个与已存在的数字数组重名的元阵列。如果得名了,MATLAB会认为你把单元阵列的内容赋值给一个普通的数组,这将会产生一个错误信息。在创建单元阵列之前,确保同名的数字数字数组已经被删除。
7.2.1.2 用cell函数创建单元阵列
函数cell允许用户创建空单元阵列,并指定阵列的大小。例如,下面的语句创建一个2×2的空单元阵列。
a = cell(2, 2)
一旦单元阵列被创立,你就可以用赋值语句对单元阵列进行赋值。
7.2.2 单元创建者——大括号({})的应用
如果在单个大括号中列出所有单元的内容,那么就定义了许多的单元,在一行中的独立单元用逗号分开,行与行之间用分号隔开。例如下面的语句创建一个2×3单元阵列。
b = {[1 2], 17, [2;4]; 3-4*i, 'Hello', eye(3)}
7.2.3 查看单元阵列的内容
MATLAB可以把单元阵列每一个元素的数据结构缩合在一行中显示出来。如果全部的数据结构没有被显示出来,那么显示就是一个总结。例如,单元阵列a和b显示如下
>> a
a =
[3x3 double] [1x22 char]
[2x2 double] []
>> b
b =
[1x2 double] [ 17] [2x1 double]
[3.0000- 4.0000i] 'Hello' [3x3 double]
注意MATLAB显示的只是数据结构,包括中括号和省略号,而不包含数据结构的内容。
如果你想要知道看到单元阵列的所有内容,要用到celldisp函数。这个函数显示的是每一个单元中的数据结构的内容。
>> celldisp(a)
a{1,1} =
1 3 -7
2 0 6
0 5 1
a{2,1} =
3.0000 + 4.0000i -5.0000
0 -10.0000i 3.0000 - 4.0000i
a{1,2} =
This is a text string.
a{2,2} =
[]
如果要用高质量的图象显示数据结构的内容,要用到函数cellplot。例如,函数cellplot(b)产生了一个图象,如图7.3所示。
图7.3 用函数cellplot显示单元阵列b数据结构的内容
7.2.4 对单元阵列进行扩展
一个值赋值于一个单元阵列中的元素,如果这个元素现在不存在,那么这个元素就会被自动的建立,其他所需的元素也会被自动建立。例如,假设定义了一个2×2单元阵列,如图7.1所示。如果我们执行下面的语句
a{3, 3} = 5
单元阵列将会自动扩展为3×3单元阵列,如图7.4所示。
cell 1,1 cell 1,2 cell 1,3
13-7,,'This is a ,,[] 205 text string.' ,,,,051
cell 2,1 cell 2,2 cell 2,3
3+i4-5,, [] [] ,,-i103-i4
cell 3,1 cell 3,2 cell 3,3
[5] [] []
图7.4把一个值赋值于a(3,3)产生的结果。注意其他的空元素也是自动创建的。
7.2.5 删除阵列中的元素
如果要删除阵列中的所有元素,我们要用clear命令。如果要删除单元阵列中的部分元素,我们把空值赋值于这一部分元素。例如,假设a的定义如下
>> a
a =
[3x3 double] [1x22 char] []
[2x2 double] [] []
[] [] [5]
我们可以用下面的语句删除第三行
>> a(3,:)=[]
a =
[3x3 double] [1x22 char] []
[2x2 double] [] [] 7.2.6 单元阵列数据的应用
在一个单元阵列中,数据结构中数据可以随时用内容索引或单元索引调用。
例如假设单元阵列c的定义如下
c = {[1 2; 3 4],'dogs';'cats',i}
存储于c(1,1)的内容可由下面的语句调用
>> c{1,1}
ans =
1 2
3 4
同样c(2,1)中的元素可由下面的元素调用
>> c{2,1}
ans =
cats
一个单元内容的子集可由两套下标得到。例如,假设我们要得到单元c(1,1)中的元素(1,2)。为了达到此目的,我们可以用表达式c{1,1}(1,2),它代表单元c(1,1)中的元素(1,2)。
>> c{1,1}(1,2)
ans =
2
7.2.7 字符串单元阵列
在一个单元阵列中存储一批字符串与在标准的字符数组中存储相比是非常方便的,因为在单元阵列中每一个字符串的长度可以是不相同的,而在标准字符数组的每一行的长度都必须相等。这就意味着在单元阵列中的字符串没的必要增加多余的空格。许多的MATLAB用户图形界面函数均使用单元阵列,正是基于这个原因,我们将在第十章看到。
字符串单元阵列可以由两种方法创建。我们可以用方括号把独立的字符串插入到单元阵列,我们也可以函数cellstr把一个二维字符数组转化为相应的字符串单元阵列。
下面的例子用第一种方法创建了一个字符串单元阵列,并显示出这个阵列的结果。注意下面的每一个字符串具有不同的长度。
>> cellstring{1} = 'Stephen J. Chapman';
>> cellstring{2} = 'Male';
>> cellstring{3} = 'SSN 999-99-9999';
>> cellstring
cellstring =
'Stephen J. Chapman' 'Male' 'SSN 999-99-9999'
我们可以利用函数cellstr把一个二维字符数据转化为相应的字符串单元阵列。考虑下面的字符数组。
>> data = ['Line 1 ';'Additional Line']
data =
Line 1
Additional Line
相应的字符串单元阵列为
>> c = cellstr(data)
c =
'Line 1'
'Additional Line'
我们还可以用char函数它转化回去
>> newdata = char(c)
newdata =
Line 1
Additional Line
7.2.8 单元阵列的重要性
单元阵列是非常灵活的,因为各种类型的大量数据可以存储在每一个单元中。所以,它经常当作中间MATLAB数据结构来用。我们必须理解它,因为在第十章中MATLAB图形用户界面要用到它的许多特性。
还有,单元阵列的灵活性可能使它们具有函数普通特性,这个函数是指带有输入参数和输出参数的变量个数的函数。一种特别的输入参数varargin可以在自定义函数中得到,这种函数支持输入参数的变量的个数。这个参数显在输入参数列表的最后一项,它返回一个单元阵列,所以一个输入实参可以包括任意数目的实参。每一个实参都变成了由varagin返回的单元阵列元素。如果它被应用,varagin必须是函数中的最后一个输入参数。
例如,假设我们要编写一个函数,它可能需要任意个数的输入参数。这个函数执行如下所示
function test1(varargin)
disp(['There are ' int2str(nargin) ' arguments.']);
disp('The input arguments are:');
disp(varargin);
我们用不同的数目参数来执行这个函数,结果如下
>> test1
There are 0 arguments.
The input arguments are:
>> test1(6)
There are 1 arguments.
The input arguments are:
[6]
>> test1(1,'test 1',[1 2,3 4])
There are 3 arguments.
The input arguments are:
[1] 'test 1' [1x4 double]
正如我们所看到的,参数变成了函数中的单元阵列元素。
下面是一个简单函数例子,这个函数拥有不同的参数数目。函数plotline任意数目的1×2行向量,每一个向量包含一个点(x,y)。函数把这些点连成线。注意这个函数也接受直线类型字符串,并把这些字符串转递给plot的函数。
function plotline(varargin)
%PLOTLINE Plot points specified by [x,y] pairs. % Function PLOTLINE accepts an arbitrary number of % [x,y] points and plots a line connecting them. % In addition, it can accept a line specification % string, and pass that string on to function plot. % Define variables:
% ii --Index variable
% jj --Index variable
% linespec --String defining plot characteristics
% msg --Error message
% varargin --Cell array containing input arguments
% x --x values to plot
% y --y values to plot
% Record of revisions:
% Date Programmer Description of change % ==== ========= ===================== % 10/20/98 S. J. Chapman Original code % Check for a legal number of input arguments. % We need at least 2 points to plot a line... msg = nargchk(2,Inf,nargin);
error(msg);
% Initialize values
jj = 0;
linespec = '';
% Get the x and y values, making sure to save the line % specification string, if one exists.
for ii = 1:nargin
% Is this argument an [x,y] pair or the line
% specification?
if ischar(varargin{ii})
% Save line specification
linespec = varargin{ii};
else
% This is an [x,y] pair. Recover the values.
jj = jj + 1;
x(jj) = varargin{ii}(1);
y(jj) = varargin{ii}(2);
end
end
% Plot function.
if isempty(linespec)
plot(x,y);
else
plot(x,y,linespec);
end
我们用下面的参数调用这个函数,产生的图象如图7.5所示。用相同的数目的参数调用
函数,看它产生的结果为什么,
也有专门的输出参数,vargout,它支持不同数目的输出参数。这个参数显示在输出参数
列表的最后一项。它返回一个单无阵列,所示单个输出实参支持任意数目的实参。每一个实
参都是这个单无阵列的元素,存储在varargout。如果它被应用,varargout必须是输出参数
列表中最后一项,在其它输入参数之后。存储在varargout中的变量数由函数nargout确定,
这个函数用指定于任何一个已知函数的输出实参。例如,我们要编写一函数,它返回任意数
目的随机数。我们的函数可以用函数nargout指定输出函数的数目,并把这些数目存储在单
元阵列varargout中。
图7.5 函数plotline产生的图象
function [nvals, varargout] = test2(mult) % nvals is the number of random values returned
% varargout contains the random values returned
nvals = nargout - 1;
for ii = 1:nargout-1
varargout{ii} =randn * mult; end
当这个函数被执行时,产生的结果如下
>> test2(4)
ans =
-1
>> [a b c d] = test2(4)
a =
3
b =
-1.7303
c =
-6.6623
d =
0.5013
好的编程习惯
应用单元阵列varargin和varargout创建函数,这个函数支持不同数目的输入或输出参
数。
7.2.9 单元阵列函数总结
支持单元阵列的一些普通函数总结在表7.2中。
表7.2普通的单元阵列函数
函数 描述
cell 对单元阵列进行预定义
celldisp 显示出单元阵列的内容
cellplot 画出单元阵列的结构图
cellstr 把二维字符数组转化为相应的字符串单元阵列
char 把字符串单元阵列转化相应的字符数组
7.3 结构数组
一个数组是一个数据类型,这种数组类型有一个名字,但是在这个数组中的单个元素只能通过已知的数字进行访问。数组arr中的第五个元素可由arr(5)访问。注意在这个数组中的所有元素都必须是同一类型(数字或字符)。一个单元阵列也是一种数据类型,也有一个名字,单个元素也只能通过已知的数字进行访问。但是这个单元阵列中元素的数据类型可以是不同的。相对地,一个结构也是一种数据类型,它的每一个元素都有一个名字。我们称结构中的元素为域。单个的域可以通过结构名和域名来访问,用句号隔开。
7.3.1 创建结构
创建结构有两种方法
, 用赋值语句创建
, 用函数struct函数进行创建
7.3.1.1 用赋值语句创建函数
你可以用赋值语句一次创建一个结构域。每一次把数据赋值于一个域,这个域就会被自动创建。例如用下面的语句创建如图7.6所示的结构。
>> student.name = 'John Doe';
>> student.addr1 = '123 Main Street';
>> student.city = 'Anytown';
>> student.zip = '71211'
student =
name: 'John Doe'
addr1: '123 Main Street'
city: 'Anytown'
zip: '71211'
第二个student可以通过在结构名前加上一个下标的方式加入到这个结构中。
>> student(2).name = 'Jane Q. Public'
student =
1x2 struct array with fields:
name
addr1
city
zip
Student现在是一个1×2数据。注意当一个结构数据超一个元素,只有域名,而没有它的内容。在命令窗口中独立键入每一个元素,它的内容就会被列出。
>> student(1)
ans =
name: 'John Doe'
addr1: '123 Main Street'
city: 'Anytown'
zip: '71211'
>> student(2)
ans =
name: 'Jane Q. Public'
addr1: []
city: []
zip: []
Student
name Student
addr1 123 Main Steet
city Anytown
state LA
zip 71211
图7.6一个简单的例子。结构中每一个元素被称作域,每一个域都可以通过它的名字来访问。
注意无论结构的元素什么时间被定义,结构中的所有域都会被创建,不管它是否被初始化,没有被初始化的域将包含一个空数组,在后面我们可以用赋值语句来初始化这个域。
我们可以用fieldnames函数随时对结构中的域名进行恢复。这个函数可以返回一系列字符单元阵列中的域名,这个函数对结构数组的运算是非常有用的。
7.3.1.2 用struct函数创建结构
函数struct允许用户预分配一个结构数据。它的基本形式如下
structure_array = struct(fields)
其中fields是填补结构域名的字符串数组或单元阵列。用上面的语法,函数struct用空矩阵初始化数组中的每一个域。
当域被定义时,我们就可以对它进行初始化,形式如下
str_array = struct('field1', var1, 'field2', val2, ...)
其中参数为域名和它们的值。
7.3.2 增加域到结构
如果一个新的域名在结构数组中的任意一个元素中被创建,那么这个域将会增加到数组的所有元素中去。例如,假设我们把一些成绩添加到jane public的记录中。
>> student(2).exams = [90 82 88]
student =
1x2 struct array with fields:
name
addr1
city
zip
exams
如下所示,在数组的每一个记录中都有一个exams域。这个将会在student(2)中进行初
始化,其他同学的数组为空,除非用赋值语句给他赋值。
>> student(1)
ans =
name: 'John Doe'
addr1: '123 Main Street'
city: 'Anytown'
zip: '71211'
exams: []
>> student(2)
ans =
name: 'Jane Q. Public'
addr1: []
city: []
zip: []
exams: [90 82 88]
7.3.3 删除结构中的域
我们可以用rmfield函数删除结构数据中的域。这个函数的形式如下 struct2 = rmfield(struct_array, 'field')
其中struct_array是一个结构数组,field是要去除的域,stuct2是得到的新结构的名字。
例如从结构student中去除域名zip,代码如下
>> stu2 = rmfield(student, 'zip')
stu2 =
1x2 struct array with fields:
name
addr1
city
exams
7.3.4 结构数组中数组的应用
现在我们假设结构sdudent中已经有三个学生,所有数据如图7.7所示。我们如何应用
结构数组中的数据呢,
我们可以在句号和域名后加数组元素名访问任意数组元素的信息。 >> student(2).addr1
ans =
P.O.Box 17
>> student(3).exams
ans =
65 84 81
任何带一个域的独立条目可以在域名后加下标的方式进行访问,例如,第三个学生的第
二个科目的成绩为
>> student(3).exams(2)
ans =
84
结构数组中的域能作为支持这种数组类型任意函数的参数。例如,计算student(2)的数
据平均值,我们使用这个函数
>> mean(student(2).exams)
ans =
86.6667
不幸是的,我们不能同时从多个元素中得到一个域的值。例如,语句 student.name是无意义的,并导致错误。如果我们想得到所有学生的名字,我们必须用
到一个for循环。
for ii = 1:length(student)
disp(student(ii).name);
end
student
array
student(1) student(2) student(3)
.name .name .name 'John Doe' 'Jane Q. Public' 'Big Bird'
.addr1 .addr1 .addr1 '123 Main Street' 'P.O. Box 17' '123 Scsame Street'
.city .city .city 'Anytown' 'Nowhere' 'New York'
.state .state .state 'LA' 'MS' 'NY'
.zip .zip .zip '71211' '68888' '10018'
.exams .exams .exams [80 95 84] [90 82 88] [65 84 81]
图7.7 用三个元素组成的student数组和它所有的域 相似地,如果我们想得到所有学生的平均成绩,我们不能用函数mean(student.exams),
我们必须独立的访问学生的每一个成绩,并算出总成绩。
exam_list = [];
for ii = 1:length(student)
exam_list = [exam_list student(ii).exams];
end
mean(exam_list)
7.3.5 函数getfield和函数setfield
MATLAB中有两个函数用来创建结构,这比用自定义函数创建要简单的多。函数getfield得到当前存储在域中的值,函数setfield在域中插入一新值。
getfield函数的结构是
f = getfield(array,{array_index},'field',{field_index})
field_index和array_index是可选择性,array_index用于创建1×1结构数组。调用这个函数的语句为
f = array(array_index).field(field_index);
当编写程序时,尽管程序不知道结构数组中的域名,这个语句也可以应用。例如,假设我们需要编写一个程序,读取一未知数组并对它进行操作。函数可以通过调用fieldnames命令来确定一个结构数据的域名,然后通过函数getfield读取数据。为了读取第二个学生的zip码,函数为
>> zip = getfield(student,{2},'zip')
zip =
68888
相似地,我们可以用setfield函数修改结构的值。形式如下
f = setfield(array,{array_index},'field',{field_index},value)
f是输出结构数组,field_index和array_index都是可选择性参数,array_index用于创建1×1结构数组。调用这个函数的语句为
array(array_index).field(field_index) = value;
7.3.6 对结构数组应用size函数
当size函数应用于结构数组时,它将返回这个结构数组的大小。当size函数应用于结构数组中的一个元素的域时它将返回这个域的大小。例如
>> size(student)
ans =
1 3
>> size(student(1).name)
ans =
1 8
7.3.7 结构的嵌套
结构数组的每一个域可是任意数据类型,包括单元阵列或结构数组。例如,下面的语句定义了一个新结构数组。它作为student的一个域,用来存储每一个学生所在班级的信息。
>> student(1).class(1).name = 'COSC 2021';
>> student(1).class(2).name = 'PHYS 1001';
>> student(1).class(1).instructor = 'Mr. Jones';
>> student(1).class(2).instructor = 'Mrs. Smith';
在这个语句被执行后,student(1)将由以下数据组成。注意访问嵌套结构中的数据方法。
>> student(1)
ans =
name: 'John Doe'
addr1: '123 Main Street'
city: 'Anytown'
state: 'LA'
zip: '71211'
exams: [80 95 84]
class: [1x2 struct]
>> student(1).class
ans =
1x2 struct array with fields:
name
instructor
>> student(1).class(1)
ans =
name: 'COSC 2021'
instructor: 'Mr. Jones'
>> student(1).class(2)
ans =
name: 'PHYS 1001'
instructor: 'Mrs. Smith'
>> student(1).class(2).name
ans =
PHYS 1001
7.3.8 struct函数总结
支持struct的普通函数总结在表7.3中。
表7.3 支持struct的函数 函数 描述
fieldnames 在一个字符串单元阵列中返回域名
getfield 从一个域中得到当前的值
rmfield 从一个结构中删除一个域
setfield 在一个域中设置一个新值
struct 预定义一个结构
测试7.1
本测试提供了一个快速的检查方式,看你是否掌握了本章的基本内容。如果你对本测试
有疑问,你可以重读本章,问你的老师,或和同学们一起讨论。在附录B中可以找到本测
试的答案。
1. 什么是稀疏矩阵,它和全矩阵有何区别,两者之间如何相互转化,
2. 什么是单元阵列,它和普通的数组有何区别,
3. 内容检索和单元检索有何区别,
4. 什么是结构,它与稀疏矩阵,单元阵列有什么区别,
5. varargin的功能是什么,它是如何工作的,
6. 下面给出了数组a的定义,下面的语句将会产生怎样的结果,
a{1,1} = [1 2 3; 4 5 6; 7 8 9];
a(1,2) = {'Comment line'};
a{2,1} = j;
a{2,2} = a{1,1} -a{1,1}(2,2);
(a) a(1,1) (b) a{1,1} (c) 2*a(1,1) (d) 2*a{1,1}
(e) a{2,2} (f) a(2,3) = {[-17;17]} (g) a{2,2}(2,2)
7. 下面给出了结构b的定义,下面的语句将会产生怎样的结果,
b(1).a = -2*eye(3);
b(1).b = 'Element 1';
b(1).c = [1 2 3];
b(2).a = (b(1).c' [-1; -2; -3] b(1).c');
b(2).b = 'Element 2';
b(2).c = [1 0 -1];
(a) b(1).a - b(2).a (b) strncmp(b(1).b, b(2).b,6)
(c) mean(b(1).c) (d) mean(b.c)
(e) b (f) b(1)
7.4 总结
本章重点介绍了三类数据类型:稀疏矩阵,单元阵列和结构。 7.4.1 好的编程习惯总结
当你访问一单元阵列时,不要把()与{}混淆。它们完全不同的运算。 7.4.2 MATLAB函数命令总结
普通的MATLAB稀疏矩阵函数
类别 函数 描述
speye 创建一个稀创建一个单位稀疏矩阵
sprand 疏矩阵 创建一个稀疏矩阵,元素是符合平均分布的随机数
sprandn 创建一个稀疏矩阵,元素是普通的随机数
sparse 全矩阵和稀把一个全矩阵转化为一个稀疏矩阵
full 疏矩阵的转把一个稀疏矩阵转化为全矩阵
find 换函数 找出矩阵中非零元素和它对应的上下标
nnz 对稀疏矩阵非零元素的个数
nonzeros 进行操作的返回一个向量,其中的元素为矩阵中非零元素
spones 函数 用1代替矩阵中的非零元素
spalloc 一个稀疏矩阵所占的内存空间
issparse 如果是稀疏矩阵就返回1
spfun 给矩阵中的非零元素提供函数
spy 用图象显示稀疏矩阵
普通的单元阵列函数
函数 描述
cell 对单元阵列进行预定义
celldisp 显示出单元阵列的内容
cellplot 画出单元阵列的结构图
cellstr 把二维字符数组转化为相应的字符串单元阵列 char 把字符串单元阵列转化相应的字符数组
支持struct的函数
函数 描述
fieldnames 在一个字符串单元阵列中返回域名
getfield 从一个域中得到当前的值
rmfield 从一个结构中删除一个域
setfield 在一个域中设置一个新值
struct 预定义一个结构
7.5 练习
7.1
编写一个MATLAB函数,可以接爱一个字符串单元阵列,并根据ascii码字母顺序对它进行升序排列。(如果你愿意的话,可以利用第六章的函数c_strcmp对它们进行比较。) 7.2
编写一个MATLAB函数,接受一个字符串单元阵列,并按字母表的顺序进行排序。(注意在这里不区分大小写)
7.3
创建一个100×100的稀疏矩阵,其中5%的元素是按普通分布的随机数(用sprandn产生这些值),其余为0。下一步,把数组对角线上的所有元素都设置为1。下一步,定义一个含100个元素稀疏列向量b,并用100个符合平均分布的随机数赋值于b。回答下面的问题。
a. 利用稀疏矩阵a创建一个全矩阵a_full。比较两矩阵所需的内存,那一个更高效呢,
b. 应用spy函数画出a中元素的分布
c. 利用稀疏矩阵b创建一个全矩阵b_full。比较两矩阵所需的内存,那一个更高效呢,
d. 分别用全矩阵和稀疏矩阵角方程组a*x=b中未知矩阵x的值,
7.4
创建一个函数,接受任意数目数字输入参数,计算出所有参数中单个元素的总和。用下面4个参数检测你的程序
1034,,,,,,-2-512a = 10, b = ,c = ,d = [1 5 -2]。 ,,,,,,2,,120
7.5
修改先前练习中的函数,使它既能够接受数字数组又能接受包含数字值的单元阵列。
用下面2组参数检测你的程序。
141-2,,,,a = ,b{1} = [1 5 2],和b{2} = ,,,,-2321
7.6
创建一个结构,画图的所有信息,在取最小值时,结构数据应当有下面的域
x_data x的值
y_data y的值
type 线性,对数等
plot_title 图象标题
x_label x轴标签
你也可以增加其他的域来增强你对最终图象的控制。
在结构数据被创建后,创建一个函数,它能接受包含有这个结构的数组,在这个数组中每一个结构产生一个图象。这个函数应当支持一些默认的域值。例如,如果域plot_title是一个空矩阵,那么产生的图象将无标题材。在编写程序之前,想好你的默认值。
为了检测你的函数,创建一个结构,包括创建三个不同图形的数据,并把这个结构传递给你的函数。这个函数应当正确的画出三个图形。
范文二:MATLAB编程第二版第七章(DOC X页)
第七章 稀疏矩阵 单元阵列 结构 ..................................................................................... 3 7.1 稀疏矩阵 ............................................................................................................ 3
7.1.1 sparse数据类型 .......................................................................................... 4
例7.1 ................................................................................................................. 6 7.2 单元阵列(cell array) ............................................................................................. 8
7.2.1 创建单元阵列 ............................................................................................ 9
7.2.2 单元创建者——大括号({})的应用............................................................ 10
7.2.3 查看单元阵列的内容 ............................................................................... 10
7.2.4 对单元阵列进行扩展 ................................................................................11
7.2.5 删除阵列中的元素 ................................................................................... 12
7.2.6 单元阵列数据的应用 ............................................................................... 12
7.2.7 字符串单元阵列 ...................................................................................... 12
7.2.8 单元阵列的重要性 ................................................................................... 13
7.2.9 单元阵列函数总结 ................................................................................... 16 7.3 结构数组 .......................................................................................................... 16
7.3.2 增加域到结构 .......................................................................................... 17
7.3.3 删除结构中的域 ...................................................................................... 18
7.3.4 结构数组中数组的应用 ............................................................................ 18
7.3.5 函数getfield和函数setfield...................................................................... 20
7.3.6 对结构数组应用size函数 ........................................................................ 20
7.3.8 struct函数总结 ......................................................................................... 21
测试7.1 ........................................................................................................... 21 7.4 总结 ................................................................................................................. 22
7.4.1 好的编程习惯总结 ................................................................................... 22
7.4.2 MATLAB函数命令总结 ........................................................................... 22
7.5 练习 ................................................................................................................. 23
7.1 ................................................................................................................... 23
7.2 ................................................................................................................... 23
7.3 ................................................................................................................... 23
7.4 ................................................................................................................... 23
7.5 ................................................................................................................... 24
7.6 ................................................................................................................... 24
第七章 稀疏矩阵 单元阵列 结构
在本章中我们要学习三种数据类型:稀疏矩阵,单元阵列和结构。稀疏矩阵是矩阵的一
种特殊形式,在这个矩阵中只对非零元素分配内存。单元阵列也是一种矩阵,它的每一个元
素可以是MATLAB任何一种数据类型。它们广泛应用于MATLAB用户图象界面(GUI)
函数。最后,结构提供了一种在单个变量中存储了不同类型的数据的方法,在这个变量中的
每一个数据项目都有一个独立的名字。
7.1 稀疏矩阵
我们在第二章中已经学过了普通的MATLAB数组。当一个普通的数组被声明后,
MATLAB将会为每一个数组元素分配内存。例如函数a = eye(10)要创建了100个元素,按
10×10的结构分配,对角线上的元素均为1,其余的元素为0。注意这些数组其中的90个元
素为0。这个包含有一百个元素的矩阵,只有10个元素包含非零值。这是稀疏矩阵或稀疏
数组的一个例子。稀疏矩阵是指一个很大的矩阵,且大多数的元素为0。
>> a=2*eye(10)
a =
2 0 0 0 0 0 0 0 0 0
0 2 0 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0
0 0 0 0 2 0 0 0 0 0
0 0 0 0 0 2 0 0 0 0
0 0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 2 0 0
0 0 0 0 0 0 0 0 2 0
0 0 0 0 0 0 0 0 0 2
现在假如我们要创建一个10×10的矩阵,定义如下
b =
1 0 0 0 0 0 0 0 0 0
0 2 0 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
若a,b两矩阵相乘得到的结果为
>> c = a * b
c =
2 0 0 0 0 0 0 0 0 0
0 4 0 0 0 0 0 0 0 0
0 0 4 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0
0 0 0 0 10 0 0 0 0 0
0 0 0 0 0 2 0 0 0 0
0 0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 2 0 0
0 0 0 0 0 0 0 0 2 0
0 0 0 0 0 0 0 0 0 2
这两个稀疏矩阵相乘需要1900次相加和相乘,但是在大多数时侯相加和相乘的结果为
0,所以我们做了许多的无用功。这个问题会随着矩阵大小的增大而变得非常的严重。例如,
假设我们要产生两个200×200的稀疏矩阵,如下所示
a = 5 * eye(200);
b = 3 * eye(200);
每一个矩阵有20000个元素,其中19800个元素是0。进一步说,对这两个矩阵相乘需
要7980000次加法和乘法。
我们可以看出对大规模稀疏矩阵进行存储和运算(其中大部分为0)是对内存空间和cpu
资源的极大浪费。不巧的是,在现实中的许多问题都需要稀疏矩阵,我们需要一些有效的方
示来解决这个问题。
大规模供电系统是现实世界中涉及到稀疏矩阵一个极好的例子。大规模供电系统可以包
括上千条或更多的母线,用来产生,传输,分配电能到子电站。如果我们想知道这个系统的
电压,电流和功率,我们必须首先知道每一条母线的电压。如果这个系统含有一千个母线,
这就要用到含有1000个未知数的联立方程组,包括一个方程,也就是说我们要创建含有
1000000个元素的矩阵。解出这个矩阵,需要上百万次的浮点运算。
但是,在这个系统中,一条母线平均只它的三条母线相连,而在这个矩阵中每一行其他
的996个元素将为0,所以在这个矩阵的加法和乘法运算中将会产生0。如果在求解的过程
中这些0可以忽略,那么这个电力系统的电压和电流计算将变得简单而高效。
7.1.1 sparse数据类型
在MATLAB中有一个专门的数据类型,用来对稀疏进行运算。sparse数据类型不同于
doulbe数据,它在内存中只存储非零元素。实际上,sparse数据类型只存储每一个非零元素
的三个值:元素值,元素的行号和列号。尽管非零元素这三个值必须存储在这内存,但相对
于存储稀疏矩阵的所有元素来说要简单高效得多。
我们用10×10的方阵来说明稀疏矩阵的应用。
>> a = eye(10)
a =
1 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
如果这个矩阵被转化为稀疏矩阵,它的结果是
>> as = sparse(a)
as =
(1,1) 1
(2,2) 1
(3,3) 1
(4,4) 1
(5,5) 1
(6,6) 1
(7,7) 1
(8,8) 1
(9,9) 1
(10,10) 1
注意在稀疏矩阵存储的是行列地址和这一点所对应的非零数据值。只要一个矩阵的大部分数都是0,这种方法用来存储数据就是高效的,但是如果非零元素很多的话,那么用占用更多的空间,因为稀疏矩阵需要存储蓄地址。函数issparse通常用作检测一个矩阵是否为稀疏矩阵。如果这个矩阵是稀疏的,那么这个函数将会返回1。
稀疏矩阵的优点可以通过下面的描述体现出来,考虑一个1000×1000的矩阵平均每一行只有4个非零元素。如果这个矩阵以全矩阵的形式储存,那么它要战胜8000000个字节。从另一方面说,如果它转化为一个稀疏矩阵,那么内存的使用将会迅速下降。
7.1.1.1 产生稀疏矩阵
MATLAB可以通过sparse函数把一个全矩阵转化为一个稀疏矩阵,也可以用MATLAB函数speye,sprand和sprandn直接产生稀疏矩阵,它们对应的全矩阵为eye,rand,和randn。例如,表达式a = speye(4)将产生一个4×4的稀疏矩阵。
>> a = speye(4)
a =
(1,1) 1
(2,2) 1
(3,3) 1
(4,4) 1
表达式b = full(a)把稀疏矩阵转化相应的全矩阵。
>> b = full(a)
b =
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
7.1.1.2 稀疏矩阵的运算
如果一个矩阵是稀疏的,那么单个元素可以通过简单的赋值语句添加或删除,例如下面的语句产生一个4×4的稀疏矩阵,然后把其他的非零元素加入其中。
>> a = speye(4)
a =
(1,1) 1
(2,2) 1
(3,3) 1
(4,4) 1
>> a(2,1) = -2
a =
(1,1) 1
(2,1) -2
(2,2) 1
(3,3) 1
(4,4) 1
MATLAB允许全矩阵与稀疏的混合运算。它们产生的结果可以是全矩阵也可以是稀疏矩阵,这取决于那种结果更高效。更重要的是,任何的适用全矩阵算法同样地也适合稀疏矩阵。
表7.1 列出的是一些普通的稀疏矩阵。
表7.1 普通的MATLAB稀疏矩阵函数
类别 函数 描述
speye 创建一个稀创建一个单位稀疏矩阵
sprand 疏矩阵 创建一个稀疏矩阵,元素是符合平均分布的随机数
sprandn 创建一个稀疏矩阵,元素是普通的随机数
sparse 全矩阵和稀把一个全矩阵转化为一个稀疏矩阵
full 疏矩阵的转把一个稀疏矩阵转化为全矩阵
find 换函数 找出矩阵中非零元素和它对应的上下标
nnz 对稀疏矩阵非零元素的个数
nonzeros 进行操作的返回一个向量,其中的元素为矩阵中非零元素
spones 函数 用1代替矩阵中的非零元素
spalloc 一个稀疏矩阵所占的内存空间
issparse 如果是稀疏矩阵就返回1
spfun 给矩阵中的非零元素提供函数
spy 用图象显示稀疏矩阵
例7.1
用稀疏矩阵解决联立方程组
为了解说明稀疏矩阵在MATLAB中应用,我们将用全矩阵和稀疏矩阵来解决下面的联
立方程组。
1.0x + 0.0x + 1.0x + 0.0x + 0.0x + 2.0x + 0.0x - 1.0x = 3.0 12345678
0.0x + 1.0x + 0.0x + 0.4x + 0.0x + 0.0x + 0.0x + 0.0x = 2.0 12345678
0.5x + 0.0x + 2.0x + 0.0x + 0.0x + 0.0x - 1.0x + 0.0x = -1.5 12345678
0.0x + 0.0x + 0.0x + 2.0x + 0.0x + 1.0x + 0.0x + 0.0x = 1.0 12345678
0.0x + 0.0x + 1.0x + 1.0x + 1.0x + 0.0x + 0.0x + 0.0x = -2.0 12345678
0.0x + 0.0x + 0.0x + 1.0x + 0.0x + 1.0x + 0.0x + 0.0x = 1.0 12345678
0.5x + 0.0x + 0.0x + 0.0x + 0.0x + 0.0x + 1.0x + 0.0x = 1.0 12345678
0.0x + 1.0x + 0.0x + 0.0x + 0.0x + 0.0x + 0.0x + 1.0x = 1.0 12345678
答案
为了解决这一问题,我们将创建一个方程系数的全矩阵,并用sparse函数把他转化为稀
疏矩阵。我们用两种方法解这个方程组,比较它们的结果和所需的内存。
代码如下:
% Script file: simul.m
%
% Purpose:
% This program solves a system of 8 linear equations in 8
% unknowns (a*x = b), using both full and sparse matrices.
%
% Record of revisions:
% Date Programmer Description of change % ==== ======== =============== % 10/14/98 S. J. Chapman Original code %
% Define variables:
% a --Coefficients of x (full matrix)
% as --Coefficients of x (sparse matrix)
% b --Constant coefficients (full matrix)
% bs --Constant coefficients (sparse matrix)
% x --Solution (full matrix)
% xs --Solution (sparse matrix) % Define coefficients of the equation a*x = b for % the full matrix solution.
a = [
1.0 0.0 1.0 0.0 0.0 2.0 0.0 -1.0; ...
0.0 1.0 0.0 0.4 0.0 0.0 0.0 0.0; ...
0.5 0.0 2.0 0.0 0.0 0.0 -1.0 0.0; ...
0.0 0.0 0.0 2.0 0.0 1.0 0.0 0.0; ...
0.0 0.0 1.0 1.0 1.0 0.0 0.0 0.0; ...
0.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0; ...
0.5 0.0 0.0 0.0 0.0 0.0 1.0 0.0; ...
0.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0
];
b = [ 3.0 2.0 -1.5 1.0 -2.0 1.0 1.0 1.0]'; % Define coefficients of the equation a*x = b for % the sparse matrix solution.
as = sparse(a);
bs = sparse(b);
% Solve the system both ways
disp ('Full matrix solution:');
x = a\b
disp ('Sparse matrix solution:');
xs = as\bs
% Show workspace
disp('Workspace contents after the solutions:') whos
运行这个程序,结果如下
>> simul
Full matrix solution:
x =
0.5000
2.0000
-0.5000
-0.0000
-1.5000
1.0000
0.7500
-1.0000
Sparse matrix solution:
xs =
(1,1) 0.5000
(2,1) 2.0000
(3,1) -0.5000
(5,1) -1.5000
(6,1) 1.0000
(7,1) 0.7500
(8,1) -1.0000
Workspace contents after the solutions:
Name Size Bytes Class
a 8x8 512 double array
as 8x8 276 double array (sparse)
b 8x1 64 double array
bs 8x1 104 double array (sparse)
x 8x1 64 double array
xs 8x1 92 double array (sparse)
Grand total is 115 elements using 1112 bytes
两种算法得到了相同的答案。注意用稀疏矩阵产生的结果不包含x,因为它的值为0。4
注意b的稀疏形式占的内存空间比全矩阵形式还要大。这种情况是因为稀疏矩阵除了元素值之外必须存储它的行号和列号,所以当一个矩阵的大部分元素都是非零元素,用稀疏矩阵将降低运算效率。
7.2 单元阵列(cell array)
单元阵列是MATLAB中特殊一种数组,它的元素被称为单元(cells),它可以存储其它类型的MATLAB数组。例如,一个单元阵列的一个单元可能包含一个实数数组或字符型数组,还可能是复数组(图7.1所示)。
在一个编程项目中,一个单元阵列的每一个元素都是一个指针,指向其他的数据结构,而这些数据结构可以是不同的数据类型。单元阵列为选择问题信息提供极好的方示,因为所有信息都聚集在一起,并可以通边一单个名字访问。单元阵列用大括号{}替代小括号来选择和显示单元的内容。这个不同是由于单元的内容用数据结构代替了内容。假设一单元阵列如图7.2所示。元素a(1,1)是数据结构3×3的数字数组。a(1,1)的含义为显示这个单元的内容,它是一个数据结构。
cell 1,2 cell 1,1
13-7,,,,'This is a string' 206 ,,,,051
cell 2,2 cell 2,1
[] 3+i4-5,, ,,-i103-i4
图7.1 一个单元阵列的一个单元可能包含一个实数数组或字符型数组,还可能是复数组
13-7,,,,206 ,,,,051
'This is a
text string.' a(1,1) a(1,2)
a(2,1) a(2,2) []
3+i4-5,, ,,-i103-i4
图7.2 单元阵列中的每一个元素都是指向其他数据结构的指针,指向的数据结构可能都不相
同
>> a(1,1)
ans =
[3x3 double]
相对地,a{1,1}的含义为显示这个数据结构的内容。
>> a{1,1}
ans =
1 3 -7
2 0 6
0 5 1
总起来说,标识a{1,1}反映的是数据结构a(1,1)内容,而标识a(1,1)是一个数据结构。
好的编程习惯
当你访问一单元阵列时,不要把()与{}混淆。它们完全不同的运算。
7.2.1 创建单元阵列
创建单元阵列有两种方法
, 用赋值语句
, 用函数cell创建
最简单的创建单元阵列的方法是直接把数据结构赋值于独立的单元,一次赋一个单元。但用cell函数创建将会更加地高效,所以我们用cell创建大的单元数组。 7.2.1.1 用赋值语句创建单元阵列
你可以用赋值语句把值赋于单元阵列的一个单元,一次赋一个单元。这里有两种赋值的方法,即内容索引(content indexing)和单元索引(cell indexing)。
内容索引要用到大括号{},还有它们的下标,以及单元的内容。例如下面的语句创建了
×2的单元阵列,如图7.2所示。 一个2
a{1,1} = [1 3 -7; 2 0 6; 0 5 1];
a{1,2} = 'This is a text string.';
a{2,1} = [3+4*i -5; -10*i 3-4*i];
a{2,2} = [];
索引的这种类型定义了包含在一个单元中的数据结构的内容。
单元索引把存储于单元中的数据用大括号括起来,单元的下标用普通下标标记法。例如下面的语句将创建一个2×2的单元阵列,如图7.2所示。
a(1,1) ={[1 3 -7; 2 0 6;0 5 1]};
a(1,2) = {'This is a text string.'};
a(2,1) = {[3+4*i -5; -10*i 3-4*i]};
a(2,2) = {[]};
索引的这种类型创建了包含有指定值的一个数据结构,并把这个数据结构赋于一个单元。
这两种形式是完全等价的,你可以在你的程序任选其一。
常见编程错误
不要创建一个与已存在的数字数组重名的元阵列。如果得名了,MATLAB会认为你把单元阵列的内容赋值给一个普通的数组,这将会产生一个错误信息。在创建单元阵列之前,确保同名的数字数字数组已经被删除。
7.2.1.2 用cell函数创建单元阵列
函数cell允许用户创建空单元阵列,并指定阵列的大小。例如,下面的语句创建一个2×2的空单元阵列。
a = cell(2, 2)
一旦单元阵列被创立,你就可以用赋值语句对单元阵列进行赋值。
7.2.2 单元创建者——大括号({})的应用
如果在单个大括号中列出所有单元的内容,那么就定义了许多的单元,在一行中的独立单元用逗号分开,行与行之间用分号隔开。例如下面的语句创建一个2×3单元阵列。
b = {[1 2], 17, [2;4]; 3-4*i, 'Hello', eye(3)}
7.2.3 查看单元阵列的内容
MATLAB可以把单元阵列每一个元素的数据结构缩合在一行中显示出来。如果全部的数据结构没有被显示出来,那么显示就是一个总结。例如,单元阵列a和b显示如下
>> a
a =
[3x3 double] [1x22 char]
[2x2 double] []
>> b
b =
[1x2 double] [ 17] [2x1 double]
[3.0000- 4.0000i] 'Hello' [3x3 double]
注意MATLAB显示的只是数据结构,包括中括号和省略号,而不包含数据结构的内容。
如果你想要知道看到单元阵列的所有内容,要用到celldisp函数。这个函数显示的是每一个单元中的数据结构的内容。
>> celldisp(a)
a{1,1} =
1 3 -7
2 0 6
0 5 1
a{2,1} =
3.0000 + 4.0000i -5.0000
0 -10.0000i 3.0000 - 4.0000i
a{1,2} =
This is a text string.
a{2,2} =
[]
如果要用高质量的图象显示数据结构的内容,要用到函数cellplot。例如,函数cellplot(b)产生了一个图象,如图7.3所示。
图7.3 用函数cellplot显示单元阵列b数据结构的内容
7.2.4 对单元阵列进行扩展
一个值赋值于一个单元阵列中的元素,如果这个元素现在不存在,那么这个元素就会被自动的建立,其他所需的元素也会被自动建立。例如,假设定义了一个2×2单元阵列,如图7.1所示。如果我们执行下面的语句
a{3, 3} = 5
单元阵列将会自动扩展为3×3单元阵列,如图7.4所示。
cell 1,1 cell 1,2 cell 1,3
13-7,,'This is a ,,[] 205 text string.' ,,,,051
cell 2,1 cell 2,2 cell 2,3
3+i4-5,, [] [] ,,-i103-i4
cell 3,1 cell 3,2 cell 3,3
[5] [] []
图7.4把一个值赋值于a(3,3)产生的结果。注意其他的空元素也是自动创建的。
7.2.5 删除阵列中的元素
如果要删除阵列中的所有元素,我们要用clear命令。如果要删除单元阵列中的部分元素,我们把空值赋值于这一部分元素。例如,假设a的定义如下
>> a
a =
[3x3 double] [1x22 char] []
[2x2 double] [] []
[] [] [5]
我们可以用下面的语句删除第三行
>> a(3,:)=[]
a =
[3x3 double] [1x22 char] []
[2x2 double] [] [] 7.2.6 单元阵列数据的应用
在一个单元阵列中,数据结构中数据可以随时用内容索引或单元索引调用。
例如假设单元阵列c的定义如下
c = {[1 2; 3 4],'dogs';'cats',i}
存储于c(1,1)的内容可由下面的语句调用
>> c{1,1}
ans =
1 2
3 4
同样c(2,1)中的元素可由下面的元素调用
>> c{2,1}
ans =
cats
一个单元内容的子集可由两套下标得到。例如,假设我们要得到单元c(1,1)中的元素(1,2)。为了达到此目的,我们可以用表达式c{1,1}(1,2),它代表单元c(1,1)中的元素(1,2)。
>> c{1,1}(1,2)
ans =
2
7.2.7 字符串单元阵列
在一个单元阵列中存储一批字符串与在标准的字符数组中存储相比是非常方便的,因为在单元阵列中每一个字符串的长度可以是不相同的,而在标准字符数组的每一行的长度都必须相等。这就意味着在单元阵列中的字符串没的必要增加多余的空格。许多的MATLAB用户图形界面函数均使用单元阵列,正是基于这个原因,我们将在第十章看到。
字符串单元阵列可以由两种方法创建。我们可以用方括号把独立的字符串插入到单元阵列,我们也可以函数cellstr把一个二维字符数组转化为相应的字符串单元阵列。
下面的例子用第一种方法创建了一个字符串单元阵列,并显示出这个阵列的结果。注意下面的每一个字符串具有不同的长度。
>> cellstring{1} = 'Stephen J. Chapman';
>> cellstring{2} = 'Male';
>> cellstring{3} = 'SSN 999-99-9999';
>> cellstring
cellstring =
'Stephen J. Chapman' 'Male' 'SSN 999-99-9999'
我们可以利用函数cellstr把一个二维字符数据转化为相应的字符串单元阵列。考虑下面的字符数组。
>> data = ['Line 1 ';'Additional Line']
data =
Line 1
Additional Line
相应的字符串单元阵列为
>> c = cellstr(data)
c =
'Line 1'
'Additional Line'
我们还可以用char函数它转化回去
>> newdata = char(c)
newdata =
Line 1
Additional Line
7.2.8 单元阵列的重要性
单元阵列是非常灵活的,因为各种类型的大量数据可以存储在每一个单元中。所以,它经常当作中间MATLAB数据结构来用。我们必须理解它,因为在第十章中MATLAB图形用户界面要用到它的许多特性。
还有,单元阵列的灵活性可能使它们具有函数普通特性,这个函数是指带有输入参数和输出参数的变量个数的函数。一种特别的输入参数varargin可以在自定义函数中得到,这种函数支持输入参数的变量的个数。这个参数显在输入参数列表的最后一项,它返回一个单元阵列,所以一个输入实参可以包括任意数目的实参。每一个实参都变成了由varagin返回的单元阵列元素。如果它被应用,varagin必须是函数中的最后一个输入参数。
例如,假设我们要编写一个函数,它可能需要任意个数的输入参数。这个函数执行如下所示
function test1(varargin)
disp(['There are ' int2str(nargin) ' arguments.']);
disp('The input arguments are:');
disp(varargin);
我们用不同的数目参数来执行这个函数,结果如下
>> test1
There are 0 arguments.
The input arguments are:
>> test1(6)
There are 1 arguments.
The input arguments are:
[6]
>> test1(1,'test 1',[1 2,3 4])
There are 3 arguments.
The input arguments are:
[1] 'test 1' [1x4 double]
正如我们所看到的,参数变成了函数中的单元阵列元素。
下面是一个简单函数例子,这个函数拥有不同的参数数目。函数plotline任意数目的1×2行向量,每一个向量包含一个点(x,y)。函数把这些点连成线。注意这个函数也接受直线类型字符串,并把这些字符串转递给plot的函数。
function plotline(varargin)
%PLOTLINE Plot points specified by [x,y] pairs. % Function PLOTLINE accepts an arbitrary number of % [x,y] points and plots a line connecting them. % In addition, it can accept a line specification % string, and pass that string on to function plot. % Define variables:
% ii --Index variable
% jj --Index variable
% linespec --String defining plot characteristics
% msg --Error message
% varargin --Cell array containing input arguments
% x --x values to plot
% y --y values to plot
% Record of revisions:
% Date Programmer Description of change % ==== ========= ===================== % 10/20/98 S. J. Chapman Original code % Check for a legal number of input arguments. % We need at least 2 points to plot a line... msg = nargchk(2,Inf,nargin);
error(msg);
% Initialize values
jj = 0;
linespec = '';
% Get the x and y values, making sure to save the line % specification string, if one exists.
for ii = 1:nargin
% Is this argument an [x,y] pair or the line
% specification?
if ischar(varargin{ii})
% Save line specification
linespec = varargin{ii};
else
% This is an [x,y] pair. Recover the values.
jj = jj + 1;
x(jj) = varargin{ii}(1);
y(jj) = varargin{ii}(2);
end
end
% Plot function.
if isempty(linespec)
plot(x,y);
else
plot(x,y,linespec);
end
我们用下面的参数调用这个函数,产生的图象如图7.5所示。用相同的数目的参数调用
函数,看它产生的结果为什么,
也有专门的输出参数,vargout,它支持不同数目的输出参数。这个参数显示在输出参数
列表的最后一项。它返回一个单无阵列,所示单个输出实参支持任意数目的实参。每一个实
参都是这个单无阵列的元素,存储在varargout。如果它被应用,varargout必须是输出参数
列表中最后一项,在其它输入参数之后。存储在varargout中的变量数由函数nargout确定,
这个函数用指定于任何一个已知函数的输出实参。例如,我们要编写一函数,它返回任意数
目的随机数。我们的函数可以用函数nargout指定输出函数的数目,并把这些数目存储在单
元阵列varargout中。
图7.5 函数plotline产生的图象
function [nvals, varargout] = test2(mult) % nvals is the number of random values returned
% varargout contains the random values returned
nvals = nargout - 1;
for ii = 1:nargout-1
varargout{ii} =randn * mult; end
当这个函数被执行时,产生的结果如下
>> test2(4)
ans =
-1
>> [a b c d] = test2(4)
a =
3
b =
-1.7303
c =
-6.6623
d =
0.5013
好的编程习惯
应用单元阵列varargin和varargout创建函数,这个函数支持不同数目的输入或输出参
数。
7.2.9 单元阵列函数总结
支持单元阵列的一些普通函数总结在表7.2中。
表7.2普通的单元阵列函数
函数 描述
cell 对单元阵列进行预定义
celldisp 显示出单元阵列的内容
cellplot 画出单元阵列的结构图
cellstr 把二维字符数组转化为相应的字符串单元阵列
char 把字符串单元阵列转化相应的字符数组
7.3 结构数组
一个数组是一个数据类型,这种数组类型有一个名字,但是在这个数组中的单个元素只能通过已知的数字进行访问。数组arr中的第五个元素可由arr(5)访问。注意在这个数组中的所有元素都必须是同一类型(数字或字符)。一个单元阵列也是一种数据类型,也有一个名字,单个元素也只能通过已知的数字进行访问。但是这个单元阵列中元素的数据类型可以是不同的。相对地,一个结构也是一种数据类型,它的每一个元素都有一个名字。我们称结构中的元素为域。单个的域可以通过结构名和域名来访问,用句号隔开。
7.3.1 创建结构
创建结构有两种方法
, 用赋值语句创建
, 用函数struct函数进行创建
7.3.1.1 用赋值语句创建函数
你可以用赋值语句一次创建一个结构域。每一次把数据赋值于一个域,这个域就会被自动创建。例如用下面的语句创建如图7.6所示的结构。
>> student.name = 'John Doe';
>> student.addr1 = '123 Main Street';
>> student.city = 'Anytown';
>> student.zip = '71211'
student =
name: 'John Doe'
addr1: '123 Main Street'
city: 'Anytown'
zip: '71211'
第二个student可以通过在结构名前加上一个下标的方式加入到这个结构中。
>> student(2).name = 'Jane Q. Public'
student =
1x2 struct array with fields:
name
addr1
city
zip
Student现在是一个1×2数据。注意当一个结构数据超一个元素,只有域名,而没有它的内容。在命令窗口中独立键入每一个元素,它的内容就会被列出。
>> student(1)
ans =
name: 'John Doe'
addr1: '123 Main Street'
city: 'Anytown'
zip: '71211'
>> student(2)
ans =
name: 'Jane Q. Public'
addr1: []
city: []
zip: []
Student
name Student
addr1 123 Main Steet
city Anytown
state LA
zip 71211
图7.6一个简单的例子。结构中每一个元素被称作域,每一个域都可以通过它的名字来访问。
注意无论结构的元素什么时间被定义,结构中的所有域都会被创建,不管它是否被初始化,没有被初始化的域将包含一个空数组,在后面我们可以用赋值语句来初始化这个域。
我们可以用fieldnames函数随时对结构中的域名进行恢复。这个函数可以返回一系列字符单元阵列中的域名,这个函数对结构数组的运算是非常有用的。
7.3.1.2 用struct函数创建结构
函数struct允许用户预分配一个结构数据。它的基本形式如下
structure_array = struct(fields)
其中fields是填补结构域名的字符串数组或单元阵列。用上面的语法,函数struct用空矩阵初始化数组中的每一个域。
当域被定义时,我们就可以对它进行初始化,形式如下
str_array = struct('field1', var1, 'field2', val2, ...)
其中参数为域名和它们的值。
7.3.2 增加域到结构
如果一个新的域名在结构数组中的任意一个元素中被创建,那么这个域将会增加到数组的所有元素中去。例如,假设我们把一些成绩添加到jane public的记录中。
>> student(2).exams = [90 82 88]
student =
1x2 struct array with fields:
name
addr1
city
zip
exams
如下所示,在数组的每一个记录中都有一个exams域。这个将会在student(2)中进行初
始化,其他同学的数组为空,除非用赋值语句给他赋值。 >> student(1)
ans =
name: 'John Doe'
addr1: '123 Main Street'
city: 'Anytown'
zip: '71211'
exams: []
>> student(2)
ans =
name: 'Jane Q. Public'
addr1: []
city: []
zip: []
exams: [90 82 88]
7.3.3 删除结构中的域
我们可以用rmfield函数删除结构数据中的域。这个函数的形式如下 struct2 = rmfield(struct_array, 'field')
其中struct_array是一个结构数组,field是要去除的域,stuct2是得到的新结构的名字。
例如从结构student中去除域名zip,代码如下
>> stu2 = rmfield(student, 'zip')
stu2 =
1x2 struct array with fields:
name
addr1
city
exams
7.3.4 结构数组中数组的应用
现在我们假设结构sdudent中已经有三个学生,所有数据如图7.7所示。我们如何应用
结构数组中的数据呢,
我们可以在句号和域名后加数组元素名访问任意数组元素的信息。 >> student(2).addr1
ans =
P.O.Box 17
>> student(3).exams
ans =
65 84 81
任何带一个域的独立条目可以在域名后加下标的方式进行访问,例如,第三个学生的第
二个科目的成绩为
>> student(3).exams(2)
ans =
84
结构数组中的域能作为支持这种数组类型任意函数的参数。例如,计算student(2)的数
据平均值,我们使用这个函数
>> mean(student(2).exams)
ans =
86.6667
不幸是的,我们不能同时从多个元素中得到一个域的值。例如,语句 student.name是无意义的,并导致错误。如果我们想得到所有学生的名字,我们必须用
到一个for循环。
for ii = 1:length(student)
disp(student(ii).name);
end
student
array
student(1) student(2) student(3)
.name .name .name 'John Doe' 'Jane Q. Public' 'Big Bird'
.addr1 .addr1 .addr1 '123 Main Street' 'P.O. Box 17' '123 Scsame Street'
.city .city .city 'Anytown' 'Nowhere' 'New York'
.state .state .state 'LA' 'MS' 'NY'
.zip .zip .zip '71211' '68888' '10018'
.exams .exams .exams [80 95 84] [90 82 88] [65 84 81]
图7.7 用三个元素组成的student数组和它所有的域 相似地,如果我们想得到所有学生的平均成绩,我们不能用函数mean(student.exams),
我们必须独立的访问学生的每一个成绩,并算出总成绩。
exam_list = [];
for ii = 1:length(student)
exam_list = [exam_list student(ii).exams];
end
mean(exam_list)
7.3.5 函数getfield和函数setfield
MATLAB中有两个函数用来创建结构,这比用自定义函数创建要简单的多。函数getfield得到当前存储在域中的值,函数setfield在域中插入一新值。
getfield函数的结构是
f = getfield(array,{array_index},'field',{field_index})
field_index和array_index是可选择性,array_index用于创建1×1结构数组。调用这个函数的语句为
f = array(array_index).field(field_index);
当编写程序时,尽管程序不知道结构数组中的域名,这个语句也可以应用。例如,假设我们需要编写一个程序,读取一未知数组并对它进行操作。函数可以通过调用fieldnames命令来确定一个结构数据的域名,然后通过函数getfield读取数据。为了读取第二个学生的zip码,函数为
>> zip = getfield(student,{2},'zip')
zip =
68888
相似地,我们可以用setfield函数修改结构的值。形式如下
f = setfield(array,{array_index},'field',{field_index},value)
f是输出结构数组,field_index和array_index都是可选择性参数,array_index用于创建1×1结构数组。调用这个函数的语句为
array(array_index).field(field_index) = value;
7.3.6 对结构数组应用size函数
当size函数应用于结构数组时,它将返回这个结构数组的大小。当size函数应用于结构数组中的一个元素的域时它将返回这个域的大小。例如
>> size(student)
ans =
1 3
>> size(student(1).name)
ans =
1 8
7.3.7 结构的嵌套
结构数组的每一个域可是任意数据类型,包括单元阵列或结构数组。例如,下面的语句定义了一个新结构数组。它作为student的一个域,用来存储每一个学生所在班级的信息。
>> student(1).class(1).name = 'COSC 2021';
>> student(1).class(2).name = 'PHYS 1001';
>> student(1).class(1).instructor = 'Mr. Jones';
>> student(1).class(2).instructor = 'Mrs. Smith';
在这个语句被执行后,student(1)将由以下数据组成。注意访问嵌套结构中的数据方法。
>> student(1)
ans =
name: 'John Doe'
addr1: '123 Main Street'
city: 'Anytown'
state: 'LA'
zip: '71211'
exams: [80 95 84]
class: [1x2 struct]
>> student(1).class
ans =
1x2 struct array with fields:
name
instructor
>> student(1).class(1)
ans =
name: 'COSC 2021'
instructor: 'Mr. Jones'
>> student(1).class(2)
ans =
name: 'PHYS 1001'
instructor: 'Mrs. Smith'
>> student(1).class(2).name
ans =
PHYS 1001
7.3.8 struct函数总结
支持struct的普通函数总结在表7.3中。
表7.3 支持struct的函数 函数 描述
fieldnames 在一个字符串单元阵列中返回域名
getfield 从一个域中得到当前的值
rmfield 从一个结构中删除一个域
setfield 在一个域中设置一个新值
struct 预定义一个结构
测试7.1
本测试提供了一个快速的检查方式,看你是否掌握了本章的基本内容。如果你对本测试
有疑问,你可以重读本章,问你的老师,或和同学们一起讨论。在附录B中可以找到本测
试的答案。
1. 什么是稀疏矩阵,它和全矩阵有何区别,两者之间如何相互转化,
2. 什么是单元阵列,它和普通的数组有何区别,
3. 内容检索和单元检索有何区别,
4. 什么是结构,它与稀疏矩阵,单元阵列有什么区别,
5. varargin的功能是什么,它是如何工作的,
6. 下面给出了数组a的定义,下面的语句将会产生怎样的结果,
a{1,1} = [1 2 3; 4 5 6; 7 8 9];
a(1,2) = {'Comment line'};
a{2,1} = j;
a{2,2} = a{1,1} -a{1,1}(2,2);
(a) a(1,1) (b) a{1,1} (c) 2*a(1,1) (d) 2*a{1,1}
(e) a{2,2} (f) a(2,3) = {[-17;17]} (g) a{2,2}(2,2)
7. 下面给出了结构b的定义,下面的语句将会产生怎样的结果,
b(1).a = -2*eye(3);
b(1).b = 'Element 1';
b(1).c = [1 2 3];
b(2).a = (b(1).c' [-1; -2; -3] b(1).c');
b(2).b = 'Element 2';
b(2).c = [1 0 -1];
(a) b(1).a - b(2).a (b) strncmp(b(1).b, b(2).b,6)
(c) mean(b(1).c) (d) mean(b.c)
(e) b (f) b(1)
7.4 总结
本章重点介绍了三类数据类型:稀疏矩阵,单元阵列和结构。 7.4.1 好的编程习惯总结
当你访问一单元阵列时,不要把()与{}混淆。它们完全不同的运算。 7.4.2 MATLAB函数命令总结
普通的MATLAB稀疏矩阵函数
类别 函数 描述
speye 创建一个稀创建一个单位稀疏矩阵
sprand 疏矩阵 创建一个稀疏矩阵,元素是符合平均分布的随机数
sprandn 创建一个稀疏矩阵,元素是普通的随机数
sparse 全矩阵和稀把一个全矩阵转化为一个稀疏矩阵
full 疏矩阵的转把一个稀疏矩阵转化为全矩阵
find 换函数 找出矩阵中非零元素和它对应的上下标
nnz 对稀疏矩阵非零元素的个数
nonzeros 进行操作的返回一个向量,其中的元素为矩阵中非零元素
spones 函数 用1代替矩阵中的非零元素
spalloc 一个稀疏矩阵所占的内存空间
issparse 如果是稀疏矩阵就返回1
spfun 给矩阵中的非零元素提供函数
spy 用图象显示稀疏矩阵
普通的单元阵列函数
函数 描述
cell 对单元阵列进行预定义
celldisp 显示出单元阵列的内容
cellplot 画出单元阵列的结构图
cellstr 把二维字符数组转化为相应的字符串单元阵列 char 把字符串单元阵列转化相应的字符数组
支持struct的函数
函数 描述
fieldnames 在一个字符串单元阵列中返回域名
getfield 从一个域中得到当前的值
rmfield 从一个结构中删除一个域
setfield 在一个域中设置一个新值
struct 预定义一个结构
7.5 练习
7.1
编写一个MATLAB函数,可以接爱一个字符串单元阵列,并根据ascii码字母顺序对它进行升序排列。(如果你愿意的话,可以利用第六章的函数c_strcmp对它们进行比较。) 7.2
编写一个MATLAB函数,接受一个字符串单元阵列,并按字母表的顺序进行排序。(注意在这里不区分大小写)
7.3
创建一个100×100的稀疏矩阵,其中5%的元素是按普通分布的随机数(用sprandn产生这些值),其余为0。下一步,把数组对角线上的所有元素都设置为1。下一步,定义一个含100个元素稀疏列向量b,并用100个符合平均分布的随机数赋值于b。回答下面的问题。
a. 利用稀疏矩阵a创建一个全矩阵a_full。比较两矩阵所需的内存,那一个更高效呢,
b. 应用spy函数画出a中元素的分布
c. 利用稀疏矩阵b创建一个全矩阵b_full。比较两矩阵所需的内存,那一个更高效呢,
d. 分别用全矩阵和稀疏矩阵角方程组a*x=b中未知矩阵x的值,
7.4
创建一个函数,接受任意数目数字输入参数,计算出所有参数中单个元素的总和。用下面4个参数检测你的程序
1034,,,,,,a = 10, b =-2 ,c = -512 ,d = [1 5 -2]。 ,,,,,,2,,120
7.5
修改先前练习中的函数,使它既能够接受数字数组又能接受包含数字值的单元阵列。
用下面2组参数检测你的程序。
141-2,,,,a = ,b{1} = [1 5 2],和b{2} = ,,,,-2321
7.6
创建一个结构,画图的所有信息,在取最小值时,结构数据应当有下面的域
x_data x的值
y_data y的值
type 线性,对数等
plot_title 图象标题
x_label x轴标签
你也可以增加其他的域来增强你对最终图象的控制。
在结构数据被创建后,创建一个函数,它能接受包含有这个结构的数组,在这个数组中每一个结构产生一个图象。这个函数应当支持一些默认的域值。例如,如果域plot_title是一个空矩阵,那么产生的图象将无标题材。在编写程序之前,想好你的默认值。
为了检测你的函数,创建一个结构,包括创建三个不同图形的数据,并把这个结构传递给你的函数。这个函数应当正确的画出三个图形。
范文三:测量学(第二版)第七章
测量学第七章作业 P110
1. 小区域测量平面控制网和高程控制网各有哪几种布设形式?各在什么条件下采用?
小区域测量平面控制网一般布设形式有小三角、导线网和GPS 网。在视野开阔而不便量距的山区或丘陵宜布设小三角;当测区视野开阔,土质坚实,相邻点间通视,边长大致相当,可以选择减少点时可以选择导线网布设;当精度要求高时可布设GPS 网。
小区域测量高程控制网布设形式有水准网和三角高程网。当地势较平坦时可选择水准网布设;当地面高低起伏较大,水准测量困难大且慢时,可考虑布设三角高程网。
2. 导线测量外业踏勘选点时应注意哪些问题?
导线测量外业踏勘选点时应注意以下几点:
(1) 相邻点间要通视良好,地势较平坦,便与测量。
(2) 点位应选在土质坚实处,便于保存标志和安置仪器。
(3) 视野应开阔,便于施测碎部。
(4) 导线各边的长度应尽量接近表7-4中的技术指标的平均边长。
(5) 导线点应有足够的密度,分布较均匀,便于控制整个测区。
(6)
3. 经纬仪交会法有哪几种形式?什么叫危险圆?
经纬仪交会法分前方交会、侧方交会和后方交会
三种形式。
对于后方交会,如果被测点P 恰好位于由三个已
知点A 、B 、C 所决定的圆周上时,如图7-12所示,
则P 点的坐标将无法解算出(因在这个圆周上的任意
一点与这三个一直点构成的水平角,即圆周角都等于
α、β),因此这个圆被称为危险圆。
4. 导线的布设形式有哪几种?它们各用在什么情况下?
导线布设形式有:闭合导线、附合导线和支导线。闭合导线适用于面积较宽阔的独立地区作测图控制,由于闭合导线本身具有严密的检核条件,通常用于测区的首级控制;附合导线适用于带状地区的测图控制,此外也广泛用于公路、铁路、管道、河道等工程的勘测与施工控制点的建立,附合导线也具有检核条件,通常用于加密控制;支导线由于自身缺乏检核条件,故其边数一般不得超过四条,它仅适用于图根控制加密。
8. 闭合导线12341的已知数据有X 1=4032.20m ,Y1=4537.16m , α12 = 95°58′00″;观测数据为β1 =125°52′14″,β2 = 82°46′25″,β3 = 91°08′28″,β4 = 60°13′52″,D 12 =100.28m,D 23 =78.95m,D34 = 137.23m,D41 = 78.97m。试列表计算2、3、4点的坐标(不需顾及全长相对闭合差的容许值)。
参考书上例题
9. 试根据图7-14中的已知数据和观测数据,列表计算符合导线中1、2两点的坐标。
注:题目坐标数据有误
范文四:力学第二版第七章答案
第七章基本知识小结
⒈刚体的质心
定义:∑??==dm dm r r m
r m r c i i c
//
求质心方法:对称分析法,分割法,积分法。 ⒉刚体对轴的转动惯量
定义:∑?==dm r I r m I
i
i 22
平行轴定理 I o = Ic +md2 正交轴定理 I z = Ix +Iy. 常见刚体的转动惯量:(略) ⒊刚体的动量和质心运动定理
∑==c
c a m F v m p
⒋刚体对轴的角动量和转动定理
∑==βτω
I I L
⒌刚体的转动动能和重力势能
c p k mgy E I E ==2
1ω
⒍刚体的平面运动 =随质心坐标系的平动 +绕质心坐标系的转动
动力学方程:
∑∑==c
c c
c
I a m F βτ
(不必考虑惯性力矩)
动能:2
2
2
2
c
c c k
I mv E ω+=
⒎刚体的平衡方程
∑=0F
, 对任意轴
∑=0τ
7.1.2 汽车发动机的转速在 12s 内由 1200rev/min增加到 3000rev/min.⑴假设 转动是匀加速转动,求角加速度。⑵在此时间内,发动机转了多少转?
解:⑴ 260
/2) 12003000(/7. 15s rad ===
-?πωβ ⑵ rad
2) 60/2)(12003000(1039. 262
222
02?==
=
?--πωωθ
对应的转数 =420
10214. 322≈?=?
7.1.3 某发动机飞轮在时间间隔 t 内的角位移为
) :, :(43s t rad ct bt at θθ-+=。求 t 时刻的角速度和角加速度。
解:23
212643ct bt ct bt a d d -==-+==
ω
θ
βω
7.1.4 半径为 0.1m 的圆盘在铅直平面内转动,在圆盘平面内建立 o-xy 坐 标系,原点在轴上, x 和 y 轴沿水平和铅直向上的方向。边缘上一点 A 当 t=0时恰好在 x 轴上,该点的角坐标满足 θ=1.2t+t2 (θ:rad,t:s)。⑴ t=0时,⑵自 t=0
开始转 45o时,⑶转过 90o时, A 点的速度和加速度在 x 和 y 轴上的投影。 y
解:0. 222. 1==+==
dt dt
t
βω
⑴ t=0时, s m R v v y x /12. 01. 02. 10, 2. 1=?====ωω
2
222
/2. 01. 00. 2/144. 01. 0/12. 0/s
m R a a s m R v a a y y n x =?===-=-=-=-=βτ
⑵ θ=π/4时 , 由 θ=1.2t+t2, 求得 t=0.47s,∴ ω=1.2+2t=2.14rad/s
s
m R v s m R v y x /15. 02/21. 014. 245sin /15. 02/21. 014. 245cos =??=?=-=??-=?-=ωω
2
222
222
22
222/182. 0) 14. 20. 2(1. 0)
(45sin 45sin 45sin /465. 0) 14. 20. 2(1. 0) (45cos 45cos 45cos s m R R R a s
m R R R a y x -=-?
=-?=?-?=-=+?-=+?-=?-?-=ωβωβωβωβ
⑶ θ=π/2时 , 由 θ=1.2t+t2, 求得 t=0.7895s,ω=1.2+2t=2.78rad/s
2
2
2
2/77. 01. 078. 2/2. 01. 00. 20/278. 01. 078. 2s
m R a s m R a v s m R v y x y x -=?-=-=-=?-=-==-=?-=-=ωβω
7.1.5 钢制炉门由两个各长 1.5m 的平行臂 AB 和 CD 支承,以角速率 ω=10rad/s逆时针转
动,求臂与铅直成 45o时门中心 G 的速度和加 B 速度。
解:因炉门在铅直面内作平动,所以门中 G 心 G 的速度、加速度与 B 点或 D 点相同,而 B 、 D 两点作匀速圆周运动 , 因此
s m AB v v B G /155. 110=?===ω,方向指向右下方,与水平方
向成 45o;
222/1505. 110s m AB a a B G =?===ω,方向指向右上方,与
水平方向成 45o
7.1.6 收割机拨禾轮上面通常装 4到 6个压板,拨禾轮一边旋转,一边随收割 机前进。压板转到下方才发挥作用,一方
面把农作物压向切割器,一方面把切下来 的作物铺放在收割台上,因此要求压板运
动到下方时相对于作物的速度与收割机前进方向相反。
已知收割机前进速率为 1.2m/s,拨禾轮直径 1.5m ,转速 22rev/min,求压板 运动到最低点挤压作物的速度。
解:拨禾轮的运动是平面运动, 其上任一点的速度等于拨禾轮轮心 C 随收 割机前进的平动速度加上拨禾轮绕轮心转动的速度。压板运动到最低点时,其 转动速度方向与收割机前进速度方向相反,压板相对地面(即农作物)的速度
s m R v v c /53. 02. 125
. 160222-=?-=-=?πω
负号表示压板挤压作物的速度方向与收割机前进方向相反。
7.1.7飞机沿水平方向飞行,螺旋桨尖端所在半径为 150cm ,发动机转速 2000rev/min. ⑴桨尖相对于飞机的线速率等于多少?⑵若飞机以 250km/h的速 率飞行,计算桨尖相对地面速度的大小,并定性说明桨尖的轨迹。
解:⑴桨尖相对飞机的速度:
s m r v /3145. 1' 60
=?=
=ω
⑵桨尖相对地面的速度:机地 v v v
+=' ,飞机相对地面的速度与螺旋桨
相对飞机的速度总是垂直的, s m v /4. 69102503==
?机地
所以, s m v v v
/6. 3214. 69314' 222
2≈+=+=机地
显然,桨尖相对地面的运动轨迹为螺旋线
7.1.8桑塔纳汽车时速为 166km/h,车轮滚动半径为 0.26m ,发动机转速与 驱动轮转速比为 0.909, 问发动机转速为每分多少转?
解:设车轮半径为 R=0.26m,发动机转速为 n 1, 驱动轮转速为 n 2, 汽车速 度 为 v=166km/h。 显 然 , 汽 车 前 进 的 速 度 就 是 驱 动 轮 边 缘 的 线 速 度 ,
909. 0/2212Rn Rn v ππ==,所以:
min /1054. 1/1024. 93410
166909. 0909. 013
rev h rev n v ?=?===??
7.2.2 在下面两种情况下求直圆锥体的总质量和质心位置。⑴圆锥体为匀 质;⑵密度为 h 的函数:ρ=ρ0(1-h/L) , ρ0为正常数。
解:建立图示坐标 o-x, 据对称性分析, 质心必在 x 轴上 , 在 x 坐标处取一厚为 dx o
的质元
dm=ρπr 2
dx ,∵ r/a=x/L, r=ax/L
∴ dm=ρ
πa 2x 2dx/L2 ⑴圆锥体为匀质,即 ρ为常数, 总质量:L a dx x dm m
L
L
a 210
22
ρπ
ρπ==
=?
? 质心:L dx x x L
L L a L dx x a dm
xdm c 4
3
3//3
22
3
2===?=?
ρπρπ
⑵ x x
L h 0
) 1(1(00ρρρρ=
-=-=-
总质量:??
==
=L a dx x dm m
L
L a 2
010
332
0πρπρ 质心:?
==??=L
L dm
xdm c L dx x x 0
4
44
7.2.3 长度为 L 的匀质杆,令其竖直地立于光滑的桌面上,然后放开手, 由于杆不可能绝对沿铅直方向,故随即到下。求杆子的上端点运动的轨迹(选 定坐标系,并求出轨迹的方程式) 。
解:设杆在 o-xy 平面内运动。因杆 在运动过程中,只受竖直向上的支承力和 竖直向下的重力的作用,在水平方向不受 外力作用,∴ v cx =0,acx =0,即质心 C 无水
平方向的移动,只能逆着 y 轴作加速直线
运动,直到倒在桌面上。 o x
取杆的上端点的坐标为 x,y ,匀质杆的质心在其几何中心,由图示的任一
瞬间的几何关系可知:4x 2+y2=L2(x≥ 0,y ≥ 0)
7.3.1 ⑴用积分法证明:质量为 m 常为 l 的匀质细杆对通过中心且与杆垂
直的轴线的转动惯量等于 2
12ml ;⑵用积分法证明:质量为 m 半径为 R 的匀
质薄圆盘对通过中心且在盘面内的轴线的转动惯量等于
24
mR
证明:⑴取图示坐标,在坐标 x 处取一线元, dx dm l
m =,它对 y 轴的
转动惯量为:dx x dI
m 2=
,
整个细杆对 y 轴的转动惯量:
2121
8832/2/332
/2
/2(|3
3ml x dx x I l l l
m l l l
m
l l l
m
=+==
=
--?
⑵在坐标 x 处取细杆状质元,
dx x R dx x R dm R R 22222
22-=-?=ππ
它对 x 轴的转动惯量:
dx x R x R dm x R dm dI R 2/322322322212) () () 2(2
-=
-=-=π
整个圆盘对 x 轴的转动惯量:?
--=
R
R
R dx x R I
2/3223) (2
π 为了能求出积分,作如下变换:θθθd R dx R x sin , cos -==
θθθ332/3222/32222/322sin ) sin () cos () (R R R R x R ==-=-
x
代入上式:??=
-=
π
π
πθθθθθ0
4
320
33
32sin ) sin (sin 2
2
d d R R
I mR R m
据三角函数公式:2
2cos 1cos , 22cos 1sin 22
θ
θθθ+=-=
) 4cos 2cos 2() 2cos 21() 2cos 2cos 21() (sin 2
242424
222cos 14θθθθθθ+-=+-=+-==∴- 24
10810236081
002362
1234132) |4sin |2sin (44cos 22cos ) 4cos 2cos 2(22
2
m R d d d d I mR mR mR
=+-=??
????+-=
+-=?
???
πππ
π
π
θθπθθθθθθθθ
7.3.2 图示实验用的摆, l=0.92m,r=0.08m,ml =4.9kg,mr =24.5kg,近似认为圆 形部分为匀质圆盘,长杆部分为匀质细杆。求对过悬点且与盘面垂直的轴线的 转动惯量。 o
解:摆对 o 轴的转动惯量 I 等于杆对 o 轴的转动 惯量 I l 加上圆盘对 o 轴的转动惯量 I r ,即 I=Il +I r . 根据 平行轴定理
2
222
1
231222232
2123
1222121
26) 08. 092. 0(5. 2408. 05. 2492. 09. 4)
()
(, ) (kgm
r l m r m l m I r l m r m I l m m l m I r r l r r r l l l l l =++??+??=+++=++==+=
7.3.3 在质量为 M ,半径为 R 的匀质圆盘上挖出半径为 r 的两个圆孔,圆 孔中心在半径 R 的中点,求剩余部分对过大圆盘中心且与盘面垂直的轴线的转 动惯量。
解:大圆盘对过圆盘中心 o 且与盘面
垂直的轴线(以下简称 o 轴)的转动惯量 r
r
为
2
2MR
I =. 由于对称放置,两个小圆 盘对 o 轴的转动惯量相等,设为 I ’ ,圆盘 质量的面密度 σ=M/πR 2,根据平行轴定理,
2
122
22214) )(() (' r M r r r I R
r M R +=
+=πσπσ
设挖去两个小圆盘后,剩余部分对 o 轴的转动惯量为 I ”
) /2(' 2
4221212
1
2
4R r r R M Mr MR I I I R
r M --=--
=-=
7.3.5一转动系统的转动惯量为 I=8.0kgm2,转速为 ω=41.9rad/s,两制动闸 瓦对轮的压力都为 392N , 闸瓦与轮缘间的摩擦系数为 μ=0.4, 轮半径为 r=0.4m, 问从开始制动到静止需多长时间?
解:由转动定理:
s rad I I /68. 15, 0
. 8==
==ββτ
制动过程可视为匀减速转动, t ??=/ωβ
s t 67. 268. 15/9. 41/==?=?βω
7.3.6 匀质杆可绕支点 o 转动,当与杆垂直的冲力作用某点 A 时,支点 o 对杆的作用力并不因此冲力之作用而发生变化,则 A 点称为打击中心。设杆长 为 L ,求打击中心与支点的距离。 y
解:建立图示坐标 o-xyz,z 轴垂直纸面向外。 N 据题意,杆受力及运动情况如图所示。由质心运 o 动定理:) 1(, 02β
L c m ma F mg N
===- 由转动定理; ) 2(02
3
β
βmL I A F o ==
把⑴代入⑵中,可求得
L
oA 2=
7.3.7 现在用阿特伍德机测滑轮转动惯量。用轻线且尽可能润滑轮轴。两 端悬挂重物质量各为 m 1=0.46kg, m 2=0.5kg,滑轮半径为 0.05m 。自静止始,释 放重物后并测得 0.5s 内 m 2下降了 0.75m
解: T 2
T 1
a m 2g m 1g T 2 1
隔离 m 2、 m 1及滑轮,受力及运动情况如图所示。对 m 2、 m 1分别应用牛顿 第二定律:) 2(); 1(111222a m g m T a m T g
m =-=-
对滑轮应用转动定理:R Ia I R T T /) (12==-β (3)
质点 m 2作匀加速直线运动,由运动学公式:2
2
at
y =?,
222/06. 00. 5/75. 02/2s m t y a =?=?=∴
由 ⑴、 ⑵可求得
a m m g m m T T ) () (121212+--=-, 代入 (3) 中,
可求得
2
1212)](/) [(R
m m a g m m I +--=,代入数据:
2221039. 105. 0) 96. 006. 0/8. 904. 0(kgm I -?=?-?=
7.3.8斜面倾角为 θ, 位于斜面顶端的卷扬机鼓轮半径为 R , 转动惯量为 I , 受到驱动力矩 τ,通过绳所牵动斜面上质量为 m 的物体,物体与斜面间的摩擦 系数为 μ,求重物上滑的加速度,绳与斜面平行,不计绳质量。
解:隔离鼓轮与重物,受力分析如图,其中 T 为绳中张力, f=μN 为摩擦 力,重物上滑加速度与鼓轮角加速度的关系为 a =βR
对重物应用牛二定律:
T- μN- mgsinθ=ma, N=mgcosθ,代入前式, 得 T- μmgcos θ- mgsinθ=ma ①
对鼓轮应用转动定理: τ- TR=Iβ=Ia /R ②
由①②联立,可求得重物上滑的加速度:
2
2)
sin cos (mR
I mg R R a ++-=
θθμτ
7.3.9利用图中所示装置测一轮盘的转动惯量, 悬线和轴的垂直距离为 r ,为减小因不计轴承摩擦力 矩而产生的误差,先悬挂质量较小的重物 m 1,从距 地面高度为 h 处由静止开始下落, 落地时间为 t 1, 然 后悬挂质量较大的重物 m 2,同样自高度 h 处下落, 所需时间为 t 2,根据这些数据确定轮盘的转动惯量, 近似认为两种情况下摩擦力矩相等。
解:隔离轮盘与重物,受力及运动情况如图示:τf
为摩擦力矩, T 为绳中张力, a =βr
对轮盘应用转动定理:
11βτI r T f =-, 22βτI r T f =-,两式相减,得:
① ) /() (), () (12121212ββββ--=-=-r T T I I r T T
对重物应用牛顿二定律:
222222111111, ββr m a m T g m r m a m T g m ==-==-, 两式相减, 可
得:) () (11221212
ββm m r g m m T T ---=-,代入①中,可得:
m 1,m 2
mg
a
② ) /(]) () [(122112212ββββ----=r m m gr m m I
由运动学公式:,
/2, 2
1122212111t h a t a t a h =∴==
2
2
22112222, 2, 2rt h
rt h t h a ===ββ,将角加速度代入②中,得:
)
(2)
(2) ()
/() (2) //(2) () () (2
22
12
21212222212122
22
12
22
12
112
222
212222
1
2
12122
12
2t t h t m t m hr t t gr m m t t t t h t m t m hr gr m m r m m gr m m I rt h rt h
rt rt ----=
----=-
---=
7.4.1 扇形装置如图,可绕光滑的铅直轴线 o 转动,其转动惯量为 I. 装置的 一端有槽, 槽内有弹簧, 槽的中心轴线与转轴垂直距离为 r 。 在槽内装有一小球, 质量为 m ,开始时用细线固定,使弹簧处于压缩状态。现在燃火柴烧断细线, 小球以速度 v 0弹出。求转动装置的反冲角速度。在弹射过程中,由小球和转动 装置构成的系统动能守恒否?总机械能守恒否?为什么?
解:取小球、转动装置构成的物体系为研究对象。在弹射过程中,物体系 相对竖直轴 o 未受外力距作用,故物体系对转轴 o 的角动量守恒,规定顺时方 向为正,有 v 0
I rmv rmv I /000=∴=-ωω
在弹射过程中,物体系动能不 o
守恒,因弹力做正功使动能增加;
总机械能守恒,因为只有保守内力(弹力)做功。
7.4.2 质量为 2.97kg ,长为 1.0m 的匀质等截面细杆可绕水平光滑的轴线 o
转动,最初杆静止于铅直方向。一弹片质量为 10g ,以水平速度 200m/s射出并
嵌 入 杆 的 下 端 , 和 杆 一 起 运 动 , 求 杆 的 最 大 摆 角 θ. o
解:将子弹、杆构成的物体系作为研究对象, 整个过程可分为两个阶段研究:
第一阶段,子弹与杆发生完全非弹性碰撞, 获得共同的角速度 ω,此过程时间极短,可认
为杆原地未动。由于在此过程中,外力矩为零, m v 因此角动量守恒, ω
ωω23232
) (l M m Ml ml
mvl +=+=
s
rad m v /0. 2200
01. 0===∴?ω 第二阶段,子弹与杆以共同的初角速度 ω摆动到最大角度 θ,由于在此过 程中,只有重力做功,所以物体系的机械能守恒,物体系原来的动能等于重力 势能的增量:
8635
. 011cos ) cos 1() cos 1() (8
. 9) 97. 201. 02(0. 20. 1) 3/97. 201. 0(2
) 2() 3/(2223
12
1
2
≈-
=-
=∴-+-=+?+???+++ωθθθωg
M m l
M m l
Mg mgl l M m
θ=30o34’
7.4.3一质量为 m 1,速度为 v 1的子弹沿水平面击中并嵌入一质量为 m 2=99m1,长度为 L 的棒的端点,速度 v 1与棒垂直,棒原来静止于光滑的水平 面上,子弹击中棒后共同运动,求棒和子弹绕垂直与平面的轴的角速度等于多 少?
解:以地为参考系, 把子弹和棒看作一个物
体系, 棒嵌入子弹后作平面运动, 可视为随质心 C 的平动和绕质心 C 的转动,绕质心 C 转动的 角速度即为所求。
据 质 心 定 义 :
CA
L
CA CA CO m m m CA CO m m 299100, , 22121=+=+=,
O
C v 1 m 1
L L L CO L L CA 005. 0495. 05. 0, 495. 0200/99=-===
据角动量守恒:ω) (222212
111CO m L m CA
m CA v m ++=
L
v L v L m L v m /058. 0) 005. 09912/99495. 0(495. 0) 005. 09999495. 0(495. 012212
2
12
2
111=?++=?+?+=?ωω
ω
7.5.1 10m高的烟囱因底部损坏而倒下来,求其上端到达地面时的线速度, 设倾倒时,底部未移动,可近似认为烟囱为匀质杆。
解:设烟囱质量为 m ,高为 h ,质心高度 h C =h/2,对转轴的转动惯量
21
221) (mh m mh I h =+=,倒在地面上时的角速度为 ω 由机械能守恒:
h g mh mg I mgh h C /3, , 221
121=?=?=ωωω
上端点到达地面时的线速度:
s m gh h v /2. 17108. 933=??=
==ω
7.5.2 用四根质量各为 m 长度各为 l 的匀质细杆制成正方形框架,可绕其 中一边的中点在竖直平面内转动, 支点 o 是光滑的。 最初, 框架处于静止且 AB 边沿竖直方向,释放后向下摆动,求当 AB 边达到水平时,框架质心的线速度 v c 及框架作用于支点的压力 N.
解:先求出正方形框架对支点 o 的转动惯量:
2372342122
22
) (4) (42
m l
I m l m m l I m l
I m I I o l c c c o =∴=+=+=+= E p
设 AB 边达到水平位置时,框架的角速
度为 ω,据机械能守恒定律:
223
7
2222) (4ωωml I mg o l == gl
l v c g
3
112, =
==
∴ωω
AB 边在水平位置时, 框架所受到的向上的支撑力 N 和向下的重力 W 的作 用线均通过支点 o ,对 o 轴的力矩为零,据转动定理,框架的角加速度为零, ∴ a c =ω2l/2=6g/7,方向向上。规定向上方向为正,对框架应用质心运动定理:
mg mg N g m ma mg N c 73
76767) 1(4444=+=∴==-
据牛顿第三定律,支点受到的压力,大小等于 N ,方向向下。
7.5.3由长为 l , 质量为 m 的匀质细杆组成正方形框架,其中一角连于水平 光滑转轴 O ,转轴与框架所在平面垂直,最初,对角线 OP 处于水平,然后从 静止开始向下自由摆动,求 OP 对角线与水平成 45°时 P 点的速度,并求此时 框架对支点的作用力。
解:先求出框架对 O 轴的转动惯量:据平行轴定理,
23
1022
1
24
121212) (4) (44ml l m l m ml mOC I I C =++=+= 设对角线 OP 转过 45°后框架的角速度为 ω,且 势能为零,由机械能守恒:
2
25212, ) 45sin (
4ω
ωml mgl I mg l
==? gl
l v p g g 366222, , ===
=ωωω
设支点 O 对框架的作用力为 N ,由定轴转动定理:τ= Iβ,
g g l a l g ml l mg I
102
32
532, 533/102/45sin 42
====?=
=
βτ
βτ质心的法向加速度
2
562562g
l l g OC a n =?=
=ω
P
在 n ?方向应用质心运动定理:n n ma mg N 445cos 4=?-,
mg mg g
m mg N n 2522) 25222(2
56422=?+=?+=
在 τ
?方向应用质心运动定理:ττma mg N 445sin 4=?+
mg mg mg g m N 25
4
2) 256(2221034-=-=-?=τ
mg mg N N N n 32. 622232
2
22
=+=
+=?τ, 设与 -τ?方向夹角
为 θ, ?===7. 795. 5|/|arctg N N arctg n τθ
7.5.4 质量为 m 长为 l 的匀质杆,其 B 端放在桌上, A 端用手支住,使杆 成水平。突然释放 A 端,在此瞬时,求:⑴杆质心的加速度,⑵杆 B 端所受的 力。
解:⑴以支点 B 为转轴,应用转动 B A
定理:l
g
ml mg 232
3
2
=∴=ββ,质 心加速度
g
a c 42==β,方向向下。 x ⑵设杆 B 端受的力为 N ,对杆应用
y 质心运动定理:N
y =0,
N x - mg = - m ac
, N x = m(g – ac ) = mg/4 ∴ N = mg/4,方向向上。
7.5.5 下面是匀质圆柱体在水平地面上作无滑滚动的几种情况,求地面对 圆柱体的静摩擦力 f.
⑴沿圆柱体上缘作用一水平拉力 F, 柱体作加速滚动。
⑵水平拉力 F 通过圆柱体中心轴线,柱体作加速滚动。 ⑶不受任何主动力的拉动或推动,柱体作匀速滚动。 ⑷在主动力偶矩 τ的驱动下加速滚动,设柱体半径为 R 。 解:规定前进方向和顺时针方向为正方向。 假设静摩擦力方向向后,其余受力情况如图所 所示。对每种情况,都可以根据质心定理、绕
质心轴的转动定理和只滚不滑条件,建立三个 方程求解。
⑴ R
a mR R f F ma f F
c c ββ==+=-, ) (, 2
2 可求得 f = - F/3, 负号说明静摩擦力方向与假设方向相反,应向前。
⑵ R a mR fR ma f F
c c ββ===-, , 2
2
可求得 f = F/3, 正号说明静摩擦力方向与假设方向相同,向后。 ⑶ a c = 0 , f = 0
⑷ R
a mR fR ma f c c ββτ==+=-
, , 22, 求得 f 2τ
-= 负号说明静摩擦力方向与假设方向相反,应向前。
7.5.6 板的质量为 M ,受水平力 F 的作用,沿水平面运动,板与平面间的 摩擦系数为 μ. 在板上放一半径为 R 质 量为 M 2的实心圆柱,此圆柱只滚动不 滑动。求板的加速度。
解:隔离圆柱,其受力及运动情况如图 β 所示,其中 a c 为质心对地的加速度, β为相
对质心的角加速度, f 2、 N 2分别为板施加给 W 2 圆柱的静摩擦力和压力。 由质心定理:
) 2(), 1(2222g M N a M f c == N 2
F(1) F(2)
对质心应用转动定理:
) 3(2
222β
R M R f = N
隔离木板,其受力及运动情况如图所示,
f 2
其中 a 为板对地的加速度, f 1、 N 1分别为水平 f 1=μN 1 面施加给板的滑动摩擦力和压力。 N 2 应用牛顿第二定律(或质心定理) :
) 4(21Mg N N += ) 5(21Ma f N F =--μ
圆柱在木板上只滚不滑的条件是:a = ac +βR (6)
(圆柱与板接触点对地的加速度等于质心加速度加上绕质心转动的加速度,即 a c +βR ,它必须等于木板对地的加速度 a , 才能只滚不滑 )
将(2)代入(4)求得:N 1=(M+M2) g ;由(1) (3)可解得, 2a c =Rβ 与 (6)联立,可求得, a c =a/3, 代入(1)中, f 2 = a M2 /3;将 N 1、 f 2代入(5)中, 有
2
23]
) ([3232) (M M g M M F a Ma
a M g M M F ++-=
∴=-+-μμ
7.5.7 在水平桌面上放置一质量为 m 的线轴, 内径为 b , 外径为 R, 其绕中心 轴转动惯量为 mR 2/3, 线轴和地面之间的静摩擦系数为 μ。线轴受一水平拉力 F, 如图所示。
⑴使线轴在桌面上保持无滑滚动之 F 最大值是多少?
⑵若 F 和水平方向成 θ角, 试证, cos θ>b/R时, 线轴向前滚; cos θ
解:可将(1)看作(2)的特殊 情况。建立图示坐标, z 轴垂直纸面 向外,为角量的正方向。根据静摩擦 力的性质,可知其方向与 F 水平分量 f 方向相反。设线轴质心的加速度为 a , 绕质心的角加速度为 β。
由质心定理:) 2(sin ) 1(cos θθF mg N ma f F -==-
由转动定理:) 3(2
1β
mR fR Fb =-
只滚不滑:a+βR=0 (4) 由⑴ , ⑶ , ⑷联立,可求得:
) cos 3(, ) cos (, ) (cos444θθβθR b f a R
R m R R m +=
-=-=
⑴ F 为水平拉力时,即
mg R b f R
F
μθ≤+==) 3(, 1cos 4
mg
F R
b R +≤∴34μ.
⑵ 若 0, 0, cos <>>βθa b
,即线轴向前滚;
若 0, 0, cos >
βθ
a R
,即线轴向后滚。
7.5.9 一质量为 m, 半径为 r 的均质实心小球沿圆弧形导轨自静止开始无滑 滚下,圆弧形导轨在铅直面内,半径为 R 。最初,小球质心与圆环中心同高度。 求小球运动到最低点时的速率以及它作用于导轨的正压力。
解:设小球运动到最低点时,其质心速 度为 v ,绕质心转动的角速度为 ω,由机械 能守恒,有 225222) ()
(ω
mr mv r R mg +=- 只滚不滑条件:ω=v/r, 代入上式,可求得
g
r R v ) (10
-=
在最低点应用质心运动定理:
) /(2r R mv mg N -=-
mg g g m r R v g m N 3
722) ()]/([=+=++=∴,
作用于导轨的正压 力与此等大,方向向下。
7.6.1 汽车在水平路面上匀速行驶,后面牵引旅行拖车,假设拖车仅对汽 车施以水平向后的拉力 F. 汽车重 W, 其重心与后轴垂直距离为 a, 前后轴距离为 l , h 表示力 F 与地面的距离。 问汽车前后论所受地面支持力与无拖车时有无区别? 试计算之。
解:隔离汽车,受力
情况如图所示(摩擦力没
有画出,因与此题无关) 。
在竖直方向应用力平 衡方程:) 1(21
W
N N =+
以前轮为支点,由力矩平衡方程, ) 2() (2Fh a l W l N +-=
由(2)解得:l Fh l a W N /) /1(2
+-=
将 N 2代入 (1)中得:l Fh l W a N //1
-=
令 F=0,即得到无拖车时前后轮的支持力 N 1’ 和 N 2’ 。显然,有拖车时,前 轮支持力减小,后轮支持力增大。
7.6.3 电梯高 2.2m , 其质心在中央, 悬线亦在中央。 另有负载 50×10kg , 其重心离电梯中垂线相距 0.5m 。 问 ⑴当电梯匀速上升时,光滑导轨对电梯的作用力,不计 摩擦 (电梯仅在四角处受导轨作用力) ; ⑵当电梯以加速 度 0.05m/s2上升时,力如何?
解:⑴以 o 为轴 , 据力矩平衡条件:mgb Nl
=
N l mgb N 310114. 12. 2/5. 08. 91050/?=???==
⑵设电梯的加速度为 a ,以电梯为参考系,负载除受重力外,还受惯性力 作用 f*=ma, 方向向下 , 据力矩平衡条件:b a g m Nl
) (+=
N l b a g m N 310119. 12. 2/5. 0) 05. 08. 9(1050/) (?=+?=+=
7.7.1环形框架质量为 0.20kg ,上面装有质量为 1.20kg 的回转仪,框架下 端置于光滑的球形槽内,回转仪既自传又旋进,框架仅随回转仪的转动而绕铅 直轴转动,回转仪自身重心以及它连同框架的重心 均在 C 点, C 点与转动轴线的垂直距离为 r=0.02m, 回转仪绕自转轴的转动惯量为 4.8×10-4kgm 2, 自转角 速度为 120rad/s. ⑴求旋进角速度;⑵求支架球形槽 对支架的总支承力。
解:根据旋进与自旋的关系式:
s rad I gr m m I /76. 4120
108. 402. 08. 9) 2. 12. 0() (421≈????+=+==
Ω-ωωτ
把回转仪与支架当作一个系统,设球形槽对支架的支承力为 N ,整个装置
的质心 C 相对竖直轴做匀速圆周运动,由质心运动定理:
N
N N N N
g m m N N
r m m N z x z x 73. 1372. 1363. 072. 138. 9) 2. 12. 0() (63. 076. 402. 0) 2. 12. 0() (222
2212221=+=+==?+=+==??+=Ω+= 与竖直轴夹角 ?===63. 273
. 1363
. 0arctg N N arctg
z x θ
范文五:模电第七章
第 7章 信号的运算和处理
自测题
一、现有电路:
A. 反相比例运算电路 B. 同相比例运算电路
C. 积分运算电路 D. 微分运算电路
E. 加法运算电路 F. 乘方运算电路
选择一个合适的答案填入空内。
(1)欲将正弦波电压移相+90o ,应选用 ( C )。
(2)欲将正弦波电压转换成二倍频电压,应选用 ( F )。
(3)欲将正弦波电压叠加上一个直流量,应选用 ( E )。
(4)欲实现 A u =? 100 的放大电路,应选用 ( A )。
(5)欲将方波电压转换成三角波电压,应选用 ( C )。
(6)欲将方波电压转换成尖顶波波电压,应选用 ( D )。
二、填空:
(1)为了避免 50H z 电网电压的干扰进入放大器,应选用 ( 带阻 ) 滤波电路。
(2)已知输入信号的频率为 10kH z ~12kH z ,为了防止干扰信号的混入,应选用 ( 带通 ) 滤 波电路
(3)为了获得输入电压中的低频信号,应选用 ( 低通 ) 滤波电路。
(4)为了使滤波电路的输出电阻足够小, 保证负载电阻变化时滤波特性不变, 应选用 ( 有源 ) 滤波电路。
三、已知 图 T7.3所示各电路中的集成运放均为理想运放,模拟乘法器的乘积系数 k 大 于零。试分别求解各电路的运算关系。
(a)
(b)
图 T7.3
解:图 (a)所示电路为求和运算电路,图 (b)所示电路为开方运算电路。它们的运算表达 式分别为:
(a) 124
13121234
(
) (1) //f I I O f I R u u R u R u R R R R R R =-+++??+ 11
O O u u dt RC =-
?
(b) ' 2
3322144
O I O O R R R u u u ku R R R =-
?=-?=-?
O u =
习题
本章习题中的集成运放均为理想运放。 7.1填空:
(1) ( 同相比例 ) 运算电路可实现 A u >1 的放大器。 (2) ( 反相比例 ) 运算电路可实现 A u <0 的放大器。="" (3)="" (="" 微分="" )="">0>
(4)( 同相求和 ) 运算电路可实现函数 123Y aX bX cX =++, a 、 b 和 c 均大于零。 (5) ( 反相求和 ) 运算电路可实现函数 123Y aX bX cX =++, a 、 b 和 c 均小于零。 (6)( 乘方 ) 运算电路可实现函数 2
Y aX =。
7.2电路如 图 P7.2所示,集成运放输出电压的最大幅值为 ±14V ,填表。
(a) (b)
解: 1(/) 10O f I I u R R u u =-=-; 2(1/) 11O f I I u R R u u =+=。 当集成运放工作到非线性区时,输出电压不是 +14V , 就是 -14V 。
7.3 设计一个比例运算电路,要求输入电阻 20i R k =Ω,比例系数为 -100。
解:可采用反相比例运算电路,电路形式如图 P7.2(a)所示。 20R k =Ω; 2f R M =Ω。
7.4电路如 图 P7.4所示,试求其输入电阻和比例系数。
解:由图可知 150i R R k ==Ω,
1212
21
, 2I M
R R M I I
u u i i R R R
u u u R -==∴=-=-即
而 243
M O
M M u u u u R R R --
=+ 解得:52104O M I u u u ==-
图 P7.4
7.5电路如 图 P7.4所示,集成运放输出电压的最大幅值为 ±14V , I u 为 2V 的直流信号。 分别求出下列各种情况下的输出电压:
(1)R 2短路; (2) R 3短路; (3) R 4短路; (4) R 4断路。
解:(1) R 2短路时, 2
1
0M I R u u R =-
=, R 4相当于开路(R 4上无电流流过) 。 ∴ 3
1
24O I I R u u u V R =-
=-=-; (2) R 3短路时, O M u u =, R 4对反馈网络无影响。 ∴ 2
1
24O I I R u u u V R =-
=-=-; (3) R 4短路时,电路无反馈。 ∴ 14O u V =-; (4) R 4断路时, 23
1
48O I I R R u u u V R +=-
=-=-。
7.6试求 图 P7.6所示各电路输出电压与输入电压的运算关系式。
(a) (b)
(c) (d) 图 P7.6
解:在图示各电路中,集成运放的同相输入端和反相输入端所接总电阻均相等。各电 路的运算关系式分析如下:
(a)123123123225f f f O I I I I I I R R R u u u u u u u R R R =-
?-
?+
?=--+
(b)1231231
2
3
1010f f f O I I I I I I R R R u u u u u u u R R R =-?+?+?=-++
(c) 21211() 8() f O I I I I R u u u u u R =
-=-
(d) 1234123412
3
4
202040f
f
f
f
O I I I I I I I I R R R R u u u u u u u u u R R R R =????=--++
7.7在 图 P7.6所示各电路中,集成运放的共模信号分别为多少?写出表达式。 解:因为集成运放同相输入端和反相输入端之间净输入电压为零, 所以它们的电位就是 集成运放的共模输入电压。图示各电路中集成运放的共模信号分别为:
(a) 3IC I u u = (b)3223232323101
1111
IC I I I I R R u u u u u R R R R =
+=+++
(c) 22189
f
IC I I f R u u u R R =
=+
(d) 3434343434401
4141
IC I I I I R R u u u u u R R R R =
+=+++
7.8图 P7.8所示为恒流源电路, 已知稳压管工作在稳压状态, 试求负载电阻中的电流。
解:22
0.6P Z
L u U I mA R R =
==。 图 P7.8
7.9电路如 图 P7.9所示。
(1)写出 O u 与 1I u 、 2I u 的运算关系式;
(2)当 R W 的滑动端在最上端时,若 mV u I 101=, mV u I 202=,则 O u =?
(3)若 O u 的最大幅值为 ±14V ,输入电压最大值 mV u I 10max 1=, mV u I 20max 2=,为 了保证集成运放工作在线性区, R 2的最大值为多少?
图 P7.9
解:(1) A 2同相输入端电位
222121() 10() f P N I I I I R u u u u u u R
==
-=-
输出电压 2222111
(1) 10(1)() O P I I R R
u u u u R R =+
?=+-
或 211
10
() W
O I I R u u u R =- (2) 将 mV u I 101=, mV u I 202= 代入上式,得 100O u mV =。
(3) 根据题目所给参数, 21() I I u u -的最大值为 20mV 。若 R 1为最小值,则为保证集 成运放工作在线性区, 21() I I u u -=20mV 时集成运放的输出电压应为+14V , 写成表达式为
211min 1min
10
10() 102014W O I I R u u u R R =?
?-=??= 故 1min 143R ≈Ω
2max 1min (100.143) 9.86W R R R k k =-=-Ω≈Ω
7.10分别求解 图 P7.10所示各电路的运算关系。
(a) (b)
(c) 图 P7.10
解:图 (a)所示为反相求和运算电路;图 (b)所示的 A 1组成同相比例运算电路, A 2组成加 减运算电路; 图 (c)所示的 A 1、 A 2、 A 3均组成为电压跟随器电路, A 4组成反相求和运算电路。
(a)设 R 3、 R 4、 R 5的节点为 M ,则 12
312
(
) I I M u u u R R R =-+ 43512125
I I M
R R R u u u i i i R R R =-=
+- 43412
434512
()() I I O M R R R u u u u i R R R R R R =-=-+++ (b)先求解 1O u ,再求解 O u 。
3
111
(1) O I R u u R =+
5553
551212
21
4441
4
4
(1) () ) ) ()
O O I I I I I R R R R R R u u u u u u u R R R R R R =+=++- (c)A 1、 A 2、 A 3的输出电压分别为 u I1、 u I2、 u I3,由于在 A 4组成的反相求和运算电路中反
相输入端和同相输入端外接电阻阻值相等,所以
4
1231231
() 10() O I I I I I I R u u u u u u u R =
++=++
7.11在 图 P7.11(a)所示电路中,已知输入电压 u I 的波形如图 (b)所示,当 t =0时 u C =0。 试画出输出电压 u O 的波形。
(a) (b)
图 P7.11
解:输出电压的表达式为 2
111() t O I O t u u dt u t RC
=-+? 当 u I 为常量时:
21121121157
11
() () () () 100() () 1010O I O I O I O u u t t u t u t t u t u t t u t RC -=-
-+=--+=--+? 若 t =0时 u O =0;则
当 t =5mS 时, 3
10055102.5O u V V -=-???=-。
当 t =15mS 时, 3
[100(5) 1010(2.5)]2.5O u V V -=-?-??+-=。 因此输出波形如 解图 P7.11所示。
解图 P7.11
7.12已知 图 P7.12所示电路输入电压 u I 的波形如 图 P7.11 (b)所示,且当 t =0时 u C =0。 试画出输出电压 u O 的波形。
图 P7.12 解图 P7.12
解:图中可见, N P I u u u ==, () C I O I
du d u u u C C
R dt dt
-∴-
== 即:O I I
du du u dt dt RC
=+;∴输出电压与输入电压的运算关系为:
1
() (0)O I I C u t u u t u RC
=++
或 :100(0)O I I C u u t u u =++(t )
设当 t =0时, u C =0。分段画出波形如 解图 P7.12所示。
7.13试分别求解 图 P7.13所示各电路的运算关系。
(a) (b)
(c) (d) 图 P7.13
解:利用节点电流法,可解出各电路的运算关系分别为:
( a ) 2111100O I I I I R u u u dt u u dt R R C
=-
-=--?? ( b ) 设两电容的充电电流为 :111C I du du
i C C dt dt
=?
=?(方向向右 ), 则 311221() 102I I
O I I du C du u iR idt RC u u C dt C dt
-=-+
=--=--? ( c )反相端:1
O N C P P u u u u u dt RC =+=+? 同相端:111
I P P C I P u u u u dt u dt u dt C R RC RC
-===-??? 代入上式,得 3
110O I
I u u dt u dt RC ==??
? ( d ) 12
1212
1() 100(0.5) I I O I I u u u dt u u dt C R R =-+=-+??
7.14在 图 P7.14所示电路中,已知 '
12100f R R R R R k =====Ω, 1C F μ=。
图 P7.14
(1)试求出 u O 与 u I 的运算关系。
(2)设 t=0时 u O =0,且 u I 由零跃变为 -1V ,试求输出电压由零上升到+6V 所需要的时间。
解:(1)因为 A 2构成电压跟随器,电容上的电压 C O u u =。 A 1为求差运算电路,利用叠 加原理,求出其输出电压:
11
1
2(1) f f O I O O I R R R u u u u u R R R R '
=-
++
?
=-'
+
电容的电流:1O O I C u u u
i R R -=
=-(利用了上式) 因此,输出电压:11
10O C C I I u u i dt u dt u dt C RC ===-
=-??
? (2)11110[10(1) ]106O I u u t t V t V V =-=-?-?==, 故 t l = 0.6S 。即经 0.6 秒输出电压达到 6V 。
7.15试求出 图 P7.15 所示电路的运算关系。
图 P7.15
解:设 A 2的输出为 u O2。因为 R 1的电流等于 C 的电流,所以:
211
2O I I u u dt u dt R C
=-
=-?? 又因为 A 2组成以 u O 为输入的同相比例运算电路,所以: 223
(1) 2O O O R u u u R ==
比较以上两式,得:O I u u dt =-?
7.16在 图 P7.16所示电路中,已知 u I1= 4V , u I2=1V 。回答下列问题:
图 P7.16
(1)当开关 S 闭合时,分别求解 A 、 B 、 C 、 D 和 u O 的电位; (2)设 t =0时 S 打开,问经过多长时间 u O = 0 ?
解:(1) 对 A 1、 A 2而言,都工作在同相比例运算状态,
∴ 1114B N P I U u u u V ====; 2221
C N P I U u u u V ====。 由于三个 R 从上而下流过同一电流 3B C R U U i R R
-==, ∴ 37A B U U R V R =+?=; 3
2D C U U R V R
=-=-。
当开关 S 闭合时, A 3输出 30O u =, ∴ (1) 24O D D R
u U U V R
=+
==-。 (2) t =0时 S 打开, A 3为积分电路, 3111
140A O A
U u U dt t t R C R C
=-
=-?=-?; 因为 A 4为求差电路,∴ 33241404O D O O u U u V u t =-=--=-。
令上式为零,求出 28.6t mS ≈。
7.17为了使 图 P7.17所示电路实现除法运算, (1)标出集成运放的同相输入端和反相输入 端; (2)求出 u O 和 u I1、 u I2的运算关系式。
图 P7.17
解:(1)为了保证电路引入负反馈, A 的上端为 “+” ,下端为 “? ” 。
(2)根据模拟乘法器输出电压和输入电压的关系和节点电流关系,可得 '
220.1O O I O I u ku u u u ==-;
'
12(0.1) I P N O O I f f
R R u u u u u u R R R R ===
=?-++
所以 1
2
10() f I O I R R u u R u +=-
?
7.18求出 图 P7.18所示各电路的运算关系。
(a)
(b)
图 P7.18
解:电路 (a)实现求和、除法运算,电路 (b)实现一元三次方程。它们的运算关系式分别 为 :
(a) '
123312(
) I I O O I u u u R ku u R R =-+=, 312312
() I I O I R u u
u ku R R =-+
(b) 223444123
O I I I R R R
u u ku k u R R R =---。
7.19在下列各种情况下, 应分别采用哪种类型 (低通、 高通、 带通、 带阻) 的滤波电路。
(1)抑制 50Hz 交流电源的干扰;
(2)处理具有 1Hz 固定频率的有用信号; (3)从输入信号中取出低于 2kHz 的信号; (4)抑制频率为 100kHz 以上的高频干扰。
解:(1)带阻滤波器; (2)带通滤波器
(3)低通滤波器 (4)低通滤波器
7.20试说明 图 P7.20所示各电路属于哪种类型的滤波电路,是几阶滤波电路。
(a)
(b)
(c) (d) 图 P7.20
解:图 (a)所示电路为一阶高通滤波器。 图 (b)所示电路二阶高通滤波器。
图 (c)所示电路二阶带通滤波器。 图 (d)所示电路二阶带阻滤波器。
7.21设一阶 HPF 和二阶 LPF 的通带放大倍数均为 2 ,通带截止频率分别为 100 Hz 和 2k Hz 。试用它们构成一个带通滤波电路,并画出幅频特性。
解:低通滤波器的通带截止频率为 2kHz , 高通滤波器的通带截止频率为 100Hz 。将两 个滤波器串联,就构成一个带通滤波电路。
其通带放大倍数为: 4uP A =。 通带增益 20l 12
uP A ≈ 幅频特性如 解图 P7.21
所示。
解图 P7.21
7.22在 图 7.3.9 (P364) 所示电路中, 已知通带放大倍数为 2 , 截止频率为 1kHz , C 取 值为 1μF 。试选取电路中各电阻的阻值。
解:因为通带放大倍数 2up A =, 所以 1, 2P
u f f Q A ===。
因为 1
2o p f f RC
π==
,代入数据,得出:160R k ≈Ω。
为使得集成运放同相输入端和反相输入端所接电阻相等,则 124640R R R k ==≈Ω。 7.23试分析 图 P7.23所示电路的输出 u O1、 u O2和 u O3分别具有哪种滤波特性(LPF 、 HPF 、 BPF 、 BEF ) ?
图 P7.23
解:以 u O1为输出是高通滤波器,以 u O2为输出是带通滤波器,以 u O3为输出是低通滤 波器。
补充 1. 分别推导出 补图 P7.1 所示各电路的传递函数,并说明它们属于哪种类型的滤 波电路。
(a)
(b)
补图 P7.1
解:利用节点电流法可求出它们的传递函数。 在图 (a)所示电路中 2211() 11u R sR C
A s sR C
R sC
=-
=-
++
。 故其为高通滤波器。
在图 (b)所示电路中 22211211/()
1() 1u R R R A s R R sR C
?
+=-=-?+。
故其为低通滤波器。
转载请注明出处范文大全网 » MATLAB编程(第二版)第