查看: 61590|回复: 172|关注: 0

[技术文章] MATLAB最基础教程

  [复制链接]

论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
发表于 2018-4-22 20:29:43 | 显示全部楼层 |阅读模式
MATLAB最基础教程(零):基本数学概念


    前言:matlab只是个软件,用来完成机械的计算,而如何安排这些计算,需要用户掌握最基本的数学概念。这篇将介绍工程数学中常用的数学概念,与matlab似乎并不相关,但实则是matlab的基础。

1.数值与符号
    如果给工程数学问题分类,最大的两类肯定是数值问题和符号问题,对应matlab的数值运算和符号运算。简而言之,数值运算就是所有的变量的值已知,求解的也是一些具体的值;符号运算则刚好相反,不要求所有的变量都已知,求解的结果也不是变量具体的值,而是变量之间的关系。一个简单的例子是
①数值问题:求解一元二次方程,ax2+bx+c=0,其中a=b=c=1,所求得的结果一定是x=几点几+几点几i,是个复数,是个具体的数值。
②符号问题:求解一元二次方程,ax2+bx+c=0,所求的的结果一定是x=求根公式,是abc的函数,是个关系
    可见,一个问题是数值问题还是符号问题,很大程度上决定于结果需要求解的是数值还是关系。当然两个问题也可以相互转化,比如数值问题的一元二次方程,我们一般会先转化成符号问题,把abc代入求根公式,求出来变量x的具体数值。但实际中,一般我们并不推荐这样做,原因是matlab的数值和符号是完全不同的两套系统,相互转化不仅需要多余的数值符号转换语言,更可能带来查错的不便。
2.典型数值问题
    以下是常见的数值问题,文中提到的解法均可在数值计算、科学计算、数值算法这类书中找到。
2.1代数方程
    代数方程又分为线性方程和非线性方程,线性方程一般可以转化为矩阵形式AX=b,对A求逆即可。求逆的数值解法一般有高斯赛德尔迭代,超松弛迭代等。非线性方程一般转化为f(x)=zeros其中x是个向量,右侧的zeros表示f是个多输出函数,数值解法一般是迭代,常见的有牛顿迭代,最速梯度,点斜式等。
2.2常微分方程
    常微分方程一般转化为Dy=f(y,t),且y(0)=y0是初始条件,其中y和Dy都是向量,f也是个多输出函数,数值解法有欧拉法,龙格库塔法。
2.3偏微分方程
    偏微分方程比较复杂,matlab处理偏微分方程也不专业,我也几乎不用matlab处理这类问题。但工程数学上,偏微分方程的解法有两类,差分法和有限元法。差分法需要采用中心差分,迎风差分等。有限元需要计算刚度矩阵等。
2.4插值和拟合
    插值和拟合是完全不同的两个数学概念,虽然很多时候很多人都混淆了。两者的描述都可以归结为:已知函数上的点(x1,y1),(x2,y2)...(xn,yn),求一个已知的x,对应的y的数值。插值常用的多项式插值,三次样条插值。拟合的本质是一个最优化问题,其中最常用的一种拟合是线性拟合,求解方法是最小二乘法。
2.5离散周期傅里叶变换
    严格说来,这并不能算一个数学问题,只是一种运算方式,就好像加减乘除一样。特殊性在于这种变换是对于一个向量进行,且运算后的结果依然是个向量。这里提出来是为了强调这种傅里叶变换的限定,要求是离散周期,这也是数值方法能处理的唯一一种傅里叶变换。
2.6最优化问题
    最优化问题比较宽泛,一般可以归结为求目标函数f(x)的最大或者最小值,其中f是一个单输出的函数,x是一个向量。其中x需要满足线性约束条件、非线性约束条件、上下界。具体的解法有最速梯度,遗传,蚁群,退火等算法。
2.7数值积分
    已知函数上的点(x1,y1),(x2,y2),...(xn,yn),求函数在x1到xn的定积分。常见算法有矩形公式,梯形公式,辛普森公式。类似的问题还有数值求导。
3.典型符号问题
    以下是常见的符号问题,需要特别指出的是,无解问题。数值问题中也有一部分无解问题,但大多数工程中是碰不到的。而符号问题恰好相反,绝大部分我们遇到的符号问题都是没有解的,或者准确的说,没有解析解。比如求一元五次方程,我们知道x和这些系数存在关系,但无法写出显式的表达式,也就是说没有解析解。
3.1递推转通项
    这个问题可以归结为:已知xn+1=f(xn),求xn,常见于数列的推导。
3.2代数方程
    区别于数值问题中的代数方程, 这里的代数方程问题可以描述为:f(x,c)=0,求x=x(c),这里需要求解的其实是x和c的关系。
