本章主要学习以下内容
1. 理解MATLAB不同类型的数据
2. 创建和使用数值型和字符型数组
3. 创建多维数组并能从这些数组中访问数据
4. 创建和使用元胞数组和结构数组
一.数据类型
MATLAB的数据类型包括字符型,逻辑型,数值型,对象。其中数值型包括整数和浮点数。整数包括有符号和无符号两种,浮点数包括单精度和多精度两种。
1.双精度浮点数
MATLAB中默认为双精度浮点数,可定义如下:
>> A = 1;
>> B = 1:10;
>> C = [1,2,3;4,5,6];
>> realmax
ans =
1.7977e+308
>> realmin
ans =
2.2251e-308
>> x = 5e400
x =
Inf
>> y = 1e-400
y =
0
2.单精度浮点数
单精度浮点数是MATLAB中的新的数据类型,单精度浮点数占用双精度浮点数存储空间的一般,每个数据需要4个数据存储。
>> d = single(5)
d =
5
>> double(d)
ans =
5
用函数single可以把数值5定义成一个单精度数值,同样,函数double可以将变量转换成双精度。
可用realmax和realmin来显示数值范围
>> realmax('single')
ans =
3.4028e+38
>> realmin('single')
ans =
1.1755e-38
用单精度计算双精度问题会引起舍入误差。例如调和级数的计算。
>> n = 1:10;
>> harmonic = 1./n
harmonic =
1.0000 0.5000 0.3333 0.2500 0.2000 0.1667 0.1429 0.1250 0.1111 0.1000
>> format rat
>> harmonic
harmonic =
1 1/2 1/3 1/4 1/5 1/6 1/7 1/8 1/9 1/10
>> format short
>> harmonic
harmonic =
1.0000 0.5000 0.3333 0.2500 0.2000 0.1667 0.1429 0.1250 0.1111 0.1000
>> partial_sum = cumsum(harmonic)
partial_sum =
1.0000 1.5000 1.8333 2.0833 2.2833 2.4500 2.5929 2.7179 2.8290 2.9290
如上,在计算过程中,harmonic的数值越来越小。当n足够大师,计算机将无法区分1/n的值与零的差别。相对于双精度运算来说,在单精度运算中很快就会出现这种情况。当数组中n的值很大,对这一性质加以验证。
>> n = 1:1e7;
>> harmonic = 1./n;
>> partial_sum = cumsum(harmonic);
由于数据太多,因此我们每1000个数据选择一个数据点,代码如下:
>> m = 1000:1000:1e7;
>> partial_sums_selected = partial_sum(m);
>> plot(partial_sums_selected)
如果使用单精度,我们把两条线绘制在一幅图中:
>> n = single(1:1e7);
>> harmonic = 1./n;
>> partial_sum = cumsum(harmonic);
>> m = 1000:1000:1e7;
>> partial_sums_selected = partial_sum(m);
>> hold on
>> plot(partial_sums_selected,':')
3.整数
整数类型分有符号和无符号。其中每种各有4中类型,分别为8位,16位,32位,64位。
如定义8位有符号整数如下:
>> E = int8(10)
E =
10
>> intmax('int8')
ans =
127
8位无符号整数:(存储数值比有符号更大)
>> intmax('uint8')
ans =
255
4.复数
复数默认的存储类型是双精度,因为实部和虚部都需要存储,所以,需要两倍的存储空间。
>> F = 5 + 3i
F =
5.0000 + 3.0000i
也可以存储为单精度的整数类型:
>> G = int8(5+3i)
G =
5 + 3i
5.字符和字符串
包括空格在内,每个字符在数组内都是一个独立的元素。
字符采用ASCALL编码,这种编码类型与C相同。详情见:ASCALL码表
>> double('a')
ans =
97
>> char(98)
ans =
b
如果创建的矩阵既包含数值有包含字符,那么MATLAB会将所有数据转换成字符类型。
>> ['a',98]
ans =
ab
6.符号数据
符号工具箱使用符号数据进行符号代数运算,函数sym创建一个符号变量。
>> L = sym('x^2-2')
L =
x^2 - 2
>>
7.逻辑数据
逻辑数据从表面上看是由0和1构成的数据,使用1 和0 分别表示true和false
>> M = [true,false,true]
M =
1 0 1
注意,不同编程语言的true和false的形式不同,如Python中“真”是大写的True,假是大写的“False”。python 代码:
>>> M = [True,False,True]
好的,回到MATLAB,另外一个例子:
>> x = 1:5;
>> y = [2,0,1,0,4];
>> z = x > y
z =
0 1 1 1 1
>> find(x>y)
ans =
2 3 4 5
8.稀疏数组
定义一个1000*1000的单位矩阵,具有100万个元素:
>> N = eye(1000);
每个元素需要八个字节表示,
>> P = sparse(N)
P =
(1,1) 1
(2,2) 1
(3,3) 1
(4,4) 1
(5,5) 1
(6,6) 1
(7,7) 1
(8,8) 1
二、多维数组
当需要按二维或三维以上的多维数组形式存储时,MATLAB将在另一个页面上表示数据。将以下四个二维数组变成一个三维数组:
>> x = [1,2,3;4,5,6];
>> y = 10 * x;
>> z = 10 * y;
>> w = 10 * z;
>> my_3D_array(:,:,1) = x;
>> my_3D_array(:,:,2) = y;
>> my_3D_array(:,:,3) = z;
>> my_3D_array(:,:,4) = w;
>> my_3D_array
my_3D_array(:,:,1) =
1 2 3
4 5 6
my_3D_array(:,:,2) =
10 20 30
40 50 60
my_3D_array(:,:,3) =
100 200 300
400 500 600
my_3D_array(:,:,4) =
1000 2000 3000
4000 5000 6000
三、字符数组
当每行的字符元素的个数相等时,可以创建二维字符数组。下面列出的名字不能直接创建二维字符数组,是因为名字的长度不相同。
>> Q = ['Holly';'Steven';'Meagan';'David';'Michael';'Heidi'];
错误使用 vertcat
串联的矩阵的维度不一致。
使用char函数可以对字符数组进行填充,以保证每行具有相同数量的元素:
>> Q = char('Holly','Steven','Meagan','David','Michael','Heidi')
Q =
Holly
Steven
Meagan
David
Michael
Heidi
Q是6*7的字符数组。在函数char中每个字符串之间使用逗号隔开。不仅字母可以存储在MATLAB的字符数组中,任何键盘上可以找到的符号或者数字都可以存储为字符。利用这种性质创建的表格从表面上看既包括字符又包括数值,但实际上都是字符类型。
字符数组Q是学生姓名,数组R是考试分数:
>> R = [98;84;73;88;95;100]
R =
98
84
73
88
95
100
将两个数组合并到一起
>> table = [Q,R]
table =
Holly b
Steven T
Meagan I
David X
Michael_
Heidi d
函数num2str能够将数值转换成字符,利用它可以将双精度矩阵R转换成字符矩阵。
>> S = num2str(R)
S =
98
84
73
88
95
100
>> table = [Q,S]
table =
Holly 98
Steven 84
Meagan 73
David 88
Michael 95
Heidi 100
四、元胞数组
元胞数组与数值、字符和符号数组不同,它可以在同一数组中存储不同类型的数据,数组中每个元素就是一个数组。
>> A = 1:3;
>> B = ['abcdefg'];
>> C = single([1,2,3;4,5,6]);
>> my_cellarray = {A,B,C}
my_cellarray =
[1x3 double] 'abcdefg' [2x3 single]
>> celldisp(my_cellarray)
my_cellarray{1} =
1 2 3
my_cellarray{2} =
abcdefg
my_cellarray{3} =
1 2 3
4 5 6
元胞数组使用索引方法与其他数组相同,可以使用单序号索引,也可以使用行和列索引。从元胞数组中提取信息的方法有两种,一种是使用小括号
>> my_cellarray(1)
ans =
[1x3 double]
另一种是使用大括号
>> my_cellarray{1}
ans =
1 2 3
为了访问存储在元胞数组中的某一特定元素,必须同时使用大括号和小括号
>> my_cellarray{3}(1,2)
ans =
2
元胞数组可能会编的相当复杂,函数cellplot是一种以图形结构查看数组内容的有效方法。
>> cellplot(my_cellarray)
元胞数组可用于复杂的编程项目或数据库应用。
五、结构数组
结构数组类似于元胞数组,具有不同数据类型的多个数组可以存储在结构数组中,与存储在元胞数组中一样。结构数组不使用内容索引,结构数组中的每个句子存储在一个称谓“域”的位置上。
如果大家会Python的话,可以看出类似于Python的字典类型
>> my_structure.some_numbers = A
my_structure =
some_numbers: [1 2 3]
继续添加元素:
>> my_structure.some_letters = B
my_structure =
some_numbers: [1 2 3]
some_letters: 'abcdefg'
>> my_structure.some_more_numbers = C
my_structure =
some_numbers: [1 2 3]
some_letters: 'abcdefg'
some_more_numbers: [2x3 single]
向所在域添加更多的矩阵,可以扩大原有数组的规模
>> my_structure(2).some_numbers = [2 4 6 8]
my_structure =
1x2 struct array with fields:
some_numbers
some_letters
some_more_numbers
>> my_structure(2)
ans =
some_numbers: [2 4 6 8]
some_letters: []
some_more_numbers: []
访问一个域,需要添加相应的域名:
>> my_structure(2).some_numbers
ans =
2 4 6 8
访问域中的每个元素,则必须在域名后指出改元素的索引号:
>> my_structure(2).some_numbers(2)
ans =
4
>> disp(my_structure(2).some_numbers(2))
4
和访问其他类型一样,访问结构数组也可以使用MATLAB自带的编辑器。