MATLAB 数据对象及运算 本章学习目标 (1)掌握MATLAB数据的表示方法。 (2)掌握在MATLAB中生成和引用变量的方法。 (3)熟悉MATLAB算术运算规则。 (4)熟悉MATLAB结构体、元胞数组和表的应用。 在MATLAB应用程序中引用的数据实体,如数、字符串、变量、文件等都称为数据对 象。本章首先讲述MATLAB描述、表达数据的方法,然后介绍MATLAB变量的生成和引 用方法,以及MATLAB 的算术运算规则和实现算术运算的多种方法,最后介绍在 MATLAB应用程序中如何使用结构体、元胞数组和表存储、处理半结构化和非结构化 数据。 3.1 MATLAB 数据类型 数据是有类型的,不同类型数据的存储方式不同,值域不同,运算的规则和方法不同。 MATLAB有17个基础数据类型,包括数值(numeric)类、字符(char)和字符串(string)类、 逻辑(logical)类、表(table和timetable)、结构体(struct)和元胞(cell)等,分别用于处理不同 的数据实体。丰富的数据类型增强了MATLAB表达和处理数据的能力。 3.1.1 数值数据 数值数据是科学计算中最常见、应用最多的数据。不同的数值类型适用不同的应用场 景。例如,采用RGB模式定义颜色时,元素的类型为uint8;定义图像颜色的饱和度时,元素 的类型为double。 1. 数值数据类型 MATLAB中的数值可以表示为有符号整型、无符号整型、单精度(single)和双精度 (double)浮点型。若没有指定类型,MATLAB将数值数据默认按双精度浮点类型存储和 处理。 1)整型 MATLAB支持以1字节、2字节、4字节和8字节存储整型数据。以uint8类型为例, 3 49 该类型数据在内存中占用1字节,可描述的数为0~255。表3.1列出了MATLAB系统定 义的整型和对应类型的值域。 表3.1 MATLAB的整型 类 型值 域类 型值 域 uint8 0~28-1 int8 -27~27-1 uint16 0~216-1 int16 -215~215-1 uint32 0~232-1 int32 -231~231-1 uint64 0~264-1 int64 -263~263-1 要将数据以指定的整型方式存储于工作区,则调用与类型同名的转换函数。例如,将数 12345指定用16位有符号整型存储,存于变量x,命令如下。 x = int16(12345); 使用类型转换函数将浮点数转换为整数时,MATLAB 将舍入到最接近的整数。如果 小数部分正好是0.5,则MATLAB 会从两个同样临近的整数中选用绝对值更大的整数。 例如: >> x = int16([-1.5, -0.8, -0.23, 1.23, 1.5, 1.89]) x = 1×6 int16 行向量 -2 -1 0 1 2 2 此外,MATLAB还提供了按指定方式将浮点数转换为整数的函数。 .round函数:四舍五入为最近的小数或整数。 .fix函数:朝零方向四舍五入为最近的整数。 .floor函数:朝负无穷大方向四舍五入。 .ceil函数:朝正无穷大方向四舍五入。 例如,分别用以上函数将向量[-1.5,-0.8,-0.23,1.23,1.5,1.89]的各个元素转换为 整型数,命令和输出如下。 >> x1 = round([-1.5, -0.8, -0.23, 1.23, 1.5, 1.89]) x1 = -2 -1 0 1 2 2 >> x2 = fix([-1.5, -0.8, -0.23, 1.23, 1.5, 1.89]) x2 = -1 0 0 1 1 1 >> x3 = floor([-1.5, -0.8, -0.23, 1.23, 1.5, 1.89]) x3 = -2 -1 -1 1 1 1 >> x4 = ceil([-1.5, -0.8, -0.23, 1.23, 1.5, 1.89]) x4 = -1 0 0 2 2 2 50 2)浮点型 浮点型用于存储和处理实数,在MATLAB中,用single和double描述。MATLAB按 照IEEE754标准来构造浮点数,single型数用4字节(32位二进制)存储,double型数用8 字节(64 位二进制)存储。因此,实数以double 型存储,比以single 型存储精度高。 MATLAB 默认以double型存储数值数据。 single函数和double函数用于将其他类型数据转换为single型和double型。 3)复型 MATLAB 可以存储和处理复数,用complex描述。复数由实部和虚部构成,在MATLAB 中,实部和虚部默认为double型,虚数单位用i或j表示,例如,5+6i、x+1i*y。 当所构造的complex型数的实部或虚部是非浮点型数时,须调用complex函数来生成 complex型数,例如,生成一个虚部为int8型数的复数,命令如下。 >> complex(3, int8(4)) ans = int8 3 + 4i real函数用于获取复型数的实部值,imag函数用于获取复型数的虚部值。 2. 识别数据类型 为了提高运算的精度和效率,在MATLAB程序中,使用表3.2中的函数识别数据对象 是否与指定类型一致。结果为1表示一致,为0表示不一致。 MATLAB的isa函数用于判别数据对象是否为指定类型,isa函数的调用格式为 isa(obj, ClassName) 其中,输入参数obj是要识别的数据对象,ClassName是类型名。例如,判别数1.23是否为 double类型,命令如下。 >> isa(1.23, 'double') ans = logical 1 表3.2 判别数值数据类型的函数 函 数说 明示 例 isinteger 判别是否为整型 >>isinteger(100) ans= logical 0 >>isinteger(int8(100)) ans= logical 1 isfloat 判别是否为浮点型 >>isfloat(int64(1.23e6)) ans= logical 0 >>isfloat(1.23e6) ans= logical 1 51 函 数说 明示 例 isnumerical 判别是否为数值型 >>isnumeric(1' .23e6') ans= logical 0 >>isnumeric(1.23e6) ans= logical 1 isreal 判别是否为实数或复数 >>isreal(5+6i) ans= logical 0 >>isreal(5+6) ans= logical 1 isfinite 判别是否为有限值 >>isfinite(inf) ans= logical 0 >>isfinite(1.23e123) ans= logical 1 isinf 判别是否为无穷值 >>isinf(1.23e123) ans= logical 0 >>isinf(inf) ans= logical 1 isnan 判别是否为NaN >>isnan(0.1/0) ans= logical 0 >>isnan(0/0) ans= logical 1 3. 数据输入/输出格式 输入/输出数值数据时,可以采用日常记数法和科学记数法。例如,1.23456、-9.8765i、 3.4+5i等是用日常记数法表示数,1.56789e2、1.234e-5是采用科学记数法分别表示数 1.56789×102、1.234×10-5。其中,字母e或E表示以10为底,字母前的数可以是实数、整 数,不能是复数;字母后的数是10的幂,只能是整数。 在命令行窗口输出数据前,可以用format函数设置数据输出格式。format函数的基本 调用格式如下。 format style 或 format(style) 其中,输入参数style指定数据的输出格式,可以使用字符向量、字符串标量,常用格式字符 串如表3.3所示,表中的示例数据是double类型。format命令只影响数据的输出格式,不 影响数据的存储精度。 在命令行窗口输出数据时,默认采用losse模式控制行距,本书为了节约排版空间,在 运行示例前,执行formatcompact命令,将命令行窗口的输出模式设置为紧凑模式,不输出 续表 52 空行。 表3.3 常用输出格式 格式字符串格 式 输出示例 设x=[4/3;1.2345e-6]; short 十进制短格式(默认格式),小数点后有4位 有效数字 1.3333 0.0000 long 固定十进制长格式,小数点后有15位数字1.333333333333333 0.000001234500000 rational 分式格式4/3 1/810045 hex 十六进制格式3ff5555555555555 3eb4b6231abfd271 compact 在命令行窗口输出时隐藏空行 loose 在命令行窗口输出时有空行 3.1.2 文本数据 网络中各种应用都会涉及文本和字符数据的处理。例如,QQ、微信、网页中传输的信 息文本,传输过程中需要加密/解密、压缩/解压缩;在做社会实践调查时,常会从电子邮件、 社交媒体内容和产品评论中提取文本和字符,进行排序、筛选、分词、聚类等分析和处理。在 MATLAB中,使用字符(character)数组和字符串(string)数组来存储和处理文本数据。 1. 字符数组 MATLAB字符数组用于存储字符序列,每个元素存储一个字符。存储单行字符序列 的字符数组称为字符向量,只有1个元素的字符数组称为字符标量。 1)生成字符向量 生成字符向量是通过单撇号界定字符序列来实现的,向量中的每个元素存储一个字符。 例如: >> ch1 = 'This is a book.'; 若字符序列中含有单撇号,则该单撇号字符须用两个单撇号来表示。例如: >> ch2 = 'It''s a book.' ch2 = 'It's a book.' 2)生成字符数组 二维字符数组由若干字符向量构成,数组中的每行对应一个字符向量。例如: >> ch = ['abcdef'; '123456']; 用字符向量生成字符数组时,各个字符向量的大小必须相同。如果各个字符向量长度 53 不等,可以使用char函数将长度不同的字符向量合成字符数组,例如: >> language = char('Fortran','C++','MATLAB') language = 3×7 char 数组 'Fortran' 'C++ ' 'MATLAB ' 这4个字符串的长度分别为7、3、6,用char函数生成字符数组时,每行长度都按照字符 向量的最大长度7进行了扩充,扩充的方法是在原字符串后添加空格。 2. 字符串数组 MATLAB字符串数组是文本片段的集合,字符串数组中的每个元素存储一个字符串, 字符串长度可以不同。只有1个元素的字符串数组称为字符串标量。 1)生成字符串 生成字符串是通过双引号括起字符序列来实现的。例如: >> str1 = "Hello, world"; 如果字符序列包含双引号,则在定义中使用两个双引号。例如: >> str = "They said, ""Welcome!"" and waved." str = "They said, "Welcome!" and waved." 2)生成字符串数组 字符串数组适合存储多段文本。字符串数组中的每个元素各存储一段文本,各段文本 的长度可以不同。例如: A = ["a","bb","ccc"; "dddd","eeeeee","This is a test."] A = 2×3 string array "a" "bb" "ccc" "dddd" "eeeeee" "This is a test." 3)连接字符串 在MATLAB中,可以通过加号运算符连接两个字符串。例如: >> name = "Andy"; >> str = "Hello," + name str = "Hello,Andy" 这种运算也可以应用于两个大小相等的字符串数组,将两个数组中对应位置的字符串 两两相连。例如: 54 >> s1 = ["Red" "Blue" "Green"]; >> s2 = ["Truck" "Sky" "Tree"]; >> s = s1 + s2 s = 1×3 string 数组 "RedTruck" "BlueSky" "GreenTree" 3. 文本数据与其他类型数据的转换 在做文本分析时,常常需要将文字数据转换为数值,或者在给图表添加标注时,需要将 数值转换为文字后输出。表3.4列出了MATLAB文本数据与其他类型数据的转换函数。 表3.4 文本数据与其他类型数据的转换函数 函 数功 能示 例 char 将数值数组转换为字符数组,字符数 组的每个元素为数值数组中对应元 素的ASCII字符 >> C =char([6566;6768]) C = 2×2char数组 'AB' 'CD' string 将数值数组转换为字符串数组 >> S=string([6566;6768]) S= 2×2string数组 "65" "66" "67" "68" num2str 按指定精度将数值数组转换为字符 数组 >> S1=num2str([12345,789;6.568,0.0523],3) S1= 2×18char数组 1' .23e+04 789' ' 6.57 0.0523' mat2str 按指定精度将数值矩阵转换为字符 向量 >> S2=mat2str([12345,789;6.568,0.0523],3) S2= '[1.23e+04789;6.570.0523]' str2num 将字符串或字符向量转换为数值 数组 >> C =str2num('[3.85,2.91;7.74,8.99]') C = 3.8500 2.9100 7.7400 8.9900 feval 将字符向量转换为函数,代入参数进 行计算 >>feval('mod',10,3) ans= 1 eval 将字符串转换为数值数组 >> C =eval("[3.8/2,2.91;7.74,8.99]") C = 1.9000 2.9100 7.7400 8.9900 注:65、66、67、68分别是字母A、B、C、D的ASCII码。 55 3.2 MATLAB 变量 MATLAB变量用于存储数值和字符、符号对象、图形对象等,变量的大小、类型根据所 存储的数据自动确定,也可以调用MATLAB函数(如zeros、uint8、reshape函数)指定和改 变变量的大小和类型。 3.2.1 建立变量 1. 赋值 在MATLAB中,通过赋值命令来建立变量。MATLAB赋值命令的基本格式如下。 变量= 表达式; 在执行赋值命令时,先对赋值号右端表达式进行计算,再将结果赋给左边的变量。赋值 号左边变量的类型、大小根据右端表达式的计算结果自动确定。当仅有表达式时,将表达式 的值赋给预定义变量ans。 如果赋值命令后没有分号,命令行窗口会输出变量的值。如果赋值命令后有分号,则仅 执行赋值操作,命令行窗口不输出变量的值。例如: >> x1 = 2.58; x2=int8(-16.3), x3=single(16.3) x2 = int8 -16 x3 = single 16.3000 执行以上命令,因为x1=2.58后有分号,不输出x1的值;int8函数、single函数分别将 其输入参数转换为int8类型、single类型,生成的变量x2、x3不是默认的double型,因此输 出变量x2、x3的类型和值。 2. 赋句柄 在MATLAB中,还可以将函数句柄赋给变量,此时变量的类型为function_handle。构 造函数句柄的方法如下。 f = @myfunction; 其中,符号@是函数句柄的定义符,myfunction可以是MATLAB内置函数(如sqrt),也可 以是自定义函数。通过函数句柄调用原函数,与直接调用函数的结果一致。例如: >> f1 = @sqrt; >> f1(9) %等效于sqrt(9) ans = 3 56 在MATLAB程序中,通常将单行表达式用匿名函数形式来定义,然后将匿名函数句柄 赋给变量。匿名函数的定义方法如下。 h = @(arglist)anonymous_function; 其中,arglist是匿名函数的自变量,如果有多个自变量,变量之间用逗号分隔;anonymous_ function是含有自变量的表达式。例如: >> h1 = @(x)3*x+x*x; >> h2 = @(x, y)sin(x)+cos(y); >> h3 = @(a,b,c)a*b+c; 定义匿名函数后,可以用存储函数句柄的变量作为函数名,代入参数,计算对应表达式 的值。例如: >> h3(2, 10, 6) %计算2*10+6 ans = 26 3.2.2 MATLAB矩阵 线性代数中,把由m ×n 个数排列成的数表称为大小为m ×n 的矩阵。若矩阵的行数 m 等于列数n,称为方阵;若矩阵只有一列(即n 为1),称为列向量;若矩阵只有一行(即m 为1),称为行向量。 在MATLAB中,数据均以数组的形式进行存储和处理,矩阵是二维数组,标量视为 1×1数组,有n 个元素的行向量视为1×n 数组,有m 个元素的列向量视为m ×1数组。 1. 构造矩阵和向量 1)构造矩阵 MATLAB使用一对方括号“[]”(称为数组构造符)构造矩阵,同一行的各元素之间用 空格或逗号分隔,行与行之间用分号分隔。例如: >> A = [1,2,3; 4,5,6; 7,8,9] A = 1 2 3 4 5 6 7 8 9 执行以上命令,变量A 存储了一个大小为3×3的数值矩阵。 MATLAB数值矩阵的元素也可以是复数。例如,建立复数矩阵: >> B = [1, 2+7i, 5*sqrt(-2); 3, 2.5i, 3.5+6i] B = 1.0000 + 0.0000i 2.0000 + 7.0000i 0.0000 + 7.0711i 3.0000 + 0.0000i 0.0000 + 2.5000i 3.5000 + 6.0000i 57 MATLAB还提供了repelem、repmat函数来构造有大量相同元素的矩阵。 (1)repelem 函数。 用于在构造数组时重复使用给定向量/矩阵中的元素,基本调用格式如下。 u = repelem(v, n) 输入参数v通常是标量或向量,指定构造矩阵的元素;输入参数n指定重复使用v中各 元素的次数。例如: >> a = [1 2 3 4]; >> t = repelem(a,3) t = 1 1 1 2 2 2 3 3 3 4 4 4 参数n也可以是向量,此时,变量n应与变量v的长度相同,变量n的元素逐一指定变 量v中对应元素的重复次数。例如: >> a = [1 2 3 4]; >> t = repelem(a,[3,2,2,1]) t = 1 1 1 2 2 3 3 4 repelem 函数的另一种调用格式如下。 B = repelem(A, r1, r2, … , rN) 输入参数A 是数组,每个元素依次按参数r1,r2,…,rN 进行重复,r1,r2,…,rN 依 次对应各个维度。例如: >> a = [1 2 3 4]; >> t = repelem(a,3,2) t = 1 1 2 2 3 3 4 4 1 1 2 2 3 3 4 4 1 1 2 2 3 3 4 4 (2)repmat函数。 用于在构造数组时重复使用给定的数组,有以下两种调用格式。 B = repmat(A, n) B = repmat(A, r1, r2, … , rN) 第1种格式中的输入参数n若是标量,变量B中存储A 的n×n个副本;若参数n是一 个二元行向量[p,q],则B中存储A 的p×q个副本。第2种格式中的参数r1,r2,…,rN 指 定从各个维度重复使用数组A 的次数,B中存储A 的r1×r2× … ×rN 个副本。例如: 58 >> A = [100 200 300]; >> B = repmat(A,2) B = 100 200 300 100 200 300 100 200 300 100 200 300 >> B = repmat(A,2,3) %与repmat(A,[2,3])等效 B = 100 200 300 100 200 300 100 200 300 100 200 300 100 200 300 100 200 300 2)构造等间距行向量 在MATLAB中,构造线性等间距的行向量通常采用冒号表达式。冒号表达式格式 如下。 a : b : c 其中,a为初始值,b为步长,c为终止值。冒号表达式可产生一个由a开始到c结束,以b为 步长递增/递减的行向量。例如: >> t=0:2:10 t = 0 2 4 6 8 10 冒号表达式中如果省略b,则步长默认为1。例如,t=0∶5与t=0∶1∶5等价。 生成线性等间距的行向量也可使用colon函数,colon(a,c)等效于冒号表达式a∶c, colon(a,b,c)等效于冒号表达式a∶b∶c。 linspace函数也用于生成线性等间距的行向量,其调用格式如下。 linspace(a, b, n) 其中,输入参数a和b指定向量的第1个和最后1个元素,参数n指定向量元素个数。当n 省略时,默认生成100个元素。显然,linspace(a,b,n)与a:(b-a)/(n-1):b等价。例如: >> x1 = linspace(0,6,4) x1 = 0 2 4 6 如果输入参数b> x2 = linspace(0,-8,6) x2 = 0 -1.6000 -3.2000 -4.8000 -6.4000 -8.0000 如果要在行向量的末尾添加元素,则通过矩阵构造符和矩阵元素分隔符来实现。例如: >> x12 = [x1, 100, 20] x12 = 0 2 4 6 100 20 59 MATLAB还提供了logspace函数,用于生成对数等间距的行向量,其调用格式为 logspace(a, b, n) 函数的用法与linspace函数相同。例如: >> x3 = logspace(0,4,5) x3 = 1 10 100 1000 10000 冒号表达式、linspace函数也可用于生成datetime和duration类型值的序列,方法与生 成线性等间距的数值向量方法相同。caldays函数用于设置间隔天数。例如: >> tt = t1:caldays(2):t2 tt = 1×3 datetime 数组 2022-11-01 08:00:00 2022-11-03 08:00:00 2022-11-05 08:00:00 3)合并矩阵 在MATLAB中,可以使用数组构造符和合并函数来合并矩阵。 (1)数组构造符。 可以用逗号或空格连接两个行数相同的矩阵,用分号连接两个列数相同的矩阵,从而拼 接成大矩阵。例如: >> A = [1,2,3,4; 5,6,7,8]; >> B = [10; 20]; >> X = [A, B] X = 1 2 3 4 10 5 6 7 8 20 >> C = [100,101,102,103]; >> Y = [A; C] Y = 1 2 3 4 5 6 7 8 100 101 102 103 (2)合并矩阵的函数。 MATLAB的cat、horzcat、vertcat等函数,用于合并矩阵。cat函数的调用格式如下。 C = cat(dim, A1, A2, …, An) 其中,输入参数dim 指定合并的维度,A1,A2,…,An是要进行合并的矩阵,这些矩阵应大 小兼容。例如: 60 >> A = ones(2,3); B=zeros(2,4); >> X1 = cat(1, A, B) 错误使用cat 要串联的数组的维度不一致 矩阵A、B的第1维度长度(即行数)相同,第2维度长度(即列数)不同,因此,不能沿第 1维度合并,只能沿第2维度进行合并。执行以下命令,合并操作能够完成。 >> X1 = cat(2, A, B) X1 = 1 1 1 0 0 0 0 1 1 1 0 0 0 0 若两个矩阵的第1维度长度相同,可以调用horzcat函数进行水平方向的串联;若两个 矩阵的第2维度长度相同,则可以调用vertcat函数进行垂直方向的串联。 2. 构造特殊矩阵 在数据可视化分析中,经常需要用到一些特殊形式的矩阵,如零矩阵、幺矩阵、单位矩阵 等。MATLAB提供了构造这些特殊形式矩阵的函数。 1)零/幺矩阵和单位矩阵 为了提高程序的运行性能,在使用大矩阵时,通常先利用zeros、ones函数构造相应大 小的零矩阵或幺矩阵,从而预备工作空间,而不是在程序运行时逐步扩充变量的工作空间。 .zeros函数:生成零矩阵,即元素值全为0的矩阵。 . ones函数:生成幺矩阵,即元素值全为1的矩阵。 .true函数:生成元素值全为逻辑1的矩阵。 .false函数:生成元素值全为逻辑0的矩阵。 .eye函数:生成单位矩阵,即主对角线上元素值为1、其他位置元素值为0的矩阵。 这几个函数的调用格式相似,下面以生成零矩阵的zeros函数为例进行说明。zeros函 数的基本调用格式如下。 zeros(m,n, classname) 调用该函数,将生成大小为m×n的零矩阵。若n省略,则生成大小为m×m 的零矩 阵;若m 和n都省略,则生成一个值为0的标量。其中,参数classname用类型字符串描述 (如d' ouble'、s'ingle'、i'nt8'等),指定矩阵元素的类型,省略时,元素默认为double类型。 例如,建立一个2×3的零矩阵,命令如下。 >> T1 = zeros(2,3); %或T1=zeros([2,3]); 建立一个3×3的零矩阵,且矩阵中的元素为整型,命令如下。 >> T2 = zeros(3,'int16'); 61 zeros函数还有其他用法。 .zeros(m,l'ike',p)生成的零矩阵元素的类型与变量p一致。 .zeros(sz1,sz2,…,szN)生成大小为sz1×sz2×… ×szN 的全0数组,参数sz1、sz2、 …、szN 依次指定各维的长度。 .zeros(sz)生成一个由向量sz中元素依次指定各维大小的全0数组。 例如,建立一个2×3的零矩阵,且矩阵元素和变量x类型相同,命令如下。 >> x = 1+2i; >> T3 = zeros(2,3,'like',x); x存储的是复数,执行命令后,T3中的元素都是复数。 2)随机数 虚拟游戏中的发牌、网络应用的数据加密,都需要使用随机数。在统计分析和控制过程 中,在蒙特卡罗类型的数值模拟中,在具有非确定性行为的人工智能算法中,或在遗传算法 中模拟神经网络,常常也需要随机数。在计算机程序中,使用的是采用某个算法得到的伪随 机数。 MATLAB提供了以下4个构造随机数矩阵的函数。 .rand(m,n)函数:返回一组值在(0,1)区间均匀分布的随机数,构造大小为m×n的 矩阵。n省略时,生成m×m 矩阵;m 和n都省略时,则生成一个随机标量。 .randn(m,n)函数:返回一组均值为0、方差为1的标准正态分布随机数,构造大小 为m×n的矩阵。 .randi(imax,m,n)函数:返回一组值在[1,imax]区间均匀分布的伪随机整数,构 造大小为m×n的矩阵。 .randperm(imax,k)函数:将[1,imax]区间的整数随机排列成一个数列,提取该数 列前k个元素构造一个向量。同一个向量中元素的值不会重复。k省略时,默认k 的值是imax。 这些函数都是从预先建立的伪随机数列中依次取出多个数,按函数的输入参数指定的 方式构造矩阵。因此,在不同计算机、不同程序中以同样的方式调用同一个函数,得到的随 机矩阵是相同的。若需要生成不同的随机数列,则在调用以上函数之前调用rng函数。rng 函数的调用格式为 rng(seed, generator) 其中,输入参数seed指定生成随机数的种子,可取值是0(默认)、正整数、s' huffle'(指定用当 前时间作为生成随机数的种子)、结构体;参数generator指定生成随机数的算法,可取值是' twister'(即梅森旋转算法,默认值)、s'imdTwister'、c' ombRecursive'、'multFibonacci'、p' hilox'、 t' hreefry'。 (1)调用rand函数将得到一组在(0,1)区间均匀分布的随机数x。若想生成一组在 (a,b)区间上均匀分布的随机数y,可以用yi=a+(b-a)xi 计算得到。例如,生成在区间 (10,30)内均匀分布的随机数,构造大小为3×4的矩阵,命令如下。 62 >> rng(0) >> a = 10; b = 30; >> A1 = a + (b-a)*rand(3,4) A1 = 26.2945 28.2675 15.5700 29.2978 28.1158 22.6472 20.9376 13.1523 12.5397 11.9508 29.1501 29.4119 由于每调用一次随机函数,MATLAB都是从预定义的伪随机数列中依次取数,即第n 次调用,会在第n-1次调用取出的数后取数。命令rng(0)将使得取数指针回退到随机数 列的第1个位置。 (2)调用randn函数将得到一组均值为0、方差为1的标准正态分布随机数x。若想生 成一组均值为μ、方差为σ2 的随机数y,可用yi=μ+σxi 计算得到。例如,生成均值为0.6、 方差为0.1的正态分布随机数,生成4阶矩阵,命令如下。 >> A2 = 0.6 + sqrt(0.1)*randn(4); (3)调用randi函数将得到一组在[1,imax]区间随机分布的整数。若想生成一组在 [a,b]区间的随机数y,可以用yi =(a-1)+(b-a+1)xi 计算得到。例如,生成在区间 [10,30]内随机分布的整数,构造大小为1×6的矩阵,命令如下。 >> A3 = 9 + randi(21, 1, 6) ; 第1个参数21是30-10+1,即区间[10,30]有21个整数。调用randi函数得到的随 机数列中,可能出现值相同的元素。 (4)调用randperm 函数将得到一组在[1,imax]区间随机排列的整数,且每一元素值 不同,用这组数构造向量。例如,生成在区间[10,30]的随机整数,构造有6个元素的向量, 命令如下。 >> A4 = 9 + randperm(21, 6); 3. 矩阵结构变换 在进行数据可视化时,常常需要将数据所组成的矩阵结构做一些变换后,再来分析、评 估矩阵的特性。MATLAB提供了多种变换矩阵结构的函数。 1)提取矩阵对角线 diag函数用于提取矩阵对角线元素,构造1个向量。其基本调用格式如下。 v = diag(A, k); 提取矩阵A 的第k条对角线上的元素,生成1个列向量。参数k为对角线编号,k省略 时,默认为0。例如: 63 >> A = [1,2,3; 11,12,13; 110,120,130]; >> d = diag(A) d = 1 12 130 由左上至右下的对角线称为主对角线(即0号对角线),由右上至左下的对角线称为副 对角线。与主对角线平行,往上对角线编号依次为1、2、3、…,往下对角线编号依次为-1、 -2、-3、…。例如,提取矩阵A 主对角线两侧对角线的元素,命令如下。 >> d1 = diag(A,1) d1 = 2 13 >> d2 = diag(A,-1) d2 = 11 120 2)构造对角矩阵 主对角线上的元素是非零值,其余元素都是0的矩阵,称为对角矩阵。对角线上的元素 值为1的对角矩阵称为单位矩阵。diag函数也可用于构造对角矩阵,其调用格式如下。 D = diag(v, k) 其中,输入参数v是向量,参数k指定将向量v放置在第k号对角线。k省略时,默认k为 0,即将向量v放置在主对角线。例如: >> diag(10:2:14, -1) ans = 0 0 0 0 10 0 0 0 0 12 0 0 0 0 14 0 用diag函数来构造5阶单位矩阵,命令如下。 >> E = diag([1, 1, 1, 1, 1]); %与eye(5) 等效 3)构造三角矩阵 三角矩阵分为上三角矩阵和下三角矩阵。上三角矩阵是位于指定对角线以下的元素值 为0的矩阵,下三角矩阵是位于指定对角线以上的元素值为0的矩阵。 triu函数用于构造上三角矩阵。triu函数的基本调用格式为 U = triu(A, k) 64 其中,输入参数k指定从编号为k的对角线往上进行截取,当k省略时,默认k为0。生成 的矩阵U 与A 具有相同的行数和列数。例如,提取矩阵A 的上三角元素,生成上三角矩阵 B,命令如下。 >> A = randi(99,5,5); >> B = triu(A) B = 81 10 16 15 65 0 28 97 42 4 0 0 95 91 85 0 0 0 79 93 0 0 0 0 68 结果显示:triu函数在构造新矩阵时,提取源矩阵的上三角部分,用其构造新矩阵的上 三角部分,而新矩阵的下三角部分元素值全为0。 在MATLAB中,构造下三角矩阵的函数是tril,其用法与triu函数相同。 4)转置矩阵 所谓转置,即把源矩阵的第1行变成目标矩阵第1列,源矩阵的第2行变成目标矩阵第 2列,以此类推。大小为m ×n 的矩阵经过转置运算后,形成大小为n ×m 的矩阵。 MATLAB中,转置运算使用运算符“.'”或“'”,或调用转置运算函数transpose。例如: >> A = randi(9,2,3) A = 3 6 2 7 2 5 >> B = A.' %或B = transpose(A) B = 3 7 6 2 2 5 复共轭转置运算是针对含复数元素的矩阵,除了将矩阵转置,还对原矩阵中的复数元素 的虚部求反。复共轭转置运算使用运算符“'”,或调用函数ctranspose。例如: >> A = [3,4-1i,2+2i; 7i,1+1i,6-1i] A = 3.0000 + 0.0000i 4.0000 - 1.0000i 2.0000 + 2.0000i 0.0000 + 7.0000i 1.0000 + 1.0000i 6.0000 - 1.0000i >> B1 = A' %或B1 = ctranspose(A) B1 = 3.0000 + 0.0000i 0.0000 - 7.0000i 4.0000 + 1.0000i 1.0000 - 1.0000i 2.0000 - 2.0000i 6.0000 + 1.0000i 矩阵B1中的元素与矩阵A 的对应元素虚部符号相反。如果仅对复数矩阵进行转置, 命令如下。 65 >> B2=A.'; %或B2=transpose(A) 5)旋转矩阵 在MATLAB中,rot90函数用于以90°为单位对矩阵A 进行旋转。函数的调用格式 如下。 rot90(A, k) 其中,输入参数k指定90°的倍数(必须为整数),当k省略时,k默认为1。旋转矩阵时,以矩 阵左上角为支点,若k为正整数,则将矩阵A 按逆时针方向进行旋转;若k为负整数,则将 矩阵A 按顺时针方向进行旋转。 例如,将矩阵A 按顺时针方向旋转90°,命令如下。 >> A = rand(3,2) A = 0.5060 0.9593 0.6991 0.5472 0.8909 0.1386 >> B = rot90(A,-1) B = 0.8909 0.6991 0.5060 0.1386 0.5472 0.9593 若要将矩阵A 按逆时针方向旋转90°,则命令如下。 >> C=rot90(A); 6)翻转矩阵 矩阵的翻转分为左右翻转和上下翻转。fliplr函数用于对矩阵A 实施水平方向的翻 转,其调用格式如下。 B = fliplr(A) 对矩阵实施左右翻转是将原矩阵的第1列和最后1列调换,第2列和倒数第2列调换,以 此类推。例如: >> A = randi(99,2,5) A = 78 13 47 34 79 93 57 2 17 31 >> B = fliplr(A) B = 79 34 47 13 78 31 17 2 57 93 66 flipud函数用于对矩阵A 实施垂直方向的翻转,用法与flipud函数相似。矩阵的上下 翻转是将原矩阵的第1行与最后1行调换,第2行与倒数第2行调换,以此类推。 MATLAB还提供了flip函数翻转数组,其调用格式如下。 B = flip(A, dim) 其中,参数dim 指定翻转的维度,若A 是矩阵,则当dim 为1(默认值)时,沿垂直方向翻转; dim 为2时,沿水平方向翻转。dim 省略时,默认在大小不等于1的首个维度上进行翻转。 3.2.3 MATLAB数组 向量、矩阵是二维数组,多维数组是指具有两个以上维度的数组。例如,将彩色图像数 据导入工作区,生成的就是三维数组。 1. 构造数组 多维数组是二维矩阵的扩展。构造多维数组,可以先构造二维矩阵,再进行扩展。 1)构造三维数组 三维数组使用三个下标,可以看成连续排列的多个矩阵,前两个维度对应于一个矩阵的 行、列,第三个维度对应于矩阵的排列次序。 在MATLAB中,通常通过给存储矩阵的变量增加第三维坐标的方式,将矩阵扩展为三 维数组。例如,先定义一个大小为3×3的矩阵,存储于变量A,然后将A 扩展为3×3×2 的三维数组,命令如下。 >> A = [1 2 3; 4 5 6; 7 8 9]; >> A(:, :, 2) = [10 11 12; 13 14 15; 16 17 18]; 第2条命令中的A(:,:,2)的第1个冒号表示所有行,第2个冒号表示所有列,第3个 参数指定赋值号右端的这个矩阵存储为变量A 的第2个矩阵,此时A 的大小变为3×3× 2,前面构造的矩阵此时自动转变为变量A 的第1个矩阵。 2)构造特殊数组 前面介绍的构造特殊矩阵的zeros、ones、rand等函数都可以扩展应用到多维数组。例 如,生成大小为3×2×3的随机数组,命令如下。 >> X = rand([3,2,3]); 3)重构数组 构造数组后,可以利用reshape函数改变数组结构。reshape函数的调用格式如下。 B = reshape(A, sz) 其中,输入参数sz是一个向量,向量中的元素依次指定各个维度的大小。例如,将有6个元 素的向量重构为大小为2×3的矩阵,命令如下。 67 >> A = reshape(1:6, [2, 3]) A = 1 3 5 2 4 6 reshape函数还有另一种调用格式: B = reshape(A, sz1, … , szN) 其中,参数sz1~szN 都是标量,用于依次指定各个维度的大小。例如,将有12个元素的行 向量重构为大小为2×3×2的数组,命令如下。 >> A3=reshape(1:12, 2, 3, 2); 2. 获取数组属性 将数据导入工作区后,需要了解数据的规模、数据类型等属性,为数据的进一步处理提 供依据。MATLAB提供了size、length、class等函数获取数组的大小、类型等属性。 1)查询数据规模 size函数用于获取数组的大小。size函数的调用格式如下。 szdim = size(A, dim) 其中,输入参数dim 指定维度,dim 省略时,默认返回所有维度的长度。例如,获取前面建立 的矩阵A3的大小: >> size(A3) ans = 2 3 2 >> size(A3, 2) ans = 3 length函数用于获取数组最长维度元素的个数。length函数的调用格式如下。 L = length(A) 若输入参数A 是向量,则返回向量中元素的个数。例如: >> length(1:2:10) ans = 5 若length函数的输入参数是数组,则返回数组中最长维度元素的个数。例如: >> length(A3)