3.3常微分方程
    区别于数值问题中的常微分数方程, 这里的代数方程问题可以描述为:Dy=f(y,t,c),求y=x(t,c),一般无需初值条件。
3.4符号积分
    区别于数值问题中的数值积分,这里的符号积分可以描述为:已知函数关系y=f(x),求y的不定积分。同样的问题还有符号求导。


论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
 楼主| 发表于 2018-4-22 20:38:24 | 显示全部楼层
本帖最后由 halleyhit 于 2018-4-22 21:04 编辑

matlab最基础教程(一):软件基本概念

前言:①如果你是第一次使用matlab,建议阅读本教程。②以2017a版本为基础,适用于2014a及之后的版本,之前的版本未测试。③结合这两个月在坛子里回答的问题,整理成教程,水平有限,欢迎指正。

1.matlab的界面
界面.jpg
    左上角,home标签下,找到layout进行设置/复位,可以设置各板块的显示与隐藏。其中有几个部分,请务必要显示
①Current Folder:中文一般翻译成工作路径,一般设置成一个自己建立的、有读写权限的文件夹,例如我的文档下建立一个matlab文件夹
②Command Window:字面意思是命令窗口,用来运行代码,所有的代码都是在这里输入
③Workspace:字面意思是工作空间,其实就是暂存所有运行结果的地方,“暂”的具体含义是:关闭matlab后丢失
2.软件中的基本概念
2.1 函数
    matlab之所以强大,就是因为提供大量的函数,你也可以建立自定义函数,方法是:Home->New->function。自定义函数一般保存在工作路径下。函数文件的特征是:扩展名m,内容的第一行以function开头,后续内容是“输出变量=函数名(输入变量)”。且函数名和文件名相同。
    每个函数在Command Window中运行,用来完成特定的计算任务,运行方式是输入“输出变量=函数名(输入变量)”,然后按回车。例如有个系统自带的函数是用来求绝对值的,函数名abs,所以在Command Window里输入“a=abs(-1)”,就会显示运算结果为“a=1”。且运算结果会在Workspace里出现一个变量a,双击后可看到a的值是1。
2.2 脚本
    可以理解为特殊的函数,这种函数内容的开头没有function那行,因此没有输入、输出变量,也没有函数名。文件扩展名和函数一样是m,也需要在Command Window里运行。脚本都是用户建立的,方法是:Home->New Script。一般保存在工作路径下。脚本的功能就是完成用户需要的、复杂的计算任务,通常脚本里会调用很多函数。
2.3 GUI
    一般翻译为界面,就是人机交互界面的意思。写脚本处理问题的方法有点麻烦,让人看起来更像是码农,所以现在很多问题可以通过界面点点鼠标解决。这时候就需要打开界面,打开方法是:在APPS标签里可以找到所有已安装的GUI工具,单击即可。注意右边有个小三角可以点开。和函数一样,用户也可以自己建立自定义GUI,这部分较为复杂,对新手而言有点遥远。
2.4 toolbox
    一般翻译成工具箱,matlab将功能相近或者应用上自成体系的一组函数和GUI打包成一个toolbox。正版的matlab在购买时,几乎每一个toolbox都是要单独收费的,所以toolbox也可以理解为matlab产品的模块,一个工具箱就是一个产品/商品。
2.5 simulink
    一般用matlab解决问题的过程是:用户自定义脚本,在Command Window里运行脚本。而脚本的运行逻辑是顺序执行,和一般的编程一样。simulink则提供另一种思路,图形化编程,有点像labview,这种方法很适合于物理模型的仿真,因此有时用“matlab编程”和“simulink仿真”强调。使用方法是在home标签下点击simulink。
3.获得帮助
    常用的获得帮助有四种方法
①home标签里,有个Help标志,点开后可以获得各工具箱/产品的完整帮助文档。新版本中默认使用在线,改用本地帮助的办法是在home标签里,Preferences下的matlab/Help里选择installed locally
②cn.mathworks.com官网上找到支持,然后可以获得教程。这种方法获得的帮助文档和第一种方法一样。
③在Command Window里输入 doc+函数名 来获得帮助。比如输入"doc fft"可以获得离散傅里叶变换函数fft的帮助和范例。这种方法获得的文档是前两种方法文档中的部分。当然,前提是你要知道函数名,才能找到帮助。这种方法适合于获得系统自带函数的使用说明。
④使用GUI时,通常界面的角落里有Help,点开可以获得帮助。这种方法获得的文档是第一和第二种方法文档中的部分。这种方法适合于获得系统自带GUI的使用说明。
    这几种方法中,最常用的是第三种,只要知道自己需要的函数名,就可以用这种方式获得说明和范例。而实际使用中,一般常用的系统自带函数,也并不是非常多,大概几十个?真正需要牢记使用方法的可能就几个,通常都是知道函数名,要用的时候doc一下。


