在这一章会学习到:
数据类型(数值,字符串,结构,单元数组,函数句柄,映射容器)
运算符与运算(算术运算符,关系运算符,逻辑运算符)
字符串处理(构造,比较,查找,替换,类型转换)
矩阵基础(构造矩阵,改变矩阵维度与大小,矩阵索引,获取矩阵属性信息)
随着人工智能的不断发展,matlab这门技术也越来越重要,很多人都开启了学习matlab,本章就介绍了入门matlab的基础内容,通过对基础部分的学习,可以将其他语言的基础编程知识与matlab融汇起来。
和c++类似,数值类型有三种,整数,单精度浮点数和双精度浮点数,但在matlab中,默认数值双精度浮点数。
整数有8,16,32,64位,还有无符号的对应整数,分别为:int8,int16,int32,int64,uint8,uint16.uint32,uint64,无符号就是正整数,
这些也是转换函数,将其他类型转换成对应整数,
>> int16(2^15)
ans =
32767
>>
还有其他转换函数,
如:floor()向下取整,floor(3.5)=3;
ceil()向上取整,ceil(3.5)=4;
round()取最接近的整数,round(1.4)=1,round(3.5)=4
fix()向0取整,取的值更接近0,fix(1.4)=1,fix(-3.5)=-3
单精度浮点数,32位,
双精度浮点数,64位,
默认双精度,与整数运算,得到整数;与单精度得到单精度‘与其他得到双精度;运算得到的结果如下:
>> a=int32(2);b=single(3.1);c=4.2;
>> i=a*c;j=b*c;k=c*c;
>> whos
Name Size Bytes Class Attributes
a 1x1 4 int32
ans 1x1 8 double
b 1x1 4 single
c 1x1 8 double
i 1x1 4 int32
j 1x1 4 single
k 1x1 8 double
s1 1x10 20 char
>>
注意:整数不能与单精度数直接相乘,如下:
>> a=int32(2);b=single(3.14);b*a
错误使用 *
整数只能与相同类的整数或标量双精度值组合使用。
>>
注意,在matlab中,使用eps当作0,避免0为分母,
>> a=eps(5);b=eps(single(5));
>>
>> b
b =
4.7684e-07
>> a
a =
8.8818e-16
>>
pi是matlba中的圆周率,即3.14
>> pi
ans =
3.1416
>> double(pi)
ans =
3.1416
>> sin(pi/2)
ans =
1
>> cos(pi/2)
ans =
6.1232e-17
>> tan(pi/2)
ans =
1.6331e+16
>>
sqrt()是开平方根,如
>> sqrt(9)
ans =
3
>>
在matlab中。字符i或j默认为虚部,构造复数可以按复数形式构造,或使用complex函数
complex(a,b),构造a实部,b虚部;
real(z)返回复数z的实部;
imag(z)返回复数的虚部;
abs(z)返回复数的模;
angle(z)返回复数的辐角;
conj(z)返回复数的共轭复数;
操作如下:
>> a=complex(6,8);b=3+4i;c=a-b
c =
3.0000 + 4.0000i
>> real(c)
ans =
3
>> imag(c)
ans =
4
>> abs(c)
ans =
5
>> angle(c)
ans =
0.9273
>> conj(c)
ans =
3.0000 - 4.0000i
>>
matlab中正无穷Inf,负无穷-Inf,NaN表示非数值量,非数值量由0/0或Inf/Inf产生,
>> 0/0
ans =
NaN
>> 1/0
ans =
Inf
>> log(0)
ans =
-Inf
>> exp(-inf)
ans =
0
>> NaN-NaN
ans =
NaN
>> exp(1000)
ans =
Inf
>>
在文本框里显示的是字符,但在存放是存储的是ASC2码,
>> s='abc'
s =
abc
>> ab=abs(s)
ab =
97 98 99
>>
字符串可以通过下标索引访问,如下:
>> s(1)
ans =
a
>>
若用矩阵下标索引访问,则矩阵每行字符数需要相同。
与其他编程语言类似,一个结构对象相当于数据容器,可以存放多种类型的数据,接下来介绍如何构造一个结构对象,
这里为标准,选择struct函数构造结构对象
一个变量名,后跟一个赋值,如下:
>> patient=struct('name','zoe','billing','168912.23','test',[95,99,96;192,185.5,197;280,295,278])
patient =
name: 'zoe'
billing: '168912.23'
test: [3x3 double]
>>
>> whos patient
Name Size Bytes Class Attributes
patient 1x1 624 struct
>>
构造好一个结构对象后,如何访问呢?
使用对象名和对象中的变量名来访问,如下:
>> patient(2).name='zuck'
patient =
1x2 struct array with fields:
name
billing
test
>> patient(2)
ans =
name: 'zuck'
billing: []
test: []
>> patient.name
ans =
zoe
ans =
zuck
>> patient(1).name
ans =
zoe
>> patient(2).name
ans =
zuck
>> patient(1).test
ans =
95.0000 99.0000 96.0000
192.0000 185.5000 197.0000
280.0000 295.0000 278.0000
>>
直接连接即可,放入一个[]中,如下:
一个[]中装下两个结构对象,
>> patient1=struct('name','ryze','billing','277.12','test',[1,2,3;4,5,6;,7,8,9]);
>> patient2=struct('name','zed','billing','877.86','test',[45,27,83;64,55,26;17,8,9]);
>>
>> patient1
patient1 =
name: 'ryze'
billing: '277.12'
test: [3x3 double]
>> patient1.test=[1,2,3;4,5,6;7,8,9]
patient1 =
name: 'ryze'
billing: '277.12'
test: [3x3 double]
>> patient2
patient2 =
name: 'zed'
billing: '877.86'
test: [3x3 double]
>> patient=[patient1,patient2];
>> whos patient patient1 patient2
Name Size Bytes Class Attributes
patient 1x2 1046 struct
patient1 1x1 620 struct
patient2 1x1 618 struct
>>
这里选择使用赋值语句构造,用花括号来构造。用逗号,分割单元,用分号;来分行,如下:
>> a={1,2,3;'a',[2;5;7],'0'}
a =
[1] [ 2] [3]
'a' [3x1 double] '0'
>>
得到一个两行三列的矩阵
可以使用cell函数构造空单元数组,如下:
>> b=cell(2,3)
b =
[] [] []
[] [] []
>>
单元外标识,使用C(x,y)形式来访问特定元素,表示单元数组C中的第x行第y列的单元。使用C{x,y}访问单元数组C中的第x行第y列的单元中的内容,如下:
>> a(2,3)
ans =
'0'
>> a(2,2)
ans =
[3x1 double]
>> a{2,2}
ans =
2
5
7
>>
操作包括:合并,删除单元数组中指定单元,改变单元数组形状
使用花括号{}将两个单元数组放一起,如下:
>> a={1,2;3,4};
>> a
a =
[1] [2]
[3] [4]
>> b={5}
b =
[5]
>> c={a b}
c =
{2x2 cell} {1x1 cell}
>> whos
Name Size Bytes Class Attributes
a 2x2 480 cell
b 1x1 120 cell
c 1x2 824 cell
>> c{1,1}
ans =
[1] [2]
[3] [4]
>> c{1,2}
ans =
[5]
>>
将空[]赋值给指定单元,如下:
>> a
a =
[1] [2]
[3] [4]
>> a{2,2}=[]
a =
[1] [2]
[3] []
>>
使用reshape函数即可,如下:
a =
[1] [2]
[3] []
>> reshape(a,1,4)
ans =
[1] [3] [2] []
>>
用操作符@,对matlab库函数,通过函数句柄来对函数间接调用,构造函数句柄语法为:
>> f_handle=@Function_Filename
f_handle =
@Function_Filename
>>
其中,Function_Filename是函数对应的M文件名称,或matlab内部函数的名称;
@是函数句柄构造操作符;
f_handle变量保存了该函数句柄;
函数句柄的创建与调用,如下:
>> F_Handle=@sin
F_Handle =
@sin
>> x=0:0.25*pi:pi;
>> F_Handle(x)
ans =
0 0.7071 1.0000 0.7071 0.0000
>>
matlab库函数对函数句柄的操作函数,因此各种数据类型和句柄形成功能交互,一些简单操作函数,如下:
@,间接调用函数;
func2str,将函数句柄转换为函数名的字符串,
str2func,将字符串转换成函数句柄;
functions(),返回函数名,类型,及文件位置的结构体;
>> F_Handle=@sin
F_Handle =
@sin
>>
>> aa=func2str(F_Handle)
aa =
sin
>> str2func(aa)
ans =
@sin
>> functions(F_Handle)
ans =
function: 'sin'
type: 'simple'
file: ''
>>
映射容器(map containers),和其他编程语言中的map对象一样,由对应的key和value组成键值对,如同python中的字典dict,也和生活中的字典很像,
key可以是字符串,单精度或双精度数,整数,
value中可以是任何数据类型,数值,字符串,结构体,单元结构,其他映射容器;
和python中的dict非常相似。
map类对象,有三种属性,使用map.属性查看,如下:
count,map对象中键值对总数,
keytype,map对象中key的数据类型,
valuetype,map对象中value的数据类型
接下来介绍如何构造map类对象,并查看和读取map类对象以及编辑。
构造格式,如下:
mapObj=containers.Map({key1,key2,…},{val1,val2,…})
可以先将key和value独自构造好,再在Map()中构造,
>> key={'jan','feb','mar','apr','may','jun','jul','aug','sep','oct','Nov','Dec','Annual'};
>> value={1,2,3,4,5,6,7,8,9,10,11,12,24};
>> containers.Map(key,value)
ans =
Map (具有属性):
Count: 13
KeyType: char
ValueType: double
>> whos
Name Size Bytes Class Attributes
ans 13x1 112 containers.Map
key 1x13 1540 cell
value 1x13 1560 cell
可以使用.keys查看所有key,使用values查看所有value,如下:
>> key={'jan','feb','mar','apr','may','jun','jul','aug','sep','oct','Nov','Dec','Annual'};
>> value={1,2,3,4,5,6,7,8,9,10,11,12,24};
>> a_map=containers.Map(key,value)
>> a_map.keys
ans =
'Annual' 'Dec' 'Nov' 'apr' 'aug' 'feb' 'jan' 'jul' 'jun' 'mar' 'may' 'oct' 'sep'
>> a_map.values
ans =
[24] [12] [11] [4] [8] [2] [1] [7] [6] [3] [5] [10] [9]
>>
也可以使用keys()和values()来查看
>> keys(a_map)
ans =
'Annual' 'Dec' 'Nov' 'apr' 'aug' 'feb' 'jan' 'jul' 'jun' 'mar' 'may' 'oct' 'sep'
>> values(a_map)
ans =
[24] [12] [11] [4] [8] [2] [1] [7] [6] [3] [5] [10] [9]
>>
查找指定的一个值,使用指定key,如下:
>> a_map('sep')
ans =
9
>>
查找指定的多个值,使用values()函数,如下:
注意:里面要使用花括号,
>> values(a_map,{'sep','Nov'})
ans =
[9] [11]
>>
用remove()函数,如下:
用key指定要删除的key/value对
>> remove(a_map,'oct')
ans =
Map (具有属性):
Count: 12
KeyType: char
ValueType: double
>>
批量删除,在删除指定key处换成花括号即可,
>> b={'apr' , 'aug' , 'feb' }
b =
'apr' 'aug' 'feb'
>> remove(a_map,b)
ans =
Map (具有属性):
Count: 9
KeyType: char
ValueType: double
>>
直接往Map对象中添加key/value对,如下:
>> a_map('apr')=4
a_map =
Map (具有属性):
Count: 10
KeyType: char
ValueType: double
>> a_map('aug')=8
a_map =
Map (具有属性):
Count: 11
KeyType: char
ValueType: double
>>
修改value直接重新赋值,如下:
>> a_map('aug')=88
a_map =
Map (具有属性):
Count: 11
KeyType: char
ValueType: double
>> a_map('aug')
ans =
88
>>
修改key需要先删除原key,再重新赋值,以完成覆盖,
在matlab中提供了大量数据类型识别的函数,
和python类似,
基本是以is开头,如:
isinteger 整数
islogical 逻辑数组
isnumeric 数值数组
isobject matlab对象
isreal 实数
isscalar 标量
isstruct 结构数组
isstr 字符串
isvector 向量
whos 变量类型数据
类型转换
char 变换为字符
int2str 整数变为字符串
如下:
>> cc=num2str(32.22)
cc =
32.22
>> whos cc
Name Size Bytes Class Attributes
cc 1x5 10 char
>>
在matlab中,运算符有算术运算符,关系运算符,逻辑运算符。与其他编程语言类似。优先级为算术>>关系>>逻辑。
matlab中有常规四则运算,和带点四则运算(为矩阵运算),
a+b a和b相加;
a-b a和b相减;
a*b a和b相乘;
a/b a和b相除;注意,a和b为数值或者矩阵,
a^b a的b次幂;注意,a和b为数值或者矩阵,
a.*b a和b对应元素相乘;a和b为相同维度矩阵,
a./b a和b对应元素相除;a和b为相同维度矩阵,
a.^b a的每个元素的b次幂;a为矩阵,b为数值。
matlab中构造矩阵方法,eye()构造指定维度的对角矩阵,ones()构造指定维度的全1矩阵,
实例如下:
>> a=eye(3)
a =
1 0 0
0 1 0
0 0 1
>> b=ones(3)
b =
1 1 1
1 1 1
1 1 1
>>
>> a*b
ans =
1 1 1
1 1 1
1 1 1
>>
>> a.*b
ans =
1 0 0
0 1 0
0 0 1
>>
在matlab中有6个关系运算符,
小于<,大于>,等于==,小于等于<=,大于等于>=,不等于~=,
返回结果仅为1或0,
即真假,
获得一组数的方法,如1:5,
>> a=1:5
a =
1 2 3 4 5
>>
>> whos a
Name Size Bytes Class Attributes
a 1x5 40 double
>>
进行关系运算,如下:
>> c=8-a
c =
7 6 5 4 3
>> torf1=(a>4)
torf1 =
0 0 0 0 1
>> torf2=(a==c)
torf2 =
0 0 0 1 0
>>
>> torf3=(a>c)
torf3 =
0 0 0 0 1
>>
与其他编程语言类似,有三种,与&,或||,非~,
如下:
>> t1=~(a>4)
t1 =
1 1 1 1 0
>> t2=(a>1)&(a<5)
t2 =
0 1 1 1 0
>> t3=(a>3)|(b>3)
t3 =
0 0 0 1 1
>>
逻辑运算符可以让矩阵和数值进行比较,方法为将矩阵的每一个数值与该数值比较,比较结果为相同维度的矩阵,
在matlab中,一些逻辑函数,
xor(x,y)异或运算。x和y不同返回1,相同返回0
any(x)向量x有任何元素非零,返回1,否则返回0,;矩阵中每一列有非零元素,返回1,否则返回0
all(x)向量x所有元素非零,返回1,否则返回0;矩阵x中每一列所有元素非零,返回1,否则返回0。
如下所述,加括号改变运算优先级,
直接变量赋值,
可通过strcat横向连接两个字符串
>> s1='what is up?'
s1 =
what is up?
>> s2='fine,and you?'
s2 =
fine,and you?
>> s=strcat(s1,s2)
s =
what is up?fine,and you?
>>
也可以通过strvcat函数和char函数纵向连接两个字符串,
>> strvcat(s1,s2)
ans =
what is up?
fine,and you?
>>
char纵向连接
>> char(s1,s2)
ans =
what is up?
fine,and you?
>>
可以通过关系运算符来比较,也可以通过strcmp函数比较两个字符串,
如下:
使用关系运算符比较时,返回一个长度和字符串大小相同的数组,而strcmp返回的是判断两个字符串是否相同,返回值0或1,
>> a1=('daisy'=='buton')
a1 =
0 0 0 0 0
>> a1=('daisy'=='wassp')
a1 =
0 1 0 1 0
>> c1=strcmp('daisy','wassp')
c1 =
0
>> c1=strcmp('wassp','wassp')
c1 =
1
>>
通过findstr函数可以查找字符串,
可以直接对字符串中元素直接赋值以替换字符串,也可以使用strrep函数替换,
如下:
>> s='you smile like sunshine. ';
>> spacePos=findstr(s,' ') %搜索字符串中空格位置
spacePos =
4 10 15 25
>> ePos=findstr(s,'e') %搜索字母e的位置
ePos =
9 14 23
>> ouPos =findstr(s,'ou')
ouPos =
2
>> repStr=strrep(s,'you','her')
repStr =
her smile like sunshine.
>>
注意:findstr函数对字母大小写敏感,
matlab有许多字符串与其他类型数据转换的函数
如abs,字符串转换为asc2码,
>> r=5;area=pi*r^2;
>> area
area =
78.5398
>> whos area
Name Size Bytes Class Attributes
area 1x1 8 double
>> jj=num2str(area)
jj =
78.5398
>> whos jj
Name Size Bytes Class Attributes
jj 1x7 14 char
>>
我想加入张量的概念,即标量,一维向量,二维矩阵,三维张量,四维张量。
矩阵的基础操作有,矩阵构造,
矩阵可以由变量直接赋值构造;另一种方法是使用特殊函数构造,
在上述知识中,已经介绍了两种构造矩阵的方法,分别是构造全1矩阵ones()函数和构造对角矩阵单位矩阵的eye()函数,实例如下:
>> ones(2,2)
ans =
1 1
1 1
>> eye(3,3)
ans =
1 0 0
0 1 0
0 0 1
>>
稍微引入了上文一下,具体由变量直接构造,方法为:用[]包住所有元素,对于每一列用分号;隔开,每个元素之间用逗号,隔开,实例如下:
>> [1,2,3;4,5,6;7,8,9] %使用逗号隔开元素,使用分号隔开每一行
ans =
1 2 3
4 5 6
7 8 9
>>
另一种方法是使用特殊函数构造,使用matlab实现定义好的特殊函数去构造,如下:
>> ones(2)
ans =
1 1
1 1
>> zeros(2)
ans =
0 0
0 0
>>
>> eye(2)
ans =
1 0
0 1
>> eye(2,3)
ans =
1 0 0
0 1 0
>> eye(3,2)
ans =
1 0
0 1
0 0
>>
注意:也可以直接创建一个空矩阵[],如下:
>> a=[] %a是一个空矩阵
a =
[]
>>
在编程世界里或者数学世界里,矩阵的形状是可以改变的,简单的如行矩阵变列矩阵,矩阵形状的改变,不改变矩阵内元素,在进行一些特定需求是很有必要,如在人工智能LSTM神经网络中,就需要对输入神经网络模型的“矩阵”进行形状的改变,对它加上一个维度,使其变成2一个三维张量,这需要将pandas这dataframe格式数据先变为numpy的ndarray格式,然后对ndarray类型矩阵进行增加一个维度,这就变成了一个三维张量,然后输入LSTM神经网络,话扯得有点远了,言归正传,在matlab里也是有需要对矩阵的维度进行改变的,那么怎么对矩阵的维度进行改变呢?这就是接下来要讲的知识。
在matlab里,提供了一些事先定义好的函数,举例如下:
>> a=[1,5,9;3,5,7;2,4,8]
a =
1 5 9
3 5 7
2 4 8
>> reshape(a,1,9) %改变矩阵为1行9列
ans =
1 3 2 5 5 4 9 7 8
>> fliplr(a) %每一行元素逆序排列
ans =
9 5 1
7 5 3
8 4 2
>> rot90(a) % 生成一个由a逆时针旋转90度的矩阵
ans =
9 7 8
5 5 4
1 3 2
>> repmat(a,[2,2]) %创建和a有相同元素的一个2*2块的矩阵,由4块和a同样大小的矩阵组成
ans =
1 5 9 1 5 9
3 5 7 3 5 7
2 4 8 2 4 8
1 5 9 1 5 9
3 5 7 3 5 7
2 4 8 2 4 8
>>
矩阵索引有单下标索引和双下标索引,推荐使用双下标索引,避免歧义,
单下标索引就是按列开始从前往后,一直排序,
a =
1 5 9
3 5 7
2 4 8
>> a(:,2) %返回第2列的所有元素
ans =
5
5
4
>> a(1,:) %返回第一行的所有元素
ans =
1 5 9
>> a(:,1:2) %返回第1到2列的所有元素
ans =
1 5
3 5
2 4
>> a(1:2,:) %返回第1到2行的所有元素
ans =
1 5 9
3 5 7
>> a(1:2,2:3) %返回第1到2行,第2到3列的所有元素
ans =
5 9
5 7
>>
使用下标索引,如下:
>> a=magic(5) %构建一个5*5的矩阵,每一行元素之和相等,每一列元素之和相等
a =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
>>
>> a(2:3,4:5) %构建一个2到3行,4到5列的矩阵
ans =
14 16
20 22
>> a([2:3 4:5]) %构建一个第2,3个元素和第4,5个元素组成的矩阵
ans =
23 4 10 11
>>
在matlab中单下标索引和双下标索引可以转换,使用sub2ind()函数,
在matlab中,提供了在一个已知size矩阵中,相互转换的函数
>> sub2ind([3,3],1,3) %给定一个矩阵的size,然后输入要提取的双下标索引,返回一个按列排序的单下标索引
ans =
7
>> [a b]=ind2sub([3,3],7) %给定一个矩阵的size,然后输入要提取的按列排序的单下标索引,返回对应双下标索引,需要给两个变量在矩阵中[]去接受这两个索引值
a =
1
b =
3
>>
矩阵属性包括:矩阵结构,矩阵大小,矩阵维度,矩阵数据类型,
举例如下:
>> a=magic(3) %构造一个3*3矩阵
a =
8 1 6
3 5 7
4 9 2
>> isempty(a) %判断矩阵是否为空矩阵
ans =
0
>> isscalar(a) %判断矩阵是否是单元素的标量矩阵
ans =
0
>> isvector(a) %判断矩阵是否是一维向量
ans =
0
>> issparse(a) %判断矩阵是否是稀疏矩阵
ans =
0
>>
矩阵的大小信息包括个信息,矩阵维度ndims,矩阵行数列数size,矩阵元素个数numel
实例如下:
>> a=[magic(3) [1,2,3]'] %生成一个3行4列矩阵,在第4列加上1列[1,2,3]'
a =
8 1 6 1
3 5 7 2
4 9 2 3
>> ndims(a) %矩阵维度
ans =
2
>> [row,column]=size(a) %矩阵的行数和列数
row =
3
column =
4
>> l=length(a) %矩阵的最长维度长度
l =
4
>> n=numel(a) %矩阵元素个数
n =
12
>>
在matlab中,空矩阵[],标量矩阵[1],一维矩阵[1,2,3],二维矩阵[1,2;3,4]都作为普通二维矩阵,并由ndims()函数计算维度信息。
实例如下:
>> a=[];b=5;c=1:3;d=ones(2);e(:,:,2)=[1 2;3 4]; %a是空矩阵,b是标量矩阵,c是一维矩阵,d是二维矩阵
>> nds=[ndims(a),ndims(b),ndims(c),ndims(d),ndims(e)] %查看每个矩阵的维度信息
nds =
2 2 2 2 3
>> whos
Name Size Bytes Class Attributes
a 0x0 0 double
b 1x1 8 double
c 1x3 24 double
d 2x2 32 double
e 2x2x2 64 double
nds 1x5 40 double
>>
matlab中可以由特定函数判断矩阵数据类型,
如下:
d =
1 1
1 1
>> isnumeric(d) %是否是数值型
ans =
1
>> isreal(d) %是否是实数
ans =
1
>> isfloat(d) %是否是浮点型
ans =
1
>> isinteger(d) %是否是整数
ans =
0
>> islogical(d) %是否是逻辑型
ans =
0
>> ischar(d) %是否是字符
ans =
0
>> isstruct(d) %是否是结构体
ans =
0
>> iscell(d) %是否是单元数组
ans =
0
>> iscellstr(d) %是否是结构体单元数组
ans =
0
>>
本章是matlab的基础知识章,讲解了matlab章的基础知识,有数据类型,运算符,字符串处理,矩阵基础等知识。通过这些知识的讲解建立起对matlab的基础认识,希望以上代码全部在matlab上敲一遍,在后续章节里,将通过这些基础知识深入讲解matlab。