论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
 楼主| 发表于 2018-4-22 20:38:35 | 显示全部楼层
本帖最后由 halleyhit 于 2018-4-22 21:32 编辑

matlab最基础教程(二):变量类型与赋值

前言:matlab解决问题的最基本思路是建立脚本文件,那么脚本文件的第一段就是定义一些变量,这和C语言等编程思想是一样的。matlab提供的变量类型很多,最基础的是三种:数值变量、符号变量、字符串,其他的类型还有cell、table等。这里仅说明最基础的变量类型。

1.数值变量
    matlab中所有的数值变量都是矩阵,赋值时,以方括号作为开头和结尾,以英文逗号或空格分割同行元素,以英文分号分割各列。例如在Command Window里输入
  1. a=[1 2;3 4]
复制代码
可以看到运算结果,a是一个数值变量。同时workspace里出现一个田字形的变量a,说明变量a的类型是数值型。
1.jpg
    向量和数字可以视为特殊的矩阵,例如
  1. a=[1 2]
  2. a=[1;2]
复制代码
分别是行向量和列向量,
  1. a=[1]
复制代码
可以简写为
  1. a=1
复制代码
是数字。

    数值变量的命名要求是英文字母开头,不能包含特殊符号,大小写敏感。这里推荐采用下划线来进行分割,例如value_of_A,这和其他编程语言的命名规则大体相当。
    赋值中,有时需要用到等差数列,例如定义一个向量a=[1 2 3],如果比较长,赋值很麻烦,所以matlab提供了一个简单的方法
  1. a=[1:1:3]
复制代码
这里两个冒号的意思是起始值:步长:终值。采用这种赋值方式时可以获得一个等差数列行向量,并可以省略两侧的方括号。当步长为1时,可以省略步长和一个冒号,于是可以简写为
  1. a=1:3
复制代码
    另一种灵活的赋值方法是分块矩阵,其方法是变量名后面加圆括号,圆括号中加序号。例如
  1. a=[1 2;3 4]
复制代码
定义变量a之后,
  1. b=a(1,2)
复制代码
就可以把a的第一行第二列元素赋值给b,当然也可以用
  1. a(1,2)=1
复制代码
来修改矩阵中部分元素的值。这里需要注意,序号必须是自然数,且不能是零。当矩阵中有多个元素需要赋值时,可以将序号部分改成向量,例如
  1. a([1 2],[1 2])=[1 2;3 4]
复制代码
中把行数和列数都用向量表示,就是说对矩阵a的第1和2行,第1和2列,总共4个元素赋值。更进一步,也可以有a([1 2],1)表示a的第一列,也可以写成
  1. a(1:end,1)
复制代码
这里的end表示终点,即a的行数2,也可以更进一步简写成
  1. a(:,1)
复制代码
这里的冒号表示从头至尾。这类赋值方法最为常用,但基本的语法非常简单,方括号表示矩阵开头和结尾,圆括号表示从矩阵中选取部分,把握这个原则,有利于读懂程序。
    当然分块矩阵也可以
  1. b=[a a]
复制代码
这样的赋值方法,但需要注意的是,方括号中的元素必须满足矩阵的行列数要求,例如
  1. a=[1 1]
  2. b=[1;1]
  3. c=[a b]
复制代码
就会引起错误,因为此时matlab无法确定c的行列数。
2.符号变量
    总体而言,符号变量比数值变量简单得多,因为变化非常少,常用的赋值命令是
  1. syms a b
复制代码
这里syms表示这里要定义一些符号变量,a和b是变量名,符号变量的命名规则和数值变量一样。有时候也采用
  1. syms a real
复制代码
来强调a是实数变量,具体可以doc syms来获得帮助。
    有些变量之间存在依赖关系,此时可以定义
  1. syms x y(x)
复制代码
这里声明x是一个符号变量,又声明y是一个符号变量,且y的值由x决定,这相当于数学中函数的概念。当然具体的函数关系并没有明确规定。也可以
  1. syms x y z(x,y)
复制代码
来定义符号变量z,z依赖x和y。这相当于二元函数的概念。这里的圆括号显然和数值变量中的圆括号含义完全不同,这也是学习matlab最不习惯的地方,同一个符号,由于变量类型不同会有完全不同的含义。所以在学习matlab的过程中,一定要区分数值变量和符号变量。
    上述方法定义的符号变量是一个数,或者1*1矩阵,matlab中也可以定义符号矩阵,例如
  1. syms a11 a12 a21 a22
  2. A=[a11 a12;a21 a22]
复制代码
就可以获得一个矩阵符号变量A。
    定义符号变量后,workspace中出现相应的变量名,图形不是数值变量的田字形,而是方框里有个立方体,双击后可以看到行列数。
2.jpg

3.字符串
    比数值、符号更为简单的就是字符串了,其定义方法是以单引号开头和结尾,例如
  1. a='hello world'
复制代码
就定义了一个字符串a,其值为你好世界。matlab中较为特殊的是,字符串可视为行向量,例如
  1. b='hello '
  2. c='world'
  3. a=[b c]
复制代码
也可以获得字符串a,其值为你好世界。另外,有时也可以将字符串视为矩阵,例如
  1. a=['ab';'cd']
复制代码
但这种用法很罕见,同时要求各行字符串长度一样,否则将违反矩阵行列数规定。
    当然字符串的值也可以是特殊符号,比如
  1. ','
复制代码
就定义了逗号,而最特殊的就是定义单引号,因为单引号会和字符串定义中的单引号混淆,因此matlab中用两个单引号表示一个单引号,也就是
  1. a=''''
复制代码
表示a是一个字符变量,值是一个单引号。语句中第一和第四个单引号是字符串类型的开头和结尾,中间两个单引号用来表示一个单引号。
    定义字符串变量后,workspace中出现相应的变量名,图像是方框里写了ch,双击后可以看到行列数。
3.jpg

论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
 楼主| 发表于 2018-4-22 20:38:54 | 显示全部楼层
本帖最后由 halleyhit 于 2018-4-26 14:12 编辑

matlab最基础教程(三):常用的系统自带函数,数值变量篇

前言:上一篇说了变量的类型和赋值,这里接着说这些变量的基本运算,捎带一些常用的系统自带的函数,通过这些运算和函数,已经可以完成一些简单的计算了。

1.数值变量的基本运算
    数值变量都是矩阵,矩阵之间最基本的运算有加、减、乘(方)、转置,运算符分别是+-*',与数学中的一般表示无异,但仍有一些地方需要注意,以下结合代码进行说明。
1)矩阵加减法只有维度相同的矩阵才能进行,例如
  1. a=[1 2]
  2. b=[1 3]
  3. c=[1;2]
复制代码

  1. d=a+b
  2. d=a-b
复制代码
都是可以进行的,因为a和b都是1行2列,但
  1. d=a+c
复制代码
则无法进行,因为数学上,不同维度的矩阵加减法并没有定义。
2)矩阵乘法只有第一个矩阵的列数等于第二个矩阵的行数时,才能进行,例如上段代码中的abc,则
  1. d=a*c
复制代码
是可以进行的,但
  1. d=a*b
复制代码
则不能进行,原因同样是因为这种计算在数学上没有定义。还有一种特殊的乘法,也就是乘方,例如
  1. A=[1 2;3 4]
  2. B=A*A
复制代码
这样的矩阵乘法可以写成
  1. B=A^2
复制代码
当然,数学上规定,只有方阵才能进行乘方。
3)矩阵与数乘除,由于数也可以看做1*1的矩阵,因此这是一种特殊的矩阵乘除法,和数学上定义一样,比如
  1. d=a*2
  2. d=a/2
复制代码
这些都能进行。
4)转置,任何维度的矩阵都可以进行转置,例如
  1. d=a'
复制代码
就会将a这个行向量转置,得到一个列向量d。需要注意的是,这种运算更准确的说法是共轭,对实数矩阵而言,这两种说法并没有什么区别,但对复数矩阵而言,共轭的意思,不仅是把a(i,j)和a(j,i)交换位置,更要把所有元素的虚数部分乘以-1。
2.数值变量的特殊运算
    和其他软件不同,matlab里提供了一些很有意思的运算符,有点乘.*、点除./和点方.^,这些运算符在本身的运算符前加一个点,可以实现很强大的功能,但由于和一般的运算符太像,也造成了很多人混淆。这些运算符有很多叫法,比如.*,一般称为点乘、元素乘、数乘,这些叫法都是为了让这个运算符区别于普通的乘,有时为了强调这种区别,也把通常的乘叫矩阵乘。
    简单而言,这些运算的含义是将矩阵作为一般的数来进行运算,比如
  1. [1 2 3].*[4 5 6]
  2. [1*4  2*5  3*6]
  3. [1 2 3]./[4 5 6]
  4. [1/4  2/5  3/6]
  5. [1 2 3].^3
  6. [1^3  2^3  3^3]
复制代码
所以这里点乘和点除需要注意,只有同样维度的矩阵才能进行这种特殊运算。另外点除还要注意不要除以零,虽然matlab并不会报错,但除以零在数学上没有定义,所以这种除法其实已经失去了意义。
    于是,什么时候用矩阵乘,什么时候用点乘,其实是看计算的目的,但有些时候,这两种运算符的确是等效的:
1)数字的乘除
  1. 1*1
  2. 1.*1
复制代码
当然结果相同
2)矩阵与数字的乘除
  1. 1*a
  2. 1.*a
复制代码
结果也是一样的
3.数值变量的常用函数
    这里的函数都可以通过doc+函数名查到更详细的帮助,因此仅列出典型用法。
  1. a=ones(3)
  2. a=ones(1,5)
复制代码
生成指定大小的全1矩阵
  1. a=zeros(3)
  2. a=zeros(1,5)
复制代码
生成指定大小的全0矩阵
  1. a=eye(3)
复制代码
生成指定大小的单位方阵
  1. inv([1 2;3 4])
复制代码
矩阵求逆,只能对方阵操作。matlab有左除法,通常更高效,如有需要也可尝试
  1. size([1 2;3 4])
复制代码
获得矩阵的行数和列数,也可以通过
  1. size([1 2;3 4],1)
复制代码
单独获得行数或者列数
  1. length([1 2 3])
复制代码
获得向量的长度,这个命令也可以对矩阵操作,当然一般只对向量操作
  1. max([1 2 3])
  2. min([1 2 3])
复制代码
获得向量的最大和最小值,也可以对矩阵操作
  1. sort([2 1 3])
复制代码
按大小对向量进行排序,也可以对矩阵操作
  1. sum([1 2 3])
复制代码
求和,也可以对矩阵操作
  1. cumsum([1 2 3])
复制代码
累积求和,类似求定积分,一般只对向量操作,需要注意的是,累积求和后,结果和原向量长度一样
  1. diff([1 2 5 6])
复制代码
差分运算,类似于求导,一般只对向量操作,需要注意的是,差分操作后,结果的长度比原向量少一
  1. plot([1 2.5 3],[5 6 4])
复制代码
画图,需要注意的是,两个向量的长度要相等才能画图
  1. exp([1 2])
复制代码
指数函数,类似的数学函数还有三角函数(sin,cos,tan,asin,acos,atan),对数函数(log),这些函数在对矩阵操作时,相当于对矩阵中的每个元素进行操作,类似点乘这样的运算符。


论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
 楼主| 发表于 2018-4-22 20:39:08 | 显示全部楼层
本帖最后由 halleyhit 于 2018-4-26 14:13 编辑

matlab最基础教程(四):常用的系统自带函数,符号变量与字符串篇

前言:matlab字面意思是矩阵实验室,软件重点是数值变量的运算。所以在符号变量和字符串的运算上,功能并不强大,我用的也不是很多,因此这篇的内容请多多指正。

1.符号变量的基本运算
    符号变量的基本运算与数值变量一样,加减乘之类的,比如
  1. syms x y(x)
  2. g=x*y
复制代码
并没有需要特别说明的。

2.符号变量的特殊运算
    符号变量的特殊运算也与数值变量一样,但一般而言,符号变量都是1*1矩阵,因此特殊运算与基本运算一般都是等效的。比如
  1. g=x*y
  2. g=x.*y
复制代码
的运算结果完全一样。

3.符号变量的常用函数
    数值变量的常用函数,一般都可以直接用在符号变量上,比如三角函数
  1. syms x
  2. y=sin(x)
  3. a=1
  4. b=sin(a)
复制代码
这些都是可以通用的,而且函数的含义也完全一样。
    但偏偏有些函数非常蛋疼,对符号变量与数值变量都可以进行操作,但操作的含义完全不同,比如diff,diff对于一个数值变量的运算结果是差分,而对于一个符号变量的运算结果则是求导
  1. syms x
  2. f=diff(sin(x))
  3. a=[1 2 3]
  4. b=diff(a)
复制代码
运算出来的f是sin(x)的导数,也就是cos(x),依然是个符号变量,而b运算结果则是一个差分向量。
    另外也存在很多函数只能对数值变量操作,比如离散傅里叶变换fft。还有很多函数只能对符号变量操作,比如泰勒展开taylor。因此在matlab使用中,一定要区分变量的类型,其实真的用起来也好区分,因为完成特定的计算任务,要么全部用数值,要么全部用符号,这也符合一般处理问题的原则。
    我平时做符号运算比较少,用到的函数,除了exp、sin这类数学运算外,还有:
int 求积分,符号运算特有,可以求定积分,也可以求不定积分,但一般不会写+C
diff 求导数,符号运算特有
limit 求极限,符号运算特有
ezplot 作图(新版本中,软件推荐使用fplot),类似数值变量运算时的plot

4.字符串的常用函数
    matlab中字符串的常用算符就更少了,但都非常有用,这里介绍几个:
1)num2str和str2num:可以实现数值变量和字符串变量的转换,比如
  1. a=1
  2. b=num2str(1)
复制代码
运算结果显示a是一个数值变量,b是一个字符串变量,函数名中的2就是英文中to的意思,也就是把num数值类型转化成str字符类型。str2num就是这个函数的反函数,这两个命令结合,可以实现特定的功能,比如提取一个数字的最高位:
  1. a=123456
  2. b=num2str(a)
  3. c=b(1)
  4. d=str2num(c)
复制代码
2)eval:其原理是把“字符串”变成“命令”并执行。但使用过程中需要注意的是,这个命令不可以“编译”,也就是只能在matlab内使用,无法移植到C,JAVA等其他语言平台。有需要的可以自行尝试这个命令。

论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
 楼主| 发表于 2018-4-22 20:39:23 | 显示全部楼层
本帖最后由 halleyhit 于 2018-4-23 07:12 编辑

matlab最基础教程(五):判断与流程控制

前言:判断常用于数学中的分段问题,更为复杂的问题则需要流程控制。本篇介绍matlab中的相关语法,这些语法并不难,但却很容易混淆,一方面是和其他语言,例如C语言混淆;另一方面是和matlab自身的其他语句,例如赋值混淆。


1.逻辑变量
1.1逻辑变量的赋值
    有些语言中,逻辑变量是一种专门的变量类型,其值为true或者false,matlab中也有这个类型,但其值为1或者0。赋值方式是“变量名=表达式”,变量名的命名规则与数值变量一样,表达式是一种判断,比如数值大小的判断,或者高级函数的判断。例如输入
  1. a=1>2
复制代码
就定义一个逻辑变量a,其值是0,表示false,在workspace里可以看见a的类型是logical。
1.jpg
    对初学者,可以认为数值大小的判断,是指两个1*1维的数值变量的比较。数值大小比较的方法有:>大于;<小于;>=大于等于;<=小于等于;==等于;~=不等于6种。因为数值计算有舍入误差,所以等于这个判断,有时需要用
  1. abs(x1-x2)<eps
复制代码
这样的不等式来代替,其中eps是matlab中最小的非零数值,相当于舍入误差的标准。
    高级函数的判断,是指系统自带的一些函数,例如
  1. a=isprime(x)
复制代码
用来判断x是否为质数,
  1. a=exist(x)
复制代码
用来判断是否存在变量、函数或者文件。

1.2逻辑变量的逻辑运算
逻辑变量的取值只有0或者1,他们之间可以进行逻辑运算,运算符有:&&与;||或;~非。这里需要注意:
1)~单独使用表示非运算,要区别于不等于~=的连用
2)如果是高级函数的判断配合非运算,也可以实现判断,例如
  1. a=~isprime(x)
复制代码
就相当于判断x是否为合数

1.3逻辑变量的数值运算
    matlab中逻辑变量可以参与数值运算,参与时,会被数值0和1代替。例如
  1. a=1>2
复制代码
生成一个逻辑变量a,则
  1. b=a+1
复制代码
时,matlab会判断正在进行数值运算,然后将逻辑变量a转化成数值变量,由于a在逻辑变量时表示false,所以转化时,a相当于数值变量0,因此会得到数值变量b=0+1=1。

2.流程控制
    matlab的流程控制和C语言类似,if和switch作为判断依据,相当于流程图的菱形框,for和while作为循环,相当于流程图的反向箭头。
2.1if判断
    语法是:
  1. if 逻辑变量1
  2.     执行语句1
  3. elseif 逻辑变量2
  4.     执行语句2
  5. else
  6.     执行语句3
  7. end
复制代码
其含义与C语言中一致,是顺序判断,即逐个if或者elseif进行判断,若逻辑变量为1,则执行语句,若为0则进行下一个判断。其中逻辑变量经常用多个逻辑变量的逻辑运算结果来代替,例如我们经常看到的是
  1. if x>1 && y>1
复制代码
而不是先赋值再判断的
  1. a=(x>1) && (y>1)
  2. if a
复制代码
其实这两种方法是等效的。有时候为了书写和注释,也会先定义一个逻辑变量flag,然后再if flag。

2.2switch判断
    switch的语法是:
  1. switch 数值变量1
  2. case 数值1
  3.     执行语句1
  4. case 数值2
  5.     执行语句2
  6. otherwise
  7.     执行语句3
  8. end
复制代码
switch与if最大的不同是,switch只进行一次判断,即根据数值变量1的值来决定执行哪一个case,而不像if会判断多个elseif。需要强调的是,只有当数值变量1==数值1时,才会执行语句1,而之前说过,==这个判断是有舍入误差的,因此switch一般用于数值变量1只取整数时,比如sfun的判断。对初学者而言,也可以先无视switch。

2.3for循环
    for循环的语法是:
  1. for 数值变量=向量
  2.     执行语句
  3. end
复制代码
其含义是,数值变量会取向量中的每一个值,然后执行语句,在执行语句中,数值变量是一个1*1的矩阵。比如
  1. for a=[0 1 3]
复制代码
则会让a=0,执行语句,然后a=1,执行语句,最后a=3,执行语句。这里容易和赋值语句混淆,因为a=[0 1 3]是一个数值变量赋值,赋值后a是个向量,但加上了for后,a是1*1矩阵。另外,在数值变量赋值那段,我们说过有一种常用的赋值方法是"a=初始值:步长:终值",其结果是把a赋值成一个向量,因此这也广泛用于for语句中
  1. for a=初始值:步长:终值
复制代码
则在执行语句中,a是一个遍历初值到终值的1*1矩阵。

2.4while循环
    while语句的语法是:
  1. while 逻辑变量
  2.     执行语句
  3. end
复制代码
其含义是,当逻辑变量为1时,执行语句,直到逻辑变量为0,因此while的执行语句中,一定有改变逻辑变量的部分,否则就是死循环。比如写了while a<10,就一定会在执行语句中有类似a=a+1这样的赋值语句,使得若干次循环后,逻辑变量为0。总体而言,while并不如for稳定,所以初学者也可以无视while。

论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
 楼主| 发表于 2018-4-22 20:39:35 | 显示全部楼层
本帖最后由 halleyhit 于 2018-4-23 07:17 编辑

matlab最基础教程(六):编程习惯

前言:matlab的基本使用方法差不多介绍完了,确定问题类型(数值/符号),编程(函数/脚本)并运行即可。但具体编程过程中,良好的习惯非常重要,一方面便于调试,另一方面便于代码维护和升级。


1.注释
    matlab提供两种注释,分别是%%和%。%%一般独占一行,用来分段,两个%%之间的内容称为一段,在程序调试时,可以设置为运行一段代码后暂停,以便查看一段代码的运行结果。使用范例如下:
  1. %%赋值
  2. 赋值代码
  3. %%第一阶段计算
  4. 第一阶段代码
  5. %%第二阶段计算
  6. 第二阶段代码
  7. %%输出
  8. 输出阶段代码
复制代码
这样在调试时,若设置分段运行,则运行完赋值代码后,程序自动进入调试模式,此时可以在workspace里看到赋值段的运行结果,以便确认这段代码是否正确。
    %常用于一般代码的末尾,用来说明这一行代码的含义,例如
  1. g=9.8%重力加速度赋值
复制代码
这样之后调试时,可以快速找到这一行,并修改相应代码。需要注意的是,%仅在行内,对其后的内容有效,遇到回车换行后失效。此外,无论是%%还是%,注释内容会显示为绿色。

2.分行
    无论matlab还是其他程序语言,也无论函数还是脚本,依次逐行运行是基本特征,因此我们一般不希望一行的内容太多,因为这样不方便差错。但如果一定要使用这样一行很长的代码,matlab提供了一种分行的方式。使用方法是在代码中输入三个.,然后回车。这样产生的代码比如:
  1. a=...
  2. 1
复制代码
这行代码和a=1完全一样。需要指出的是,这种分行方式仅在输入时有效,在实际运行中,matlab仍然认为这是一行代码。这种分行的另一种用法是用在矩阵赋值中,比如
  1. a=[1 2;...
  2.    3 4]
复制代码
这样可以很明显看出a是2*2矩阵。

3.分号
    matlab的每一行代码,一般都会在command window里显示运行结果,如果不想显示,可以在代码后面写一个分号;,这样就可以不显示该行的运行结果。需要注意的是:其一,写不写分号不影响程序的运行和结果;其二,显示运行结果是需要占用计算时间的,因此一般的语句都会写上分号;其三,if、for等流程控制语句,这一行不加分号。

4.先定义再使用
    虽然matlab中可以直接使用a(2,2)=1这样的语句,而无需先定义a是多大维度的矩阵,但这样可能造成运行变慢。先定义再使用依然是个好习惯,尤其是赋值语句中有讲过zeros和ones这样的语句,先把矩阵的维度定义好,再逐个元素赋值或者局部赋值,有助提高运行效率。

5.特殊运算代替循环
    matlab相较于C等语言的强大之处在于用特殊运算代替循环,比如a和b是同纬度矩阵,要将他们对应的元素相乘。在常用运算中,我们讲过,在matlab中可以用点乘.*。在C语言中则需要一个for循环,遍历a和b的每个元素,相乘后赋值给结果矩阵。当然,matlab中也可以用for循环来实现这个操作,但相比特殊运算,for循环的效率实在是差太多。特殊运算代替循环也成为了提高运行效率的主要方法,当然,如果是习惯于C语言的初学者也可以无视这一节。

论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
 楼主| 发表于 2018-4-22 20:39:47 | 显示全部楼层
本帖最后由 halleyhit 于 2018-4-23 07:22 编辑

matlab最基础教程(七):编程调试与常见报错

前言:刚写完的脚本,运行时难免出错,此时需要关注报错信息与提示,进行调试。同时,这也是本教程最后一篇。

1.打断点和分段
   写完脚本并保存后,在每一行可执行代码前,有一个行号,和一个小横线。报错信息中会有类似“Error in 文件名 (line 行号)”这样的提示,其中的行号就是代码前的这个行号。小横线说明这一行是可执行代码,而不是注释。鼠标左键小横线,此时横线变为红点,说明在这个位置设置了一个断点。脚本运行时,遇到断点会自动暂停,并进入调试模式。此时可以用continue继续执行,也可以step逐行执行,也可以step in进入调用的子函数执行。初学者一般熟悉step即可。
1.jpg
    进入调试模式时,可以观察workspace里的变量,看是否和预想一样,也可以在command window里输入其他代码或运行其他脚本/函数。在调试模式中,可以通过左键断点(红点)和小横线来设置新的断点和取消旧的断点。也可以按quit debugging退出调试模式。
    分段是类似断点的一种运行方式,参考上一篇中%%注释的说明。当脚本中有多个%%时,%%相当于分段符号,左键run and advance可以实现逐段运行,运行完一段后,相当于进入调试模式,可以在workspace里查看运行结果,但其他的操作一般不建议进行。分段运行的另一种用法,是需要输出多个图像的时候,可以运行一段,截图,再运行一段,再截图。

2.常见报错
    运行脚本后,会在command window里出现红色或者黄色的字,就是报错信息与提示。首先,报错信息会给出定位,哪个文件,第几行。有时会在多个位置给出报错,这说明报错那行的调用关系,例如自定义脚本A中n行调用了自定义函数B,而自定义函数B的m行出错了,则报错信息会定位到A的n和B的m,看起来好像是两个地方出错,其实是B的m错了,但实际中也可能是调用B的方式不对。这种情况尤其会出现在调用系统自带函数时,此时一般是调用方式不对,所以要关注A的n。
    给出报错定位后,就是看具体的报错信息了,matlab中常见的一些报错信息有:

Undefined function or variable '函数/变量名'.
说明使用变量前没有遵循先定义再使用的原则

Inner matrix dimensions must agree.
数值运算中常见错误,参考数值基本运算那篇的矩阵运算部分

Index exceeds matrix dimensions.
超出索引,例如a=[1 2 3],此时当用到a(4)时
虽然定义了a1~3,但没有定义a4,此时却用到了a4,因此报错
本质上,这也是一种未定义先使用的错误

Subscript indices must either be real positive integers or logicals.
参考矩阵赋值中所说的分块赋值,圆括号中表示位置或者序号,当圆括号中出现非自然数时报错

Expression or statement is incorrect--possibly unbalanced (, {, or [.
有开括号而没有关括号,或者有关括号而没有开括号,一般是计算式太长而打错了

Invalid data type. 或者Data must be numeric.
或者Undefined function '函数名' for input arguments of type 'double'.
参考前述的数值运算与符号运算的说明,有些函数只用于数值,有些只用于符号,混用时报错。

3.最后总结
1)doc+函数名,多看帮助多看范例。看到范例,逐行运行看结果
2)分清数值和符号,两种运算两套系统
3)学好数学再学软件(其实基本的数学知识在帮助文档里也有)

论坛优秀回答者

专家

2689 麦片

财富积分


20003000


4

主题

5060

帖子

598

最佳答案
  • 关注者: 656
 楼主| 发表于 2018-4-22 20:40:39 | 显示全部楼层
完结,水平有限,欢迎指正

新手

16 麦片

财富积分


050


0

主题

25

帖子

0

最佳答案
发表于 2018-4-23 10:17:38 | 显示全部楼层
非常好啊,基础
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐上一条 /3 下一条

快速回复 返回顶部 返回列表