1.1 MATLAB 的发展历程和影响 - pudn.comread.pudn.com/downloads151/ebook/656278/ch05.pdf ·...

105
1 1. 1.1 MATLAB 的发展历程和影响 MATLAB 名字由 MATrix LABoratory 两词的前三个字母组合而成。那是 20 世纪七 十年代后期的事:时任美国新墨西哥大学计算机科学系主任的 Cleve Moler 教授出于减轻学 生编程负担的动机,为学生设计了一组调用 LINPACK EISPACK 库程序的“通俗易用” 的接口,此即用 FORTRAN 编写的萌芽状态的 MATLAB经几年的校际流传,在 Little 的推动下,由 LittleMolerSteve Bangert 合作,于 1984 年成立了 MathWorks 公司,并把 MATLAB 向市场从这MATLAB 内核采 C 语言编写,而且除原有数值计算能力外数据图视功能MATLAB 以商品形式后,仅短短几年,就以其良好开放性运行可靠性使 原先控制领域里封闭式软件包(如英国的 UMIST瑞典LUND SIMNON国的 KEDDC)纷纷淘汰,而改以 MATLAB 平台加以重建。在时间进入 20 世纪十年代的时 MATLAB 经成为国际控制界标准计算软件到九十年代期,在国际30 几个技应软件中MATLAB 数值计算方面 独占鳌头,而 Mathematica Maple 则分居符号计算软件的前两名。 Mathcad 提供计算、 图形处理环境深受学生欢迎MathWorks 公司于 1993 年推出 MATLAB4.0 版本告别 DOS 4.x 继承发展其原有数值计算和图形可视能力时,出下几个要变化1推出了 SIMULINK是一个交互作的动态系仿真分析集环境的出现使人们 有可能考虑许多不得不做简化假设的非线因素因素而大大提高人们对 非线机动态系能力2)开进行数据交换的组通了 MATLAB 进行数据分析处理件开道路3推出了符号计算工具1993 MathWorks 公司从加滑铁卢大学购得 Maple 使Maple 为“引擎Symbolic Math Toolbox 1.0MathWorks 公司此快结束了国际上数值计算、符号计算优孰劣争论成了两计算的互补发展新时代。 4作了 Notebook MathWorks 公司准应范围最广Word DDE OLEMATLAB Word 缝连接, 而为专业者创造科学计算、图形可视处理于一环境1997 仲春MATLAB5.0 世,5.15.21999 5.3 4.x 相比MATLAB 更丰富数据类结构更友善面向图形可视广学和数据分析资源发工具MATLAB5.x 特点节将更详细介绍诚然1999 Mathematica 4.0 欠缺的大数据处理能力Mathcad 也赶2000 来之前推出了 Mathcad 2000 它购Maple 和库的部分使通了MATLAB 的接口, 而把其数学计算能力提高专业层次是,影响至今仍然没一个的计算软件可MATLAB 匹敌美大学如应用代理统计、控制号处理字通 、时分析、动态系统仿真等课程的教科书都MATLAB 作为成了十年代教科书籍性标。在那MATLAB 攻读的大学生、 硕士生、 博士必须掌握本工具在国际学MATLAB 被确可靠的科学计算标准软件。在许多国际 一流学术刊物科学刊物可以MATLAB 用。 PDF 件使"pdfFactory Pro" 版本www.fineprint.cn

Transcript of 1.1 MATLAB 的发展历程和影响 - pudn.comread.pudn.com/downloads151/ebook/656278/ch05.pdf ·...

1

1. 概 论

1.1 MATLAB的发展历程和影响

MATLAB名字由 MATrix和 LABoratory 两词的前三个字母组合而成。那是 20世纪七十年代后期的事:时任美国新墨西哥大学计算机科学系主任的 Cleve Moler教授出于减轻学生编程负担的动机,为学生设计了一组调用 LINPACK和 EISPACK库程序的“通俗易用”的接口,此即用 FORTRAN编写的萌芽状态的MATLAB。 经几年的校际流传,在 Little的推动下,由 Little、Moler、Steve Bangert合作,于 1984年成立了 MathWorks公司,并把 MATLAB正式推向市场。从这时起,MATLAB的内核采用 C语言编写,而且除原有的数值计算能力外,还新增了数据图视功能。 MATLAB以商品形式出现后,仅短短几年,就以其良好的开放性和运行的可靠性,使原先控制领域里的封闭式软件包(如英国的 UMIST,瑞典的 LUND 和 SIMNON,德国的KEDDC)纷纷淘汰,而改以 MATLAB为平台加以重建。在时间进入 20世纪九十年代的时候,MATLAB已经成为国际控制界公认的标准计算软件。 到九十年代初期,在国际上 30几个数学类科技应用软件中,MATLAB在数值计算方面独占鳌头,而 Mathematica和 Maple则分居符号计算软件的前两名。Mathcad因其提供计算、图形、文字处理的统一环境而深受中学生欢迎。 MathWorks公司于 1993年推出 MATLAB4.0版本,从此告别 DOS版。4.x版在继承和发展其原有的数值计算和图形可视能力的同时,出现了以下几个重要变化:(1)推出了SIMULINK。这是一个交互式操作的动态系统建模、仿真、分析集成环境。它的出现使人们有可能考虑许多以前不得不做简化假设的非线性因素、随机因素,从而大大提高了人们对

非线性、随机动态系统的认知能力。(2)开发了与外部进行直接数据交换的组件,打通了MATLAB进行实时数据分析、处理和硬件开发的道路。(3)推出了符号计算工具包。1993年 MathWorks公司从加拿大滑铁卢大学购得 Maple的使用权,以 Maple为“引擎”开发了Symbolic Math Toolbox 1.0。MathWorks公司此举加快结束了国际上数值计算、符号计算孰优孰劣的长期争论,促成了两种计算的互补发展新时代。(4)构作了 Notebook 。MathWorks公司瞄准应用范围最广的Word ,运用 DDE和 OLE,实现了 MATLAB与Word的无缝连接,从而为专业科技工作者创造了融科学计算、图形可视、文字处理于一体的高水准环境。 1997年仲春,MATLAB5.0版问世,紧接着是 5.1、5.2,以及和 1999年春的 5.3版。与 4.x相比,现今的 MATLAB 拥有更丰富的数据类型和结构、更友善的面向对象、更加快速精良的图形可视、更广博的数学和数据分析资源、更多的应用开发工具。(关于 MATLAB5.x的特点下节将作更详细的介绍。) 诚然,到 1999年底,Mathematica也已经升到 4.0版,它特别加强了以前欠缺的大规模数据处理能力。Mathcad 也赶在 2000年到来之前推出了 Mathcad 2000 ,它购买了 Maple内核和库的部分使用权,打通了与 MATLAB的接口,从而把其数学计算能力提高到专业层次。但是,就影响而言,至今仍然没有一个别的计算软件可与MATLAB匹敌。 在欧美大学里,诸如应用代数、数理统计、自动控制、数字信号处理、模拟与数字通

信、时间序列分析、动态系统仿真等课程的教科书都把MATLAB作为内容。这几乎成了九十年代教科书与旧版书籍的区别性标志。在那里,MATLAB是攻读学位的大学生、硕士生、博士生必须掌握的基本工具。 在国际学术界,MATLAB已经被确认为准确、可靠的科学计算标准软件。在许多国际一流学术刊物上,(尤其是信息科学刊物),都可以看到MATLAB的应用。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

2

在设计研究单位和工业部门,MATLAB被认作进行高效研究、开发的首选软件工具。如美国 National Instruments公司信号测量、分析软件 LabVIEW,Cadence公司信号和通信分析设计软件 SPW等,或者直接建筑在 MATLAB之上,或者以 MATLAB为主要支撑。又如HP公司的 VXI硬件,TM公司的 DSP,Gage公司的各种硬卡、仪器等都接受 MATLAB的支持。

1.2 MATLAB 5.3的基本组成和特点

经过近 20年实践,人们已经意识到:MATLAB作为计算工具和科技资源,可以扩大科学研究的范围、提高工程生产的效率、缩短开发周期、加快探索步伐、激发创造活力。那

末,作为当前最新版本的MATLAB 5.3究竟包括哪些内容?有哪些特点呢?

1.2.1 MATLAB的语言部分

5.0以前版本的 MATLAB语言比较简单。它只有双精度数值和简单字符串两种数据类型,只能处理 1维、2维数组。它的控制流和函数形式也都比较简单。这一方面与当时软件的整体水平有关,另方面与 MATLAB仅限于数值计算和图形可视应用的设计目标有关。 从 5.0版起,MATLAB对其语言进行了根本性的变革,使之成为一种高级的“阵列”式语言。

1.2.1.1 MATLAB语言的传统优点 MATLAB自问世起,就以数值计算称雄。MATLAB进行数值计算的基本处理单位是复数数组(或称阵列),并且数组维数是自动按照规则确定的。这一方面使 MATLAB程序可以被高度“向量化”,另方面使用户易写易读。 比如已知 t的采样数据是 )( mn × 维数组,要计算 )5sin(2 tey t−= 。对一般的计算语言

来说,必须采用两层循环才能得到结果。这不但程序复杂,而且那讨厌的循环十分费时。

MATLAB 处理这类问题则简洁快捷得多,它只需直截了当的一条指令 y = exp(-2*t).*sin(5*t) ,就可获得同样是 )( mn × 维的 y数组。这就是所谓的“数组运算”。这种运算在信号处理和图形可视中,将被频繁使用。

又如对于求解 bAx = 代数方程问题。教科书的基本叙述:当 A是标量时,Abx = ;当

A是非奇异矩阵时, bAx 1−= ;当 A是行数大于列数的满秩阵时, bAAAx TT 1)( −= ;当

A的列数大于行数时, x有无数解。一般程序就必须按以上不同情况进行编程。然而对MATLAB来说,那只需一条指令:x=A\b 。指令是简单的,但其内涵却远远超出了普通教科书的范围,其计算的快速性、准确性和稳定性都是普通程序所远不及的。

1.2.1.2 5.3 的语言新特点 (1)数据类型和面向对象编程技术 MATLAB5.x 版与旧版最显著的不同在于数据类型的变化。5.x 版现有六种基本数据类型:双精度数组、字符串数组、元胞数组、构架数组、稀疏矩阵和 unit8数据。 数据类型的变革,面向对象编程技术的采用,所产生的影响是广泛而深层的。这种影

响首先表现在 MATLAB的自身。从 5.0版起,MATLAB就用新数据类型逐步地对其自身的函数指令加以改造。这个过程一直延续到 5.3版才基本完成。比如 5.3版就推出了一组名称全新(求取极小值等)的泛函指令,它们优化参数的设置是采用构架数组进行的。再如 5.x版提供的常微分方程解算指令 ODE Solver的参数设置也全是靠新数据类型进行的。 新数据类型和面向对象技术的影响之二:若干通用工具包的相应升级。以符号计算为

例,在 MATLAB 4.2c中, Symbolic Math Toolbox 1.0版处理符号计算的指令形式与数值计

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

3

算指令形式很不协调,显得十分生硬。比如,符号矩阵的“四则”运算的旧版指令分别是

symadd , symsub , symmul 和 inverse 。但在 5.x版中,符号工具包已升级为 2.0版,新的“四则”符号运算指令形式上与数值计算完全相同,它们分别是 + , - , * , / 。新的符号计算形式已被改造得与“MATLAB风格数值计算形式”浑然统一。 新数据类型和面向对象技术影响之三:一系列的应用工具包相继升级。这不仅使应用

工具包表现更为友善,而且功能大大加强。以控制工具包为例,新版利用构架数组和重载

技术,把线性时不变系统(Linear Time-Invariant system)设计为“LTI对象”。这样处理后,不管 LTI 是由传递函数产生、由零极点增益方式产生,还是由状态方程形式创建,只要是LTI对象,它们之间就可方便地进行各种数学运算。比如在控制教科书上,由前向控制环节

1G 、对象 0G 、反馈环节 2G 组成的负反馈闭环系统传递函数210

10

1 GGGGGG

+= 。假如 0G 、

1G 、 2G 都是用传递函数,那末读者“手算”时,必须进行多项式展开、乘法 、合并、简化等运算。如果利用“旧版 MATLAB”求G,那末必须先使用 series指令把 0G 、 1G 串接成“中间”函数 01G ,然后再用 feedback指令由 01G 、 2G 算得G。然而“新版 MATLAB”只需直截了当的一条指令 G=G0*G1/(1+G0*G1*G2) ,并且式中的 G0 , G1 , G2的表达形式可以各不相同,任取传递函数、零极点增益、状态方程等形式。当然 LTI的优点远不至此,比如它还可直接对多输入多输出系统进行统一运算,而无须分解成若干个子系统进行。 (2)控制流和函数类型 新版 MATLAB的控制流新增了多分支结构 switch-case、try-catch结构和警告提示指令error、warning 。这进一步提高了程序的可读性和运行可靠性。 新版的函数类型大大丰富,适应编制和管理复杂程度不同的程序。例如内联函数比较

简练,适用于各类比较简单数学模型。而子函数、私用函数的增添,使得复杂函数比较容

易组织,既提高了软件的“重用度”,又避免了众多内存变量名的冲突、庞大工具库的函

数名冲突。 为函数设计了新的变长度输入输出宗量 varagin、varagout。采用了这种变长度宗量,MATLAB自身的新版指令被进一步“柔性化”。一个指令可以接受任意多个输入宗量,可以产生任意多个输出宗量,以适应不同场合的需要。可使得所有这些措施使得MATLAB能更加便捷地编制复杂的大型程序。当然,用户也可以借助这种变长度宗量来编制灵活多变

的应用程序。

1.2.2 MATLAB的工作环境

所谓工作环境是指:帮助系统、工作内存管理、指令和函数管理、搜索路径管理、操

作系统、程序调试和性能剖析工具等。

1.2.2.1 传统工作环境 与同时期其他数学类软件相比,旧版 MATLAB的工作环境虽属比较友善之列,但其工作环境确实比较“单调”。它的帮助系统是“纯文本”形式的;内存管理、路径管理、调

试工具是单纯指令操纵形式的;文件类型也形式单一,仅有 M文件和 MAT文件。4.2c版情况开始变化,但那只是过渡形式。

1.2.2.2 5.3工作环境新特点 (1)大量引入图形用户界面 5.x版改变了过去单调依靠“在指令窗通过纯文本形指令进行各种操作”面貌,引入了许多让使用者一目了然的图形界面,如在线帮助的交互型界面 helpwin ,管理工作内存的workspace ,交互式的路径管理界面 pathtool ,指令窗显示风格设置界面等。它们的开启方式有:工具条图标开启、选择菜单项开启,直接“文本式”指令开启。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

4

5.3版更进一步把图形显示窗改造成了交互操作的可编辑图形界面。 (2)引入了全方位帮助系统 “临场”在线帮助:这些帮助内容,大多嵌附在 M文件中,即时性强,反应速度快。它对求助内容的回答最及时准确。MATLAB旧版就一直采用这种帮助系统,并深受用户欢迎。新版保留原功能的同时,还新增一个内容与之完全对应的图形界面 helpwin ,加强了对用户的向导。 综合型在线帮助文库 helpdesk :该文库以 HTML 超文本形式独立存在。整个文库按MATLAB的功能和核心内容编排,系统性强,且可以借助“超链接”方便地进行交叉查阅。但是,这部分内容偶而发生与真实 M文件脱节的现象。 完整易读的 PDF文档:这部分内容与 HTML帮助文库完全对应。PDF文档不能直接从指令窗中开启,而必须借助 Adobe Acrobat Reader软件阅读。这种文件的版面清楚、规范,适宜有选择地系统阅读,也适宜于制作硬拷贝。 演示软件 demo :这是一个内容广泛的演示程序。MATLAB一向重视演示软件的设计,因此无论 MATLAB旧版还是新版,都随带各自的演示程序。只是,新版内容更丰富了 。 (3)M文件编辑、调试 的集成环境 新的编辑器有十分良好的文字编辑功能。它可采用色彩和制表位醒目地区分标识程序

中不同功能的文字,如运算指令、控制流指令、注释等。通过编辑器的菜单选项可以对编

辑器的文字、段落等风格进行类似Word那样的设置。 从 5.2版起,还新增了“变量现场显示”功能,只要把鼠标放在变量名上(Mouse over),就能在现场显示该变量的内容。 在 5.x版中,调试器已经被图形化,它与编辑器集成为一体。只需点动交互窗上的调试图标就可完成对程序的调试。 (4)M文件的性能剖析 调试器只负责M文件中语法错误和运行错误的定位,而性能剖析指令 profile 将给出程序各环节的耗时分析报告。5.3版剖析指令的分析报告特别详细,它将帮助用户寻找影响程序运行速度的“瓶颈”所在,以便改进。 (5)Notebook新的安装方式 从 4.2c版引入 Notebook以来,这种集文字、计算、图形于一体的“活”环境就深受用户赞赏。但直到 5.2版至,Notebook的安装都是与 MATLAB的安装同步进行的。这种安装方式的不便之处是:一旦 Word发生变动,就必须把 MATLAB全盘重装。5.3版改变了这种局面,它可以在 MATLAB指令窗中“随时”进行安装 Notebook,省时灵活。 (6)MATLAB环境可运行文件的多样化 旧版中,用户可编制和运行的程序文件只有 M脚本文件和 M函数文件。5.x版新增了产生伪代码 P文件的 pcode指令和产生二进制 MEX文件的 mex 指令。较之 M文件,这两种文件的运行速度要快得多,保密性也好。

1.2.3 MATLAB的图视系统

1.2.3.1 传统的图形表现力 MATLAB的图形可视能力在所有数学软件中是首屈一指的。MATLAB的图形系统有高层和低层两个部分组成。高层指令友善、简便;低层指令细腻、丰富、灵活。 一般说来,不管二元函数多么复杂,它的三维图形,仅需 10条左右指令,就能得到富于感染力的表现。数据和函数的图形可视手段包括:线的勾画、色图使用、浓谈处理、视

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

5

角选择、透视和裁剪。MATLAB有比较完备的图形标识指令,它们可标注:图名、轴名、解释文字和绘画图例。

1.2.3.2 5.3版的图视新特点 (1)5.3版的可编辑图形窗 对一般用户来说,在使用 MATLAB5.3 版图形功能时,感受最强烈的变化是图形窗。此前的图形窗只具单纯的显示功能。5.3版则不同,它是可编辑的图形显示窗。在 5.3的图形窗里,只需点动工具图标或菜单选项,就可直接对显示图形的各种“对象属性”进行随

心所欲的设置,可交互式地改变线条型式、粗细、颜色,可动态地变换观察视角,可在图

形窗随意位置标识文字或子图。5.3版图形窗是十分成功的“图柄”操作的图形用户界面。 (2)5.x版的 Tex特殊字符集 图形功能的另一个较大变化是标识能力的大大增强。具体表现:一,引进 Tex 特殊字符子集,可标注如 ,, βα ∑等数学字符;二,可书写上下标;三,可对英文、中文进行字体

形式和大小的设置。四,可采取多种方式进行多行文字注释。 (3)5.x版的简捷绘图指令 这组指令的特点是“指令的前两个字母是 ez ”,英文含义是“Easy to ”。这组指令有两个功能:一,直接表现用字符串描写的函数图形;二,与符号计算配套使用,作为符号

计算结果的图形可视工具。 这种指令的使用方法极其简单。例如使用一条指令 ezsurf('y/(1+x^2+y^2)') 就可以绘制

二元函数 221 yxyz

++= 的曲面。

这组指令与普通“数值型”绘图指令起着互为补充的作用。假若就方便易用排序,简捷指

令最方便,普通“数值型”绘图指令次之,低层指令最繁;假若就绘图的细致和个性化能

力排序,那末低层指令最强,简捷指令最弱。 (4)5.x版增强了高层绘图指令的排版能力 新版在同一图形窗口中可设置大小不同、非等距排列的任意个子图,而旧版只能开设

面积等分的子图。新版可以在同一图形中使用两套不同的坐标系统,而旧版不能。 (5)5.x版新增的其他高层绘图指令 增添了主要用于表现统计数据的面域图 area , 水平直方图 barh , 三维直方图 bar3 , bar3h , 二维、三维饼图 pie , pie3 , 三维杆图 stem3等;新增了四维数值表现力更强的切片等位线图 slicecontour ;改造了切片图 slice ,允许任意设置切面;新增了表现不规则数据点的三维网线和曲面图 trimesh , trisurf ;新增了若干色图函数,如 spring , summer , autumn , winter 等;增加了表现数据点的 8种新“点型”。 (6)5.x版读写图象文件能力的加强 旧版 MATLAB 能读写的图象文件类型比较狭窄。新版能够读写的文件格式有:bmp , hdf , jpg , jpeg , pex , tif , tiff , xwd 等。这无疑为进一步开拓图象处理方面的应用程序提供了更好的条件。 (7)5.x版低层指令结构的改变和能力的加强 “轴”对象上新增的“子对象”light 。该对象的增设,再配合增强了的光照模式 lighting 和控制光线反射的材质指令 material ,使得图形表现具真实感。 “轴”新增的照相机属性和投影属性,能更好地满足人们的视觉要求。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

6

“面”对象的面色属性可以采用纹理影射技术,从而可以在各种形状曲面上彩绘各种

图象,或表现表面的凹凸不平、材料纹路。 (8) 5.3版的图形用户界面 GUI制作工具 从 4.2c版起,MATLAB就开始向用户提供制作 GUI的指令,但十分稚嫩。随 5.0 , 5.1 , 5.2 版的升级,GUI制作工具不断改进。现在 5.3版中:不仅可以制作位置固定的用户菜单uimenu ,而且可以制作位置不固定的“现场”菜单(Context menu);用户控件 uicontrol已增加到 10种;不管是菜单,还是控件,都可以进行“使能”和“可见性”控制。 MATLAB向用户提供两种制作 GUI的途径:依靠指令制作 GUI;借助交互式工具 guide 制作 GUI 。这两种方法各有优缺点:前者灵活、细致;后者直观、全局观念强。用户交替运用这两种制作手段,可高效地制作 GUI ,开发出各种生动活泼的应用程序。

1.2.4 MATLAB的数学函数库

1.2.4.1 世界一流水平的数值计算函数库 MATLAB自问世起,就抱定一个宗旨:其所有数值计算算法都必须是国际公认的、最先进的、可靠算法;其程序由世界一流专家编制,并经高度优化;而执行算法的指令形式

则必须简单、易读易用。MATLAB正是仰赖这些高质量的数值计算函数赢得了声誉。 MATLAB数值计算函数库的另一个特点是其内容的基础性和通用性。它正由于这一特点,而适应了诸如自动控制、信号处理、动力工程、电力系统等应用学科的需要,并进而

开发出一系列应用工具包。 在整个 MATLAB的发展过程中,这数值计算函数库,从内容到形式,变化最小。

1.2.4.2 5.x版函数库的变化 (1)5.x版新增的常微分方程解算程序 5.x版MATLAB数值计算方面的最大变化是增添了一组常微分方程数值解算程序 ODE Solver 。这组解算程序无论是算法还是软件结构都十分精良,它包含 ode23 , ode45 , ode113 , ode23t ,ode15s , ode23s , ode23tb等不同解算指令,用以解算包括 Stiff方程在内的各种微分方程。 MATLAB5.x为解 ODE 问题所设计的文件十分严整,包括解算指令 Solver 、被 Solver调用的微分方程描述文件、进行积分算法参数设置的 odeset 和 odeget 、解算输出指令 odeplot , odephas2等。 (2)5.x新增的其他数值计算指令 5.x版新增的许多计算指令与数值计算方面的最新成就直接相关。举例来说,新版及时的增添了广义奇异值计算指令 gsvd ;高维快速 Fourier变换和反变换 fftn , ifftn ;高维插值指令 interpn 等。

1.2.4.3 5.x版的符号计算工具包 关于符号计算和数值计算优劣的争论曾经历过一段时间,但那是 20世纪九十年代以前的事。MathWorks公司打破门户之见,把 MAPLE的内核和数学函数库引入了 MATLAB,从而使 MATLAB 具有了数值和符号双重计算能力。用户可以视具体问题而进行适当的选择。比如,对于比较复杂的“初值类”非线性微分方程,有时符号计算或无法解、或求解

时间太长,而数值算法却比较有效;反之,对于边值类微分方程,数值算法的实现可能比

较繁琐,而符号计算有时倒比较简便。 MAPLE 的函数库十分庞大,包含 2000多个函数。它几乎囊括了一般用户所需的所有函数。与 5.x版 MATLAB配用的 Symbolic Math Toolbox 2.0 允许用户在三个不同层次上符

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

7

号计算。第一层次是,在进行符号对象定义后,直接利用 MATLAB格式进行矩阵分解、微分、积分、积分变换、代数方程求解、微分方程求解等运算。第二层次是,借助 maple 指令,把单个 MAPLE格式的指令送往 MAPLE引擎计算。第三层次是,借助 procread 把整段 Maple程序送往MAPLE计算。

1.2.5 MATLAB与外部程序的交互

MATLAB的卓越性能引发了用户的新需求:希望把在 MATLAB 环境中编制的程序开发成能脱离 MATLAB独立运行的程序;希望能在外部程序中调用 MATLAB作为计算引擎。需求决定商品,市场也真出现了诸如Mediva等商品软件,能把 MATLAB的M文件转变为独立于平台的 EXE可执行文件;出现许多专用软件把 MATLAB直接当计算引擎使用。鉴于此,MATLAB在 4.x版时代的后期,就尝试性地推出了自己的编译器。

1.2.5.1 与 5.3版配用的编译器 Compiler 2.0 伴随 MATLAB5.0版向 5.3版升级的过程中,变化较大,更新较快的是 MATLAB编译器。与 5.2版配用的是 Compiler 1.2版,而与 5.3版配用的则是 Compiler 2.0版、2.0.1版。 无论是 1.2版编译器,还是 2.0版编译器,它们都不但可以把全 M函数文件编译成独立应用程序,而且也可以把 C或 FORTRAN程序与 M文件混编成独立应用程序。这种程序的优点是:一,可以脱离 MATLAB环境独立运行;二,运行速度快。 MATLAB编译器无疑给用户开发计算类 EXE可执行程序提供了快捷、高效的工具。举例来说,假如用户想编制一个求解各类线性代数方程的可独立执行的程序,用户只要先在

MATLAB环境中编写由 30来条指令组成的 M函数文件,然后借助编译器把它变成独立执行的 EXE程序。这 EXE文件不但可以计算“恰定”方程,而且可以解算“超定”、“欠定”方程。值得指出:原M文件是不过 2K字节的小小程序。而编译生成的 EXE文件却超过 200K 字节,这可是一个不算小的程序。 与 1.2版相比,2.0版编译器具有处理高维数组、元胞数组、构架数组的能力,支持变长度输入输出宗量,支持多分支等控制流。

1.2.5.2 5.x版的 API应用程序接口 与 MATLAB编译器相比,MATLAB的 API应用程序接口问世得更晚,也更不成熟。MATLAB API 由一系列接口指令组成。借助这些接口指令,用户就可在 C或 FORTRAN中,或直接读写 MATLAB的MAT数据文件,或把 MATLAB当作计算引擎使用。

1.3 与MATLAB 5.3配用的 SIMULINK3.0

SIMULINK 是 MathWorks 公司开发的又一个产生重大影响的软件产品。它的前身SIMULIB 问世于 20 世纪九十年代初,以工具库的形式挂接在 MATLAB 3.5 版上。以SIMULINK名称广为人知,是在 MATLAB 4.2x版时期。SIMULINK不能独立运行,而只能在 MATLAB环境中运行。现在较为流行的有:与 MATLAB5.2版配用的 SIMULINK2.2 ;与 MATLAB5.3版配用的 SIMULINK3.0 。

1.3.1 SIMULINK的传统优点

不管是什么版本,SIMULINK 总由模块库、模型构造及分析指令、演示程序等三部分组成。在 SIMULINK环境中,对于由微分方程或差分方程描写的动态系统,用户无须编写文本形式的程序,而只要通过一些简单的鼠标操作就可形象地建立起被研究系统的数学模

型,并进行仿真和分析研究。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

8

举例来说,面对一个由微分方程描写的动态系统,用户有如下三个研究途径:一,直

接利用 ODE Solver数值解算指令编写表示那系统的 M文件;二,利用符号计算指令编写相应的程序;三,在 SIMULINK环境中建立那系统的方块图模型。三者比较而言,SIMULINK 是最合适、最方便、最直观的研究环境。在 SIMULINK中,那些以往不得不忽略的非线性、随机干扰等因素的影响也十分容易研究。

1.3.2 SIMULINK 3.0的特点

(1)SIMULINK系列软件产品 经过几年的努力,MathWorks公司已经把 SIMULINK发展成一个系列产品。例如,它与 Stateflow 状态流配合,可以建立更清晰的离散事件系统的概念化模型;与 Real-Time Workshop配合可产生进行实时仿真和运行于各种硬件的 C码;与 DSP Blockset 配用可以进行 DSP 装置和系统的快速设计和仿真。SIMULINK 在 Communication Toolbox、 Nonlinear Control Design Blockset、Power System Blockset等专业工具包的配合下,就可对通信系统、非线性控制系统、电力系统进行深入的建模、仿真和分析研究。 (2)SIMULINK3.0的模型库 与以前版本相比,SIMULINK3.0版本体模型库的结构已彻底改变。原先是子库分层的块图结构,现在是树状的文件夹形式,并且旧版中只有部分子库与新版文件夹对应。 与 SIMULINK3.0版配用的工具包显著增加。新版除把原 2.2版 12 个应用子库改造为12个文件夹之外,又增添了 2个新文件夹。 (3)模块的“使能”和“触发”功能 从 2.x版起,SIMULINK增设了“使能”和“触发”功能。这就为 SIMULINK进行离散事件系统的仿真打下了基础。借助“使能”和“触发”功能,用户可以建立各种根据状

态组合和迁移改变模型结构的复杂系统。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

1

2. 基础准备及入门

2.1 MATLAB 5.x 版对外部系统的要求

2.2 MATLAB的安装

2.3 MATLAB环境的启动

2.4 MATLAB指令窗简介

2.4.1 工具条

2.4.2 菜单选项

2.5 指令窗运行入门

2.5.1 最简单的计算器使用法

【例 2.5.1-1】求 23)]47(212[ ÷−×+ 的算术运算结果。

(1)用键盘在 MATLAB指令窗中输入以下内容 >> (12+2*(7-4))/3^2 (2)在上述表达式输入完成后,按【Enter】键,该就指令被执行。 (3)在指令执行后,MATLAB指令窗中将显示以下结果。 ans = 2

【例 2.5.1-2】简单矩阵

=

987654321

A 的输入步骤。

(1)在键盘上输入下列内容 A = [1,2,3; 4,5,6; 7,8,9] (2)按【Enter】键,指令被执行。 (3)在指令执行后,MATLAB指令窗中将显示以下结果: A = 1 2 3 4 5 6 7 8 9

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

2

【例 2.5.1-3】矩阵的分行输入 A=[1,2,3 4,5,6 7,8,9] (以下是显示结果) A = 1 2 3 4 5 6 7 8 9 【例 2.5.1-4】指令的续行输入(以下格式在除 Notebook外的 MATLAB环境中可运行) S = 1 – 1/2 + 1/3 –1/4 + 1/5 – 1/6 ... + 1/7 – 1/8 S =

0.6345

2.5.2 数值、变量和表达式

2.5.2.1 数值的记述

2.5.2.2 变量命名规则

2.5.2.3 MATLAB默认的预定义变量

2.5.2.4 表达式

2.5.2.5 复数和复数矩阵

【例 2.5.2.5-1】复数i

eziziz 6321 2,21,43

π

=+=+= 表达,及计算3

21

zzzz = 。

(1)经典教科书的直角坐标表示法 z1= 3 + 4i z1 = 3.0000 + 4.0000i (2)采用运算符构成的直角坐标表示法和极坐标表示法 z2 = 1 + 2 * i %运算符构成的直角坐标表示法 z3=2*exp(i*pi/6) %运算符构成的极坐标表示法 z=z1*z2/z3 z2 = 1.0000 + 2.0000i z3 = 1.7321 + 1.0000i z = 0.3349 + 5.5801i

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

3

【例 2.5.2.5-2】复数矩阵的生成及运算 A=[1,3;2,4]-[5,8;6,9]*i B=[1+5i,2+6i;3+8*i,4+9*i] C=A*B A = 1.0000 - 5.0000i 3.0000 - 8.0000i 2.0000 - 6.0000i 4.0000 - 9.0000i B = 1.0000 + 5.0000i 2.0000 + 6.0000i 3.0000 + 8.0000i 4.0000 + 9.0000i C = 1.0e+002 * 0.9900 1.1600 - 0.0900i 1.1600 + 0.0900i 1.3700 【例 2.5.2.5-3】求上例复数矩阵 C的实部、虚部、模和相角。 C_real=real(C) C_imag=imag(C) C_magnitude=abs(C) C_phase=angle(C)*180/pi %以度为单位计算相角 C_real = 99 116 116 137 C_imag = 0 -9 9 0 C_magnitude = 99.0000 116.3486 116.3486 137.0000 C_phase = 0 -4.4365 4.4365 0

2.5.3 计算结果的图形表示

【例 2.5.3-1】画出衰减振荡曲线 teyt

3sin3−

= 及其它的包络线 30

t

ey−

= 。 t的取值范围是]4,0[ π 。

t=0:pi/50:4*pi; %定义自变量取值数组 y0=exp(-t/3); %计算与自变量相应的 y0数组 y=exp(-t/3).*sin(3*t); %计算与自变量相应的 y数组 plot(t,y,'-r',t,y0,':b',t,-y0,':b') %用不同颜色、线型绘制曲线 grid %在“坐标纸”画小方格

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

4

0 2 4 6 8 10 12 14-1

-0.8

-0.6

-0.4

-0.2

0

0.2

0.4

0.6

0.8

1

图 2.5.3-1 衰减振荡曲线与包络

【例 2.5.3-2】画出22

22 )sin(

yx

yxz

+

+= 所表示的三维曲面。 yx, 的取值范围是 ]8,8[− 。

clear;x=-8:0.5:8; %定义自变量 x的一维刻度向量 y=x'; %定义自变量 y的一维刻度向量 X=ones(size(y))*x; %计算自变量平面上取值点 x坐标的二维数组 Y=y*ones(size(x)); %计算自变量平面上取值点 y坐标的二维数组

R=sqrt(X.^2+Y.^2)+eps; %计算中间变量 22 yxR += <5>

Z=sin(R)./R; %计算与自变量二维数组相应的函数值R

Rz sin= <6>

mesh(Z); %绘制三维网格图 colormap(hot) %指定网格图用 hot色图绘制

图 2.5.3-2 三维网线图

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

5

2.6 控制指令窗的指令、操作和标点

2.6.1 常用控制指令

2.6.2 数值计算结果的显示格式

2.6.3 指令行的编辑 【例 2.6.3-1】指令行操作过程示例。

(1)若用户想计算51

)3.0sin(21

+=

πy 的值,那末用户应依次键入以下字符

y1=2*sin(0.3*pi)/(1+sqrt(5)) (2)按【Enter】键,该指令便被执行,并给出以下结果 y1 = 0.5000 在以上操作和计算结束后,操作指令和计算结果都记录在 MATLAB工作内存中。因此,假如用户希望调回前面输入的指令重新运行,或希望对前面输入的指令加以修改后再运行,

那末只要反复按动键盘上的箭头键,就可从内存中把以前输入的那指令调回到当前行,以

供重新运行或修改后运行。新的计算结果,只可能被此后运行的指令所使用,而绝不会影

响以前生成的(非同名)变量的“内容”。 (3)利用指令回调,进行新的计算。

若又想计算51

)3.0cos(22

+=

πy ,用户当然可以象前一个算例那样,通过键盘把相应字

符一个一个“敲入”。但也可以较方便地用操作键获得该指令,具体办法是:先用á键调回已输入过的指令 y1=2*sin(0.3*pi)/(1+sqrt(5)) ;然后移动光标,把 y1改成 y2;把 sin 改成 cos 便可。即得 y2=2*cos(0.3*pi)/(1+sqrt(5)) y2 = 0.3633

2.6.4 指令行中的标点符号

2.6.5 内存变量的查阅和删除

2.6.5.1 指令 who和 whos 【例 2.6.5.1-1】用 who 检查 MATLAB内存变量。 在指令窗中运行以下指令,就可看到内存变量。 who Your variables are: R Y x y1 X Z y y2 【例 2.6.5.1-2】键入 whos ,获得驻留变量的详细情况:全部变量名,变量的数组维数,占用字节数,变量的类别(如双精度),是否复数等。 whos Name Size Bytes Class

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

6

R 33x33 8712 double array X 33x33 8712 double array Y 33x33 8712 double array Z 33x33 8712 double array x 1x33 264 double array y 33x1 264 double array y1 1x1 8 double array y2 1x1 8 double array Grand total is 4424 elements using 35392 bytes

2.6.5.2 内存浏览器和变量编辑器

2.6.6 变量的文件保存

2.6.6.1 通过菜单保存和再度读取变量

2.6.6.2 save 和 load 指令 【例 2.6.6.2-1】数据的存取。 (1)建立用户目录,并使之成为当前目录,保存数据 mkdir('c:\','my_dir'); %在 C盘上创建目录 my_dir cd c:\my_dir %使 c:\my_dir成为当前目录 save saf X Y Z %选择内存中的 X,Y,Z变量保存为 saf.mat文件 dir %显示目录上的文件 . .. saf.mat (2)清空内存,从 saf.mat 向内存装载变量 Z clear %清除内存中的全部变量 load saf Z %把 saf.mat文件中的 Z变量装入内存 who %检查内存中有什么变量 Your variables are: Z 〖说明〗 l 本例运用了例 2.5.3-2和例 2.6.3-1中指令运行后产生的变量。 l 如果一组数据是经过长时间的复杂计算后获得的,那末为避免再次重复计算,常使用

save 加以保存。此后,每当需要,都可通过 load重新获取这组数据。这种处理模式常在实际中被采用。

2.7 操作实录指令和M脚本文件

2.7.1 操作实录指令

2.7.2 M脚本文件编写初步

2.8 在线自学引导和演示指令

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

7

2.8.1 在线提供的入门引导

2.8.2 在线演示

2.9 帮助系统

2.9.1 帮助系统的构造

2.9.2 指令窗中的 help 指令

2.9.2.1 直接使用 help获得指令的使用说明 【例 2.9.2.1-1】假如准确知道所要求助的主题词,或指令名称,那末使用 help 是获得在线帮助的最简单有效的途径。本例演示:关于矩阵对数函数 logm 使用说明的在线求助。 help logm LOGM Matrix logarithm.

L = LOGM(A) is the matrix logarithm of A, the inverse of EXPM(A). Complex results are produced if A has negative eigenvalues. A warning message is printed if the computed expm(L) is not close to A.

[L,esterr] = logm(A) does not print any warning message, but returns an estimate of the relative residual, norm(expm(L)-A)/norm(A).

If A is real symmetric or complex Hermitian, then so is LOGM(A).

Some matrices, like A = [0 1; 0 0], do not have any logarithms, real or complex, and LOGM cannot be expected to produce one.

See also EXPM, SQRTM, FUNM.

2.9.2.2 使用 help指令进行分类搜索 【例 2.9.2.2-1】运行不带任何限定的 help,可以得到分类名称明细表。 help HELP topics: matlab\general - General purpose commands. matlab\ops - Operators and special characters. matlab\lang - Programming language constructs. matlab\elmat - Elementary matrices and matrix manipulation. matlab\elfun - Elementary math functions. matlab\specfun - Specialized math functions. ...... ...... For more help on directory/topic, type "help topic".

2.9.2.3 采用 help topic指令形式获得具体子类的指令明细 【例 2.9.2.3-1】如果用户想知道有关矩阵操作指令一栏表,那末就运行以下指令。 help elmat Elementary matrices and matrix manipulation. Elementary matrices. zeros - Zeros array.

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

8

ones - Ones array. ...... ...... Basic array information. size - Size of matrix. length - Length of vector. ...... ...... Matrix manipulation. reshape - Change size. diag - Diagonal matrices and diagonals of matrix. ...... ...... Special variables and constants. ans - Most recent answer. eps - Floating point relative accuracy. ...... ...... Specialized matrices. compan - Companion matrix. gallery - Higham test matrices. ...... ...... 〖说明〗 l 省略号由笔者所加,用来表示被删除的内容。这样做是出于节省篇幅的考虑。

2.9.3 指令窗中的 lookfor 指令 【例 2.9.3-1】查找包含积分这个关键词的所有指令。 lookfor integral ELLIPKE Complete elliptic integral. EXPINT Exponential integral function. DBLQUAD Numerically evaluate double integral. INNERLP Used with DBLQUAD to evaluate inner loop of integral. QUAD Numerically evaluate integral, low order method. QUAD8 Numerically evaluate integral, higher order method. COSINT Cosine integral function. SININT Sine integral function. ASSEMA Assembles area integral contributions in a PDE problem. COSINT Cosine integral function. FOURIER Fourier integral transform. IFOURIER Inverse Fourier integral transform. SININT Sine integral function.

2.9.4 其他起帮助作用的工具指令

2.9.5 专门的在线帮助窗

2.9.6 超文本形式的用户指南和指令手册

2.9.7 用户指南和指令手册的 PDF文件

2.10 文件管理

2.10.1 MATLAB的搜索路径

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

9

【例 2.10.1-1】sqrt是 MATLAB的内部函数。下面观察,当对 sqrt重新赋值后,所产生的不正常现象。 (1)正常运作情况 sqrt(2) ans =

1.4142 which sqrt sqrt is a built-in function. exist sqrt %当用 exist判断 sqrt时,显示结果“5”指明是内建函数。 ans = 5 (2)不正常运作 sqrt=[1, 0] %把 sqrt赋值成一个两个元素的行向量 sqrt = 1 0 sqrt(2) %这时该指令给出结果是 0,而不是正常的平方根值 1.4142 ans = 0 which sqrt %当用 which检查 sqrt在哪里时,显示的却是“内存变量” sqrt is a variable. exist sqrt %当用 exist判断 sqrt时,显示结果“1”指明是变量 ans = 1

2.10.2 用户目录的设置

2.10.3 MATLAB搜索路径的扩展和修改

2.10.3.1 利用 path 指令扩展搜索路径

2.10.3.2 利用路径浏览器修改搜索路径

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

1

3 数值数组及其运算

3.1 引导 【*例 3.1-1】绘制函数 xxey −= 在 10 ≤≤ x 时的曲线。

x=0:0.1:1 %定义自变量的采样点取值数组 y=x.*exp(-x) %利用数组运算计算各自变量采样点上的函数值 plot(x,y),xlabel('x'),ylabel('y'),title('y=x*exp(-x)') %绘图 x = Columns 1 through 7 0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 Columns 8 through 11 0.7000 0.8000 0.9000 1.0000 y = Columns 1 through 7 0 0.0905 0.1637 0.2222 0.2681 0.3033 0.3293 Columns 8 through 11 0.3476 0.3595 0.3659 0.3679

0 0.2 0.4 0.6 0.8 10

0.05

0.1

0.15

0.2

0.25

0.3

0.35

0.4

x

y

y=x*exp(-x)

图 3.1-1

3.2 一维数组的创建和寻访

3.2.1 一维数组的创建

3.2.2 一维数组的子数组寻访和赋值 【*例 3.2.2-1】子数组的寻访(Address)。 rand('state',0) %把均匀分布伪随机发生器置为 0状态

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

2

x=rand(1,5) %产生 )51( × 的均布随机数组 x =

0.9501 0.2311 0.6068 0.4860 0.8913

x(3) %寻访数组 x的第三个元素。 ans =

0.6068

x([1 2 5]) %寻访数组 x的第一、二、五个元素组成的子数组。 ans =

0.9501 0.2311 0.8913

x(1:3) %寻访前三个元素组成的子数组 ans = 0.9501 0.2311 0.6068 x(3:end) %寻访除前 2个元素外的全部其他元素。end是最后一个元素的下标。 ans = 0.6068 0.4860 0.8913 x(3:-1:1) %由前三个元素倒排构成的子数组 ans = 0.6068 0.2311 0.9501 x(find(x>0.5)) %由大于 0.5的元素构成的子数组 ans =

0.9501 0.6068 0.8913 x([1 2 3 4 4 3 2 1]) %对元素可以重复寻访,使所得数组长度允许大于原数组。 ans = Columns 1 through 7 0.9501 0.2311 0.6068 0.4860 0.4860 0.6068 0.2311 Column 8 0.9501 【*例 3.2.2-2】子数组的赋值(Assign)。 x(3) = 0 %把上例中的第三个元素重新赋值为 0 x = 0.9501 0.2311 0 0.4860 0.8913 x([1 4])=[1 1] %把当前 x数组的第一、四个元素都赋值为 1。 x = 1.0000 0.2311 0 1.0000 0.8913

3.3 二维数组的创建

3.3.1 直接输入法 【*例 3.3.1-1】在MATLAB环境下,用下面三条指令创建二维数组 C。 a=2.7358; b=33/79; %这两条指令分别给变量 a ,b 赋值。 C=[1,2*a+i*b,b*sqrt(a);sin(pi/4),a+5*b,3.5+i] %这指令用于创建二维数组 C C = 1.0000 5.4716 + 0.4177i 0.6909

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

3

0.7071 4.8244 3.5000 + 1.0000i 【*例 3.3.1-2】复数数组的另一种输入方式。 M_r=[1,2,3;4,5,6],M_i=[11,12,13;14,15,16] CN=M_r+i*M_i %由实部、虚部数组构成复数数组 M_r = 1 2 3 4 5 6 M_i = 11 12 13 14 15 16 CN = 1.0000 +11.0000i 2.0000 +12.0000i 3.0000 +13.0000i 4.0000 +14.0000i 5.0000 +15.0000i 6.0000 +16.0000i

3.3.2 利用M文件创建和保存数组 【例 3.3.2-1】创建和保存数组 AM的 MyMatrix.m 文件。 % MyMatrix.m Creation and preservation of matrix AM AM=[101,102,103,104,105,106,107,108,109;... 201,202,203,204,205,206,207,208,209;... 301,302,303,304,305,306,307,308,309];

3.4 二维数组元素的标识

3.4.1 “全下标”标识

3.4.2 “单下标”标识

3.4.3 “逻辑 1”标识

【*例 3.4.3-1】找出数组

−−−−

=5311342024

A 中所有绝对值大于 3的元素。

A=zeros(2,5); %预生成一个(2*5)全零数组 A(:)=-4:5 %运用“全元素”赋值法获得 A L=abs(A)>3 %产生与 A同维的“0-1”逻辑值数组 islogical(L) %判断 L是否逻辑值数组。输出若为 1,则是。 X=A(L) %把 L中逻辑值 1对应的 A元素取出 A = -4 -2 0 2 4 -3 -1 1 3 5 L = 1 0 0 0 1 0 0 0 0 1 ans = 1 X =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

4

-4 4 5 【*例 3.4.3-2】演示逻辑数组与一般双精度数值数组的关系和区别。(本例在例 3.4.3-1基础上进行)。 (1)逻辑数组与双精度数组的相同之处 Num=[1,0,0,0,1;0,0,0,0,1]; %产生与 L数组外表完全相同的“双精度数组” N_L=Num==L %假如 Num与 L数值相等,则应得 1 。 c_N=class(Num) %用 class指令检查 Num的类属 c_L=class(L) %用 class指令检查 L的类属 N_L = 1 1 1 1 1 1 1 1 1 1 c_N = double c_L = double (2)逻辑数组与一般双精度数组的差别 islogical(Num) %检查 Num是否属于逻辑数组类 Y=A(Num) %试探 Num能否象 L一样具有标识作用 ans = 0 ??? Index into matrix is negative or zero. See release notes on changes to logical indices.

3.5 二维数组的子数组寻访和赋值 【*例 3.5-1】不同赋值方式示例。 A=zeros(2,4) %创建 )42( × 的全零数组 A = 0 0 0 0 0 0 0 0 A(:)=1:8 %全元素赋值方式 A = 1 3 5 7 2 4 6 8 s=[2 3 5]; %产生单下标数组行数组 A(s) %由“单下标行数组”寻访产生 A元素组成的行数组 Sa=[10 20 30]' %Sa是长度为 3的“列数组” A(s)=Sa %单下标方式赋值 ans = 2 3 5 Sa = 10 20 30 A = 1 20 30 7

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

5

10 4 6 8 A(:,[2 3])=ones(2) %双下标赋值方式:把 A的第 2、3列元素全赋为 1 A = 1 1 1 7

10 1 1 8

3.6 执行数组运算的常用函数

3.6.1 函数数组运算规则的定义:

3.6.2 执行数组运算的常用函数 【*例 3.6.2-1】演示 pow2的数组运算性质。 A=[1:4;5:8] %生成 )42( × 数组 A = 1 2 3 4 5 6 7 8 pow2(A) %计算 ][22 ijaA = 的结果也是 )42( × 数组 ans = 2 4 8 16

32 64 128 256

3.7 数组运算和矩阵运算

3.7.1 数组运算和矩阵运算指令对照汇总 【*例 3.7.1-1】两种不同转置的比较 clear;A=zeros(2,3); A(:)=1:6; %全元素赋值法 A=A*(1+i) %运用标量与数组乘产生复数矩阵 A_A=A.' %数组转置,即非共轭转置 A_M=A' %矩阵转置,即共轭转置 A = 1.0000 + 1.0000i 3.0000 + 3.0000i 5.0000 + 5.0000i 2.0000 + 2.0000i 4.0000 + 4.0000i 6.0000 + 6.0000i A_A = 1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i 4.0000 + 4.0000i 5.0000 + 5.0000i 6.0000 + 6.0000i A_M = 1.0000 - 1.0000i 2.0000 - 2.0000i 3.0000 - 3.0000i 4.0000 - 4.0000i 5.0000 - 5.0000i 6.0000 - 6.0000i

3.8 多项式的表达方式及其操作

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

6

3.8.1 多项式的表达和创建

3.8.1.1 多项式表达方式的约定

3.8.1.2 多项式行向量的创建方法 【*例 3.8.1.2-1】求 3阶方阵 A的特征多项式。 A=[11 12 13;14 15 16;17 18 19]; PA=poly(A) %A的特征多项式 PPA=poly2str(PA,'s') %以较习惯的方式显示多项式 PA = 1.0000 -45.0000 -18.0000 -0.0000 PPA = s^3 - 45 s^2 - 18 s - 2.8387e-015 【*例 3.8.1.2-2】由给定根向量求多项式系数向量。 R=[-0.5,-0.3+0.4*i,-0.3-0.4*i]; %根向量 P=poly(R) %R的特征多项式 PR=real(P) %求 PR的实部 PPR=poly2str(PR,'x') P = 1.0000 1.1000 0.5500 0.1250 PR = 1.0000 1.1000 0.5500 0.1250 PPR = x^3 + 1.1 x^2 + 0.55 x + 0.125

3.8.2 多项式运算函数

【*例 3.8.2-1】求1

)1)(4)(2(3

2

+++++

sssss

的“商”及“余”多项式。

p1=conv([1,0,2],conv([1,4],[1,1])); %计算分子多项式 p2=[1 0 1 1]; %注意缺项补零 [q,r]=deconv(p1,p2); cq='商多项式为 '; cr='余多项式为 '; disp([cq,poly2str(q,'s')]),disp([cr,poly2str(r,'s')]) 商多项式为 s + 5 余多项式为 5 s^2 + 4 s + 3 【*例 3.8.2-2】两种多项式求值指令的差别。 S=pascal(4) %生成一个 4阶方阵 P=poly(S);PP=poly2str(P,'s') PA=polyval(P,S) %独立变量取数组 S元素时的多项式值 PM=polyvalm(P,S) %独立变量取矩阵 S时的多项式值 S = 1 1 1 1 1 2 3 4 1 3 6 10 1 4 10 20 PP = s^4 - 29 s^3 + 72 s^2 - 29 s + 1 PA =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

7

1.0e+004 * 0.0016 0.0016 0.0016 0.0016 0.0016 0.0015 -0.0140 -0.0563 0.0016 -0.0140 -0.2549 -1.2089 0.0016 -0.0563 -1.2089 -4.3779 PM = 1.0e-011 * -0.0077 0.0053 -0.0096 0.0430 -0.0068 0.0481 -0.0110 0.1222 0.0075 0.1400 -0.0095 0.2608 0.0430 0.2920 -0.0007 0.4737 【*例 3.8.2-3】部分分式展开。 a=[1,3,4,2,7,2]; %分母多项式系数向量 b=[3,2,5,4,6]; %分子多项式系数向量 [r,s,k]=residue(b,a) r = 1.1274 + 1.1513i 1.1274 - 1.1513i -0.0232 - 0.0722i -0.0232 + 0.0722i 0.7916 s = -1.7680 + 1.2673i -1.7680 - 1.2673i 0.4176 + 1.1130i 0.4176 - 1.1130i -0.2991 k = []

3.9 标准数组生成函数和数组操作函数

3.9.1 标准数组生成函数 【*例 3.9.1-1】标准数组产生的演示。 ones(1,2) %产生长度为 2的全 1行数组 ans = 1 1 ones(2) %产生 )22( × 的全 1阵 ans = 1 1 1 1 randn('state',0) %把正态随机数发生器置 0 randn(2,3) %产生 )32( × 的正态随机阵 ans = -0.4326 0.1253 -1.1465 -1.6656 0.2877 1.1909 D=eye(3) %产生 )33( × 的单位阵 D = 1 0 0

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

8

0 1 0 0 0 1 diag(D) %取 D阵的对角元 ans = 1 1 1 diag(diag(D)) %内 diag取 D的对角元,外 diag利用一维数组生成对角阵 ans = 1 0 0 0 1 0 0 0 1 repmat(D,1,3) %在水平方向“铺放”三个 D阵 ans = 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1 0 0 1 0 0 1

3.9.2 数组操作函数 【*例 3.9.2-1】diag与 reshape的使用演示。 a=-4:4 %产生一维数组 A=reshape(a,3,3) %把一维数组 a重排成 )33( × 的二维数组 a = -4 -3 -2 -1 0 1 2 3 4 A = -4 -1 2 -3 0 3 -2 1 4 a1=diag(A,1) %取 A阵“第一上对角线”的元素 a1 = -1 3 A1=diag(a1,-1) %产生以 a1数组元素为“第一下对角线”元素的二维数组 A1 = 0 0 0 -1 0 0 0 3 0 【*例 3.9.2-2】数组转置、对称交换和旋转操作后果的对照比较。 A A = -4 -1 2 -3 0 3 -2 1 4 A.' %转置 ans = -4 -3 -2 -1 0 1 2 3 4

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

9

flipud(A) %上下对称交换 ans = -2 1 4 -3 0 3 -4 -1 2 fliplr(A) %左右对称交换 ans = 2 -1 -4 3 0 -3 4 1 -2 rot90(A) %逆时针旋转 90度 ans = 2 3 4 -1 0 1 -4 -3 -2 【*例 3.9.2-3】演示 Kronecker乘法不具备“可交换规律”。 B=eye(2) %产生 )22( × 单位阵 C=reshape(1:4,2,2) %利用重组操作产生 )22( × 矩阵 B = 1 0 0 1 C = 1 3 2 4 kron(B,C) ans = 1 3 0 0 2 4 0 0 0 0 1 3 0 0 2 4 kron(C,B) ans = 1 0 3 0 0 1 0 3 2 0 4 0 0 2 0 4

3.10 数组构作技法综合 【*例 3.10-1】数组的扩展。 (1)数组的赋值扩展法 A=reshape(1:9,3,3) %创建 )33( × 数组 A A = 1 4 7 2 5 8 3 6 9 A(5,5)=111 %扩展为 )55( × 数组。扩展部分除(5,5)元素为 111外,其余均为 0。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

10

A = 1 4 7 0 0 2 5 8 0 0 3 6 9 0 0 0 0 0 0 0 0 0 0 0 111 A(:,6)=222 %标量对子数组赋值,并扩展为 )65( × 数组。 A = 1 4 7 0 0 222 2 5 8 0 0 222 3 6 9 0 0 222 0 0 0 0 0 222 0 0 0 0 111 222 (2)多次寻访扩展法 AA=A(:,[1:6,1:6]) %相当于指令 repmat(A,1,2),读者可以试试。 AA = 1 4 7 0 0 222 1 4 7 0 0 222 2 5 8 0 0 222 2 5 8 0 0 222 3 6 9 0 0 222 3 6 9 0 0 222 0 0 0 0 0 222 0 0 0 0 0 222 0 0 0 0 111 222 0 0 0 0 111 222 (3)合成扩展法 B=ones(2,6) %创建 )62( × 全 1数组 B = 1 1 1 1 1 1 1 1 1 1 1 1 AB_r=[A;B] %行数扩展合成 AB_r = 1 4 7 0 0 222 2 5 8 0 0 222 3 6 9 0 0 222 0 0 0 0 0 222 0 0 0 0 111 222 1 1 1 1 1 1 1 1 1 1 1 1 AB_c=[A,B(:,1:5)'] %列数扩展合成 AB_c = 1 4 7 0 0 222 1 1 2 5 8 0 0 222 1 1 3 6 9 0 0 222 1 1 0 0 0 0 0 222 1 1 0 0 0 0 111 222 1 1 【*例 3.10-2】提取子数组,合成新数组。 A %重显 A数组 A = 1 4 7 0 0 222 2 5 8 0 0 222 3 6 9 0 0 222 0 0 0 0 0 222 0 0 0 0 111 222 AB_BA=triu(A,1)+tril(A,-1) %利用操作函数,使主对角元素为全 0 AB_BA =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

11

0 4 7 0 0 222 2 0 8 0 0 222 3 6 0 0 0 222 0 0 0 0 0 222 0 0 0 0 0 222 AB1=[A(1:2,end:-1:1);B(1,:)] %灵活合成 AB1 = 222 0 0 7 4 1 222 0 0 8 5 2 1 1 1 1 1 1 【*例 3.10-3】单下标寻访和 reshape指令演示。 clear %清除内存变量 A=reshape(1:16,2,8) %变一维数组成 )82( × 数组 A = 1 3 5 7 9 11 13 15 2 4 6 8 10 12 14 16 reshape(A,4,4) %变 )82( × 数组为 )44( × 数组 ans = 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16 s=[1 3 6 8 9 11 14 16]; %定义“单下标”数组 A(s)=0 %利用“单下标”数组对 A的元素重新赋值 A = 0 0 5 7 0 0 13 15 2 4 0 0 10 12 0 0 【*例 3.10-4】“对列(或行)同加一个数”三种的操作方法。 clear,A=reshape(1:9,3,3) A = 1 4 7 2 5 8 3 6 9 b=[1 2 3];A_b1=A-b([1 1 1],:) %使 A的第 1,2,3行分别减 b向量[1 2 3] A_b1 = 0 2 4 1 3 5 2 4 6 A_b2=A-repmat(b,3,1) A_b2 = 0 2 4 1 3 5 2 4 6 A_b3=[A(:,1)-b(1),A(:,2)-b(2),A(:,3)-b(3)] A_b3 = 0 2 4 1 3 5 2 4 6

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

12

【*例 3.10-5】逻辑函数的运用示例。 randn('state',1),R=randn(3,6) %创建正态随机阵 R = 0.8644 0.8735 -1.1027 0.1684 -0.5523 -0.6149 0.0942 -0.4380 0.3962 -1.9654 -0.8197 -0.2546 -0.8519 -0.4297 -0.9649 -0.7443 1.1091 -0.2698 L=abs(R)<0.5|abs(R)>1.5 %不等式条件运算,结果给出逻辑数组 L = 0 0 0 1 0 0 1 1 1 1 0 1 0 1 0 0 0 1 R(L)=0 %“逻辑 1”对应的元素赋 0值。 R = 0.8644 0.8735 -1.1027 0 -0.5523 -0.6149 0 0 0 0 -0.8197 0 -0.8519 0 -0.9649 -0.7443 1.1091 0 s=(find(R==0))' %利用 find获得符合关系等式条件的元素“单下标” s = 2 5 6 8 10 11 17 18 R(s)=111 %利用“单下标”定位赋值 R = 0.8644 0.8735 -1.1027 111.0000 -0.5523 -0.6149 111.0000 111.0000 111.0000 111.0000 -0.8197 111.0000 -0.8519 111.0000 -0.9649 -0.7443 1.1091 111.0000 [ii,jj]=find(R<0); %利用 find获得符合关系等式条件的元素“双下标” disp(ii'),disp(jj') 3 1 3 3 1 2 1 1 3 3 4 5 5 6

3.11 高维数组

3.11.1 高维数组的创建 【*例 3.11.1-1】“全下标”元素赋值方式创建高维数组演示。 A(2,2,2)=1 %单元素赋值创建 )222( ×× 数组 A(:,:,1) = 0 0 0 0 A(:,:,2) = 0 0

0 1

B(2,5,:)=1:3 %子数组赋值创建 )352( ×× 数组 B(:,:,1) = 0 0 0 0 0 0 0 0 0 1 B(:,:,2) = 0 0 0 0 0 0 0 0 0 2

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

13

B(:,:,3) = 0 0 0 0 0 0 0 0 0 3 【*例 3.11.1-2】低维数组合成高维数组。 clear,A=ones(2,3);A(:,:,2)=ones(2,3)*2;A(:,:,3)=ones(2,3)*3 A(:,:,1) = 1 1 1 1 1 1 A(:,:,2) = 2 2 2 2 2 2 A(:,:,3) = 3 3 3 3 3 3 【*例 3.11.1-3】由函数 ones, zeros, rand, randn直接创建标准高维数组的示例。 rand('state',1111),rand(2,4,3) ans(:,:,1) = 0.6278 0.9748 0.2585 0.6949 0.2544 0.2305 0.0313 0.1223 ans(:,:,2) = 0.4889 0.3898 0.8489 0.0587 0.9138 0.3071 0.4260 0.6331 ans(:,:,3) = 0.2802 0.2073 0.7438 0.2714 0.4051 0.2033 0.4566 0.2421 【*例 3.11.1-4】借助 cat, repmat, reshape等函数构作高维数组。 (1)cat构作高维数组示例 cat(3,ones(2,3),ones(2,3)*2,ones(2,3)*3) ans(:,:,1) = 1 1 1 1 1 1 ans(:,:,2) = 2 2 2 2 2 2 ans(:,:,3) = 3 3 3 3 3 3 (2)repmat构作高维数组示例 repmat(ones(2,3),[1,1,3]) ans(:,:,1) = 1 1 1 1 1 1 ans(:,:,2) = 1 1 1 1 1 1 ans(:,:,3) = 1 1 1 1 1 1 (3)reshape构作高维数组示例

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

14

reshape(1:12,2,2,3) ans(:,:,1) = 1 3 2 4 ans(:,:,2) = 5 7 6 8 ans(:,:,3) = 9 11 10 12

3.11.2 高维数组的标识 【*例 3.11.2-1】维数、大小和长度 clear;A=reshape(1:24,2,3,4); dim_A=ndims(A) %测量 A的维数 size_A=size(A) %测量 A的大小 L_A=length(A) %求 A的长度 dim_A = 3 size_A = 2 3 4 L_A = 4

3.11.3 高维数组构作和操作函数汇总 【*例 3.11.3-1】数组元素对称交换指令 flipdim的使用示例。 A=reshape(1:18,2,3,3) %创建 3维数组 A(:,:,1) = 1 3 5 2 4 6 A(:,:,2) = 7 9 11 8 10 12 A(:,:,3) = 13 15 17 14 16 18 flipdim(A,1) %关于“行平分面”交换对称位置上的元素 ans(:,:,1) = 2 4 6 1 3 5 ans(:,:,2) = 8 10 12 7 9 11 ans(:,:,3) = 14 16 18 13 15 17 flipdim(A,3) %关于“页平分面”交换对称位置上的元素 ans(:,:,1) = 13 15 17 14 16 18 ans(:,:,2) = 7 9 11

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

15

8 10 12 ans(:,:,3) = 1 3 5 2 4 6 【*例 3.11.3-2】数组的“维序号左移”重组。 shiftdim(A,1) %“维号左移 1位”重组,使 )332( ×× 数组变成 )233( ×× 数组 ans(:,:,1) = 1 7 13 3 9 15 5 11 17 ans(:,:,2) = 2 8 14 4 10 16 6 12 18 shiftdim(A,2) %“维号左移 2位”重组,使 )332( ×× 数组变成 )323( ×× 数组 ans(:,:,1) = 1 2 7 8 13 14 ans(:,:,2) = 3 4 9 10 15 16 ans(:,:,3) = 5 6 11 12

17 18 【*例 3.11.3-3】广义非共轭转置。

permute(A,[2,3,1]) %相当于 shiftdim(A,1) ans(:,:,1) = 1 7 13 3 9 15 5 11 17 ans(:,:,2) = 2 8 14 4 10 16 6 12 18 permute(A,[1,3,2]) ans(:,:,1) = 1 7 13 2 8 14 ans(:,:,2) = 3 9 15 4 10 16 ans(:,:,3) = 5 11 17 6 12 18 【*例 3.11.3-4】“孤维”的撤消和降维。

B=cat(4,A(:,:,1),A(:,:,2),A(:,:,3)) %串接为 4维数组

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

16

B(:,:,1,1) = 1 3 5 2 4 6 B(:,:,1,2) = 7 9 11 8 10 12 B(:,:,1,3) = 13 15 17 14 16 18 size(B) %测量数组 B的大小 ans = 2 3 1 3 C=squeeze(B) %撤消长度为 1的“孤维”,使原 4维数组减为 3维数组。 C(:,:,1) = 1 3 5 2 4 6 C(:,:,2) = 7 9 11 8 10 12 C(:,:,3) = 13 15 17 14 16 18 size(C) ans = 2 3 3 【*例 3.11.3-5】赋“空阵”值操作。 A=reshape(1:18,2,3,3) %创建 3维数组 A(:,:,1) = 1 3 5 2 4 6 A(:,:,2) = 7 9 11 8 10 12 A(:,:,3) = 13 15 17 14 16 18 A(:,2:3,:)=[] %赋“空”,使原 A数组的第二、三列消失。 B=A; A(:,:,1) = 1 2 A(:,:,2) = 7 8 A(:,:,3) = 13 14 size(A) ans = 2 1 3 A_1=squeeze(A) %撤消“孤维”,数组由 3维降为 2维。 A_1 = 1 7 13

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

17

2 8 14 size(B) %B数组与 A同样存在“孤维” ans = 2 1 3 B(:,1,:)=[] %对“孤维”赋“空”,不能降维! B = Empty array: 2-by-0-by-3

3.12 “非数”和“空”数组

3.12.1 非数 NaN 【*例 3.12.1-1】非数的产生和性质演示。 (1)非数的产生 a=0/0,b=0*log(0),c=inf-inf Warning: Divide by zero. a = NaN Warning: Log of zero. b = NaN c = NaN (2)非数的传递性 0*a,sin(a) ans = NaN ans = NaN (3)非数的不可比较性 a==nan %该指令想计算“a等于非数吗?”。但不能给出正确的判断结果。 ans = 0 (4)非数不能进行关系运算 a~=nan %该指令“a不是非数吗?”,也不可能给出正确的判断结果。 a==b %两个非数不存在“等”与“不等”的概念 b>c %两个非数不能比较大小 ans = 1 ans = 0 ans = 0 (5)非数的属性判断 class(a) %数据类型归属 isnan(a) %该指令是唯一能正确判断非数的指令。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

18

ans = double ans = 1 【*例 3.12.1-2】非数元素的寻访 %创建带非数的二维数组 rand('state',0) %将随机发生器置 0。目的是使读者便于把自己运算结果与本书对照。 R=rand(2,5);R(1,5)=NaN;R(2,3)=NaN R = 0.9501 0.6068 0.8913 0.4565 NaN 0.2311 0.4860 NaN 0.0185 0.4447 isnan(R) %对数组元素是否非数进行判断 ans = 0 0 0 0 1 0 0 1 0 0 %找出非数元素的位置标识 Linear_index=find(isnan(R)) %非数的“单下标”标识 [r_index,c_index]=ind2sub(size(R),Linear_index); %转换成“全下标”标识 disp('r_index c_index'),disp([r_index c_index]) Linear_index = 6 9 r_index c_index 2 3

1 5

3.12.2 “空”数组 【*例 3.12.2-1】关于“空”数组的算例。 (1)创建“空”数组的几种方法 a=[],b=ones(2,0),c=zeros(2,0),d=eye(2,0),f=rand(2,3,0,4) a = [] b = Empty matrix: 2-by-0 c = Empty matrix: 2-by-0 d = Empty matrix: 2-by-0 f = Empty array: 2-by-3-by-0-by-4 (2)“空”数组的属性 class(a) %“空”的数据类别 isnumeric(a) %是数值数组类吗 isempty(a) %唯一可正确判断数组是否“空”的指令 ans = double ans = 1 ans = 1

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

19

which a %变量 a是什么 ndims(a) %数组 a的维数 size(a) %a数组的大小 a is a variable. ans = 2 ans = 0 0 (3)“空”数组不具备一般的传递性 b_c1=b.*c %两个空阵的点乘 b_c2=b'*c %矩阵乘一。注意:生成矩阵为 0-by-0,故“空”。 b_c3=b*c' %矩阵乘二。注意:生成矩阵为 2-by-2。 b_c1 = Empty matrix: 2-by-0 b_c2 = [] b_c3 = 0 0 0 0 (4)“空”数组的比较要谨慎 a==b %结果解释不合理 Warning: [] == X is technically incorrect. Use isempty(X) instead. ans = 0 b==c %结果可合理解释为“无法比较” ans = Empty matrix: 2-by-0 c>d %结果可合理解释“无法比较” ans = Empty matrix: 2-by-0 a==0 %结果可解释为“不等于” Warning: Future versions will return empty for empty == scalar comparisons. ans = 0 a~=0 %结果解释为“是不等” Warning: Future versions will return empty for empty ~= scalar comparisons. ans = 1 (5)没有“空”数组参与运算时,结果中的“空”有合理的解释 A=reshape(-4:5,2,5) %创建一个数值数组 A A = -4 -2 0 2 4 -3 -1 1 3 5 L2=A>10 %检查 A中大于 10的元素位置 find(L2) %找出 L2逻辑数组中非 0元素的“单下标”标识。 L2 =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

20

0 0 0 0 0 0 0 0 0 0 ans = [] (6)“空”数组用于子数组的删除和大数组的维数收缩(参见例 3.11.3-5) A(:,[2,4])=[] %删除 A的第二、四列 A = -4 0 4 -3 1 5

3.13 关系操作和逻辑操作

3.13.1 关系操作 【*例 3.13.1-1】关系运算示例。 A=1:9,B=10-A,r0=(A<4),r1=(A==B) A = 1 2 3 4 5 6 7 8 9 B = 9 8 7 6 5 4 3 2 1 r0 = 1 1 1 0 0 0 0 0 0 r1 = 0 0 0 0 1 0 0 0 0 【*例 3.13.1-2】关系运算运用之一:求近似极限,修补图形缺口。 t=-2*pi:pi/10:2*pi; %该自变量数组中,存在 0值。 y=sin(t)./t; %在 t=0处,按 IEEE规则,计算将产生 NaN tt=t+(t==0)*eps; %逻辑数组参与运算,使 0元素被一个“机器零”小数代替。 yy=sin(tt)./tt; %用数值可算的 sin(eps)/eps近似替代 sin(0)/0极限. subplot(1,2,1),plot(t,y),axis([-7,7,-0.5,1.2]), xlabel('t'),ylabel('y'),title('残缺图形') subplot(1,2,2),plot(tt,yy),axis([-7,7,-0.5,1.2]) xlabel('t'),ylabel('yy'),title('正确图形') Warning: Divide by zero.

-5 0 5

-0.4

-0.2

0

0.2

0.4

0.6

0.8

1

1.2

t

y

残缺图形

-5 0 5

-0.4

-0.2

0

0.2

0.4

0.6

0.8

1

1.2

t

yy

正 确图形

图 3.13.2-2 极限处理前后的图形对照

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

21

3.13.2 逻辑操作 【*例 3.13.2-1】逻辑操作示例。 A=1:9,L1=~(A>5) %判断 A中,哪些元素不大于 5 L2=(A>3)&(A<7) %判断 A中,哪些元素大于 3小于 7 A = 1 2 3 4 5 6 7 8 9 L1 = 1 1 1 1 1 0 0 0 0 L2 = 0 0 0 1 1 1 0 0 0 【*例 3.13.2-2】逻辑操作应用之一:逐段解析函数的计算和表现。本例演示削顶整流正弦半波的计算和图形绘制。 t=linspace(0,3*pi,500);y=sin(t);%产生正弦波 %处理方法一:从自变量着手进行逐段处理。 z1=((t<pi)|(t>2*pi)).*y; %获得整流半波 <3> w=(t>pi/3&t<2*pi/3)+(t>7*pi/3&t<8*pi/3);%关系逻辑运算和数值运算 <4> w_n=~w; % <5> z2=w*sin(pi/3)+w_n.*z1; %获得削顶整流半波 <6> subplot(1,3,1),plot(t,y,':r'),ylabel('y') subplot(1,3,2),plot(t,z1,':r'),axis([0 10 -1 1]) subplot(1,3,3),plot(t,z2,'-b'),axis([0 10 -1 1])

0 5 10-1

-0.8

-0.6

-0.4

-0.2

0

0.2

0.4

0.6

0.8

1

y

0 5 10-1

-0.8

-0.6

-0.4

-0.2

0

0.2

0.4

0.6

0.8

1

0 5 10-1

-0.8

-0.6

-0.4

-0.2

0

0.2

0.4

0.6

0.8

1

图 3.13.2-1 逐段解析函数的产生

%处理方法二:从函数量着手进行逐段处理。 z=(y>=0).*y; %正弦整流半波 <11> a=sin(pi/3); z=(y>=a)*a+(y<a).*z; %削顶的正弦整流半波 <13> plot(t,y,':r');hold on;plot(t,z,'-b') xlabel('t'),ylabel('z=f(t)'),title('逐段解析函数') legend('y=sin(t)','z=f(t)'),hold off

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

22

图 3.13.2-2 逐段解析函数的生成和表现

3.13.3 关系、逻辑函数

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

1

4 字符串数组、元胞数组和构架数组

4.1 字符串数组

4.1.1 字符串入门 【*例 4.1.1-1】先请读者实际操作本例,以体会数值量与字符串的区别。 clear %清除所有内存变量 a=12345.6789 %给变量 a赋数值标量 class(a) %对变量 a的类别进行判断 a_s=size(a) %数值数组 a的“大小” a = 1.2346e+004 ans = double a_s = 1 1 b='S' %给变量 b赋字符标量(即单个字符) class(b) %对变量 b的类别进行判断 b_s=size(b) %符号数组 b的“大小” b = S ans = char b_s = 1 1 whos %观察变量 a,b在内存中所占字节 Name Size Bytes Class a 1x1 8 double array a_s 1x2 16 double array ans 1x4 8 char array b 1x1 2 char array b_s 1x2 16 double array Grand total is 10 elements using 50 bytes

4.1.2 串数组的属性和标识 【*例 4.1.2-1】本例演示:串的基本属性、标识和简单操作。 (1)创建串数组 a='This is an example.' a = This is an example. (2)串数组 a的大小 size(a) ans =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

2

1 19 (3)串数组的元素标识 a14=a(1:4) %提出一个子字符串 ra=a(end:-1:1) %字符串的倒排 a14 = This ra = .elpmaxe na si sihT (4)串数组的 ASCII码 ascii_a=double(a) %产生 ASCII码 ascii_a = Columns 1 through 12 84 104 105 115 32 105 115 32 97 110 32 101 Columns 13 through 19 120 97 109 112 108 101 46 char(ascii_a) %把 ASCII码变回字符串 ans = This is an example. (5)对字符串 ASCII码数组的操作 %使字符串中字母全部大写 w=find(a>='a'&a<='z'); %找出串数组 a中,小写字母的元素位置。 ascii_a(w)=ascii_a(w)-32; %大小写字母 ASCII值差 32.用数值加法改变部分码值。 char(ascii_a) %把新的 ASCII码翻成字符 ans = THIS IS AN EXAMPLE. (6)中文字符串数组 A='这是一个算例。'; %创建中文字符串 A_s=size(A) %串数组的大小 A56=A([5 6]) %取串的子数组 ASCII_A=double(A) %获取 ASCII码 A_s = 1 7 A56 = 算例 ASCII_A = Columns 1 through 6 54754 51911 53947 47350 52195 49405 Column 7 41379 char(ASCII_A) %把 ASCII码翻译成字符 ans = 这是一个算例。 (7)创建带单引号的字符串 b='Example ''4.1.2-1''' b = Example '4.1.2-1'

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

3

(8)由小串构成长串 ab=[a(1:7),' ',b,' .'] %这里第 2个输入为空格串 ab = This is Example '4.1.2-1' .

4.1.3 复杂串数组的创建

4.1.3.1 多行串数组的直接创建 【*例 4.1.3.1-1】多行串数组的直接输入示例。 clear S=['This string array ' 'has multiple rows.'] S = This string array has multiple rows. size(S) ans =

2 18

4.1.3.2 利用串操作函数创建多行串数组 【*例 4.1.3.2-1】演示:用专门函数 char , str2mat , strvcat创建多行串数组示例。 S1=char('This string array','has two rows.') S1 = This string array has two rows. S2=str2mat('这','字符','串数组','由 4行组成') S2 = 这 字符 串数组 由 4行组成 S3=strvcat('这','字符','串数组',' ','由 4行组成')%“空串”会产生一个空格行 S3 = 这 字符 串数组 由 4行组成 size(S3) ans = 5 5

4.1.3.3 转换函数产生数码字符串 【*例 4.1.3.3-1】最常用的数组/字符串转换函数 int2str , num2str , mat2str 示例。 (1)int2str把整数数组转换成串数组(非整数将被四舍五入园整后再转换) A=eye(2,4); %生成一个 )42( × 数值数组 A_str1=int2str(A) %转换成 )102( × 串数组。请读者自己用 size检验。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

4

A_str1 = 1 0 0 0 0 1 0 0 (2)num2str把非整数数组转换为串数组(常用于图形中,数据点的标识) rand('state',0) B=rand(2,4); %生成数值矩阵 B3=num2str(B,3) %保持 3位有效数字,转换为串 B3 = 0.95 0.607 0.891 0.456 0.231 0.486 0.762 0.0185 (3)mat2str把数值数组转换成输入形态的串数组(常与 eval指令配用) B_str=mat2str(B,4) %保持 4位有效数字,转换为“数组输入形式”串 B_str = [0.9501 0.6068 0.8913 0.4565;0.2311 0.486 0.7621 0.0185] Expression=['exp(-',B_str,')']; %相当于指令窗写一个表达式 exp(-B_str) eval(Expression) %把 exp(-B_str)送去执行 ans = 0.3867 0.5451 0.4101 0.6335 0.7937 0.6151 0.4667 0.9817 【*例 4.1.3.3-2】综合例题:在 MATLAB计算生成的图形上标出图名和最大值点坐标。 clear %清除内存中的所有变量 a=2; %设置衰减系数 w=3; %设置振荡频率 t=0:0.01:10; %取自变量采样数组 y=exp(-a*t).*sin(w*t); %计算函数值,产生函数数组 [y_max,i_max]=max(y); %找最大值元素位置 t_text=['t=',num2str(t(i_max))]; %生成最大值点的横坐标字符串 <7> y_text=['y=',num2str(y_max)]; %生成最大值点的纵坐标字符串 <8> max_text=char('maximum',t_text,y_text);%生成标志最大值点的字符串 <9> %生成标志图名用的字符串 tit=['y=exp(-',num2str(a),'t)*sin(',num2str(w),'t)']; %<11> plot(t,zeros(size(t)),'k') %画纵坐标为 0的基准线 hold on %保持绘制的线不被清除 plot(t,y,'b') %用兰色画 y(t)曲线 plot(t(i_max),y_max,'r.','MarkerSize',20) %用大红点标最大值点 text(t(i_max)+0.3,y_max+0.05,max_text) %在图上书写最大值点的数据值<16> title(tit),xlabel('t'),ylabel('y'),hold off%书写图名、横坐标名、纵坐标名

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

5

0 2 4 6 8 10-0.1

0

0.1

0.2

0.3

0.4

0.5

0.6

maximum t=0.33 y=0.4321

y=exp(-2t)*sin(3t)

t

y

图 4.1.3.3-1 字符串运用示意图

4.1.3.4 利用元胞数组创建复杂字符串 【*例 4.1.3.4-1】元胞数组在存放和操作字符串上的应用。 a='MATLAB 5 ';b='introduces new data types:'; %创建单行字符串 a,b c1='◆Multidimensional array';c2='◆User-definable data structure'; c3='◆Cell arrays';c4='◆Character array'; c=char(c1,c2,c3,c4); %创建多行字符串 c C={a;b;c}; %利用元胞数组存放长短不同的字符串 <5> disp([C{1:2}]) %显示前两个元胞中的字符内容 <6> disp(' ') %显示一行空白 disp(C{3}) %显示第 3个元胞中的字符内容 <8> MATLAB 5 introduces new data types: ◆Multidimensional array ◆User-definable data structure ◆Cell arrays ◆Character array

4.1.4 串转换函数 【*例 4.1.4-1】fprintf, sprintf, sscanf的用法示例。 rand('state',0);a=rand(2,2); %产生 )22( × 随机阵 s1=num2str(a) %把数值数组转换为串数组 s_s=sprintf('%.10e\n',a) %10数位科学记述串,每写一个元素就换行。 s1 = 0.95013 0.60684 0.23114 0.48598 s_s = 9.5012928515e-001 2.3113851357e-001 6.0684258354e-001 4.8598246871e-001 fprintf('%.5g\\',a) %以 5位数位最短形式显示。不能赋值用 0.95013\0.23114\0.60684\0.48598\ s_sscan=sscanf(s_s,'%f',[3,2])%浮点格式把串转换成成 )23( × 数值数组。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

6

s_sscan = 0.9501 0.4860 0.2311 0 0.6068 0

4.1.5 串操作函数

4.2 元胞数组

4.2.1 元胞数组的创建和显示

4.2.1.1 元胞标识寻访和内容编址寻访的不同

4.2.1.2 元胞数组的创建和显示 【*例 4.2.1.2-1】本例演示: )22( × 元胞数组的创建。 C_str=char('这是','元胞数组创建算例 1'); %产生字符串 R=reshape(1:9,3,3); %产生 )33( × 实数阵 R Cn=[1+2i]; %产生复数标量 S_sym=sym('sin(-3*t)*exp(-t)'); %产生符号函数量 (1)直接创建法之一:“外标识元胞元素赋值法” A(1,1)={C_str};A(1,2)={R};A(2,1)={Cn};A(2,2)={S_sym}; A %显示元胞数组 A = [2x10 char] [3x3 double] [1.0000+ 2.0000i] [1x1 sym ] (2)直接创建法之二:“编址元胞元素内涵的直接赋值法” B{1,1}=C_str;B{1,2}=R;B{2,1}=Cn;B{2,2}=S_sym; celldisp(B) %显示元胞数组内容 B{1,1} = 这是 元胞数组创建算例 1 B{2,1} = 1.0000 + 2.0000i B{1,2} = 1 4 7 2 5 8 3 6 9 B{2,2} = -sin(3*t)*exp(-t)

4.2.2 元胞数组的扩充、收缩和重组 【*例 4.2.2-1】元胞数组的扩充。 (1)利用 cell指令创建元胞数组

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

7

C=cell(2); %预设 )22( × 空元胞数组 C(:,1)={char('Another','text string');10:-1:1} %对第一列元胞赋值 C = [2x11 char ] [] [1x10 double] [] (2)元胞数组的“列”扩充和“行”扩充 AC=[A C] %空格(或逗号)利用来分隔列 A_C=[A;C] %分号利用来分隔“行” AC = [2x10 char] [3x3 double] [2x11 char ] [] [1.0000+ 2.0000i] [1x1 sym ] [1x10 double] [] A_C = [2x10 char ] [3x3 double] [1.0000+ 2.0000i] [1x1 sym ] [2x11 char ] [] [1x10 double] [] 【*例 4.2.2-2】cellplot能用图形形象化地表示元胞数组的内容。(A_C取自上例) cellplot(A_C,'legend')

1+2i

double

char

sparse

structure

other

图 4.2.2-1 元胞数组 A_C的形象化结构图

【*例 4.2.2-3】元胞数组的收缩和重组。 (1)元胞数组的收缩 A_C(3,:)=[] %删除第 3行,使 A_C成为 )23( × 的元胞数组 A_C = [2x10 char ] [3x3 double] [1.0000+ 2.0000i] [1x1 sym ] [1x10 double] [] (2)把 A_C重组成 )32( × 元胞数组 R_A_C R_A_C=reshape(A_C,2,3) R_A_C =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

8

[2x10 char] [1x10 double] [1x1 sym] [1.0000+ 2.0000i] [3x3 double] []

4.2.3 元胞数组内容的调取 【*例 4.2.3-1】元胞数组内容的调取示例。 (1)取一个元胞 f1=R_A_C(1,3) %使用园括号寻访得到的是元胞,而不仅是内容。 class(f1) f1 = [1x1 sym] ans = cell (2)取一个元胞的内容 f2=R_A_C{1,3} %用花括号寻访取得内容 class(f2) f2 = sin(-3*t)*exp(-t) ans = sym (3)取元胞内的子数组 f3=R_A_C{1,1}(:,[1 2 5 6]) %注意三种括号的不同用途 %取第 1行第 1列元胞内容中的第 1、2、5、6列。 f3 = 这是 元胞创建 (4)同时调取多个元胞内容 [f4,f5,f6]=deal(R_A_C{[1,3,4]}) %取三个元胞内容,赋值给三个变量 f4 = 这是 元胞数组创建算例 1 f5 = 10 9 8 7 6 5 4 3 2 1 f6 = 1 4 7 2 5 8 3 6 9

4.3 构架数组

4.3.1 构架数组的创建和显示

4.3.1.1 直接创建法及显示

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

9

【*例 4.3.1.1-1】本例通过温室数据(包括温室名、容积、温度、湿度等)演示:单构架的创建和显示。 (1)直接对域赋值法产生“单构架”,即 )11( × 构架数组。 green_house.name='一号房'; %构架的域由(构架名).(域名)标识。 <1> green_house.volume='2000立方米'; %<2> green_house.parameter.temperature=[31.2 30.4 31.6 28.7 29.7 31.1 30.9 29.6];%<3> green_house.parameter.humidity=[62.1 59.5 57.7 61.5 62.0 61.9 59.2 57.5]; %<4> (2)显示“单构架”结构和内容 green_house %显示单构架结构 <5> green_house = name: '一号房' volume: '2000立方米' parameter: [1x1 struct] green_house.parameter %显示 parameter域中内容 <6> ans = temperature: [2x4 double] humidity: [2x4 double] green_house.parameter.temperature %显示 temperature域中的内容 <7> ans = 31.2000 30.4000 31.6000 28.7000 29.7000 31.1000 30.9000 29.6000

【*例 4.3.1.1-2】本例演示构架数组的创建和显示,并利用构架数组保存一个温室群的数据。本例的运行以例 4.3.1.1-1为先导。 (1)直接对域赋值法“构架数组”。 green_house(2,3).name='六号房'; %产生 )32( × 构架数组 <1> (2)显示构架数组的结构和构架元素的内容 green_house %显示构架数组的结构:构架行列数;构架的域。 <2> green_house = 2x3 struct array with fields: name volume parameter green_house(2,3) %显示元素构架的结构:域;是否有子域 <3> ans = name: '六号房' volume: [] parameter: []

4.3.1.2 利用构造函数创建构架数组 【*例 4.3.1.2-1】利用构造函数 struct,建立温室群的数据库。 (1)struct预建空构架数组方法之一 a=cell(2,3); %创建 )32( × 空元胞数组

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

10

green_house_1=struct('name',a,'volume',a,'parameter',a(1,2)) % <2> green_house_1 = 2x3 struct array with fields: name volume parameter (2)struct预建空构架数组方法之二 green_house_2=struct('name',a,'volume',[],'parameter',[]) % <3> green_house_2 = 2x3 struct array with fields: name volume

parameter (3)struct预建空构架数组方法之三 green_hopuse_3(2,3)=struct('name',[],'volume',[],'parameter',[])%<4> green_hopuse_3 = 2x3 struct array with fields: name volume parameter (4)struct创建构架数组方法之四 a1={'六号房'};a2={'3200立方米'}; green_house_4(2,3)=struct('name',a1,'volume',a2,'parameter',[]);%<6> T6=[31.2,30.4,31.6,28.7;29.7,31.1,30.9,29.6]; % <7> green_house_4(2,3).parameter.temperature=T6; % <8> green_house_4 ans = 2x3 struct array with fields: name volume parameter

4.3.2 构架数组域中内容的调取和设置 【*例 4.3.2-1】本例目的:一,演示函数 fieldnames , getfield , setfield的使用方法;二,让读者感受到构架数组对应用工具包的影响;三,演示 struct函数把“对象”转换为构架的应用。本例为获得一个演练的构架,借助 Toolbox control 工具包中的 tf函数,先产生一个用传递函

数描写的 LTI线性时不变 2输入 2输出系统

++++

++++

sssss

ssss1

12214

12

233

23

22。

(1)产生 2输入 2输出系统的传递函数阵“对象” Stf=tf({3,2;[4 1],1},{[1 3 2],[1 1 1];[1 2 2 1],[1 0]}) Transfer function from input 1 to output... 3 #1: ------------- s^2 + 3 s + 2

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

11

4 s + 1 #2: --------------------- s^3 + 2 s^2 + 2 s + 1 Transfer function from input 2 to output... 2 #1: ----------- s^2 + s + 1 1 #2: - s (2)为本例演示,把上述的 LTI对象 Stf转换为构架 SSTF=struct(Stf) %把对象转换成构架,并显示构架的组成 SSTF = num: {2x2 cell} den: {2x2 cell} Variable: 's' lti: [1x1 lti] (3)获得构架数组 SSTF的域名 FN=fieldnames(SSTF) %获得域名元胞数组 FN class(FN) %检查 FN的类别 FN = 'num' 'den' 'Variable' 'lti' ans = cell (4)获取 SSTF.den(2,1)域的内容 FC=getfield(SSTF,'den',{2,1}) %相当于 FC=SSFT.den(2,1) FC{1} %与 celldisp(FC)的作用大致相当 poly2str(FC{1},'s'), %为了把多项式显示成习惯的形式 FC = [1x4 double] ans = 1 2 2 1 ans = s^3 + 2 s^2 + 2 s + 1 (5)重新设置 SSTF.num(2,1)域的内容 SSTF.num{2,1} %显示原始情况 SSTF=setfield(SSTF,'num',{2,1},{[1 3 1]}); %注意“花括号”的使用 SSTF.num{2,1} %显示被重新设置后的情况 ans = 0 0 4 1 ans = 1 3 1

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

12

4.3.3 构架数组操作深入

4.3.3.1 构架数组的扩充和收缩 【*例 4.3.3.1-1】本例演示构架数组 SSTF的扩充和收缩。(本例以例 4.3.2-1的运行为基础。) (1)原构架是一个“单构架” size(SSTF) ans = 1 1 (2)演示构架的扩充 SSTF(2,2)=struct(tf(1,[1 1])) %把 1/(s+1)放在第 2行第 2列构架中 size(SSTF) SSTF = 2x2 struct array with fields: num den Variable lti ans = 2 2 (3)演示构架数组的收缩:删除构架数组的第 1行 SSTF(1,:)=[] %收缩成为 )21( × 的构架 S22n=SSTF(1,2).num,S22d=SSTF(1,2).den %取出第 2构架 num域和 den域的内容 printsys(S22n{1},S22d{1}) %显示成习惯的表达形式 SSTF = 1x2 struct array with fields: num den Variable lti S22n = [1x2 double] S22d = [1x2 double] num/den = 1 ----- s + 1

4.3.3.2 增添域和删除域 【*例 4.3.3.2-1】对构架数组进行域的增添和删减操作。 (1)创建构架数组 clear,for k=1:10;department(k).number=['No.',int2str(k)];end department department = 1x10 struct array with fields: number

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

13

(2)增添域:在数组中任何一个构架上进行的域增添操作,其影响遍及整个构架数组。 department(1).teacher=40;department(1).student=300; department(1).PC_computer=40; department department = 1x10 struct array with fields: number teacher student PC_computer (3)增添子域的操作只影响被操作的那个具体构架,而不是影响整个构架数组。 department(2).teacher.male=35;department(2).teacher.female=13; D2T=department(2).teacher %第 2构架 teacher域包含两个子域 D1T=department(1).teacher %第 1构架 teacher域仅是一个数 D2T = male: 35 female: 13 D1T = 40 (4)删除子域的操作也只影响被操作的那个具体构架。 department(2).teacher=rmfield(department(2).teacher,'male'); department(2).teacher ans = female: 13 (5)删除域的操作是对整个构架数组实施的。 department=rmfield(department,'student') %删除一个域 department = 1x10 struct array with fields: number teacher PC_computer department=rmfield(department,{'teacher';'PC_computer'})%删除 2个域 department = 1x10 struct array with fields: number

4.3.3.3 数值运算操作和函数对构架数组的应用 【*例 4.3.3.3-1】数值运算操作和函数在构架域上的作用。 n_ex=5; %构架数组的长度 for k=1:n_ex, ex(k).f=(k-1)*n_ex+[1:5];end %创建 )51( × 构架数组 ex %显示构架数组的结构 ex = 1x5 struct array with fields: f %显示构架数组的域中内容 disp([blanks(10) '构架域中内容']) for k=1:n_ex,disp(ex(k).f),end 构架域中内容

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

14

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class(ex(1).f) %检查域中内容的类型 ans = double %对各构架域中数值数组相应位置的数据相加求和 sum_f=zeros(1,5) for k=1:n_ex,sum_f=sum_f+ex(k).f;end,sum_f sum_f = 55 60 65 70 75 %对构架数组域中各元素分别求平方根 disp([blanks(20) 'ex.f的平方根值']) for k=1:n_ex, disp(sqrt(ex(k).f)),end ex.f的平方根值 1.0000 1.4142 1.7321 2.0000 2.2361 2.4495 2.6458 2.8284 3.0000 3.1623 3.3166 3.4641 3.6056 3.7417 3.8730 4.0000 4.1231 4.2426 4.3589 4.4721

4.5826 4.6904 4.7958 4.8990 5.0000

4.3.4 构架数组和元胞数组之间的转换 【*例 4.3.4-1】指令 struct2cell和 cell2struct的使用。 (1)创建“带 2个域的 )51( × 构架数组” for k=1:5,ex(k).s=['No.' int2str(k)];ex(k).f=(k-1)*5+[1:5];end (2)显示构架数组的内容 fprintf('%s\n','ex.s域的内容 ');fprintf('%s\',blanks(4)) for k=1:5;fprintf('%s\\',[ex(k).s blanks(1)]);end fprintf('%s\n',blanks(1)),fprintf('%s\n','ex.f域的内容 ') for k=1:5;disp(ex(k).f);end %显示 ex.f域内容 ex.s域的内容 No.1 \No.2 \No.3 \No.4 \No.5 \ ex.f域的内容 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 (3)把 ex构架数组转换为元胞数组 C_ex=struct2cell(ex);%“带 2个域的 )51( × 构架数组”转换为 )512( ×× 元胞数组 size(C_ex) fprintf('%s\',[C_ex{1,1,1},blanks(3)]) %显示 C_ex第 1页第 1行第 1列内容 fprintf('%5g\',C_ex{2,1,1}) %显示 C_ex第 2页第 1行第 1列内容 ans = 2 1 5 No.1 1 2 3 4 5

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

15

(4)把元胞数组转换为构架数组之一 FS={'S_char';'F_num'}; %用元胞数组预建域名字符串 EX1=cell2struct(C_ex,FS,1) %元胞数组向构架数组转换 EX1 = 1x5 struct array with fields: S_char F_numric EX1(1) %观察新构架 EX1第一构架的情况 ans = S_char: 'No.1'

F_numric: [1 2 3 4 5] (5)把元胞数组转换为构架数组之二 EX2=cell2struct(C_ex,'xx',2) EX2 = 2x5 struct array with fields: xx (6)把元胞数组转换为构架数组之三 YY=strvcat('y1','y2','y3','y4','y5');EX3=cell2struct(C_ex,YY,3) EX3 = 2x1 struct array with fields: y1 y2 y3 y4 y5 EX3(1) %观察第一构架情况 ans = y1: 'No.1' y2: 'No.2' y3: 'No.3' y4: 'No.4' y5: 'No.5' EX3(2) %观察第二构架情况 ans = y1: [1 2 3 4 5] y2: [6 7 8 9 10] y3: [11 12 13 14 15] y4: [16 17 18 19 20] y5: [21 22 23 24 25] 【*例 4.3.4-2】带子域的构架数组转换为元胞数组。本例中的 ex构架数组由例 4.3.4-1生成,然后再运行以下程序。 ex(1,1).s %原构架 ex(1,1).s中的内容 ans = No.1 %增设子域,并把 ex构架数组扩充为 )53( × 。 ex(1,1).s.sub='SUB 1'; %原 ex(1,1).s中的字符串将因本指令而消失。 ex(3,1).s.sub='SUB 3'; ex(3,1).s.num=1/3; ex(1,1).s %经新赋值后,ex(1,1).s中的内容 ans =

sub: 'SUB 1' ex(3,1).s %经新赋值后,ex(3,1).s中的内容

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

16

ans = sub: 'SUB 3' num: 0.3333 C_ex_sub=struct2cell(ex) %把构架转换为元胞数组 C_ex_sub(:,:,1) = [1x1 struct] [] [1x1 struct] [1x5 double] [] [] C_ex_sub(:,:,2) = 'No.2' [] [] [1x5 double] [] [] C_ex_sub(:,:,3) = 'No.3' [] [] [1x5 double] [] [] C_ex_sub(:,:,4) = 'No.4' [] [] [1x5 double] [] [] C_ex_sub(:,:,5) = 'No.5' [] [] [1x5 double] [] [] size(C_ex_sub) %观察新元胞数组的大小 ans = 2 3 5 C_ex_sub{1,1,1} %观察第一元胞中的内容 ans =

sub: 'SUB 1' C_ex_sub{1,3,1} %观察(1,3,1)元胞中的内容 ans = sub: 'SUB 3'

num: 0.3333

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

1

5 数值计算

5.1 引言 本章将花较大的篇幅讨论若干常见数值计算问题:线性分析、一元和多元函数分析、

微积分、数据分析、以及常微分方程求解等。但与一般数值计算教科书不同,本章的讨论

重点是:如何利用现有的世界顶级数值计算资源 MATLAB。至于数学描述,本章将遵循“最低限度自封闭”的原则处理,以最简明的方式阐述理论数学、数值数学和 MATLAB计算指令之间的内在联系及区别。 对于那些熟悉其他高级语言(如 FORTRAN,Pascal,C++)的读者来说,通过本章,MATLAB卓越的数组处理能力、浩瀚而灵活的 M函数指令、丰富而友善的图形显示指令将使他们体验到解题视野的豁然开朗,感受到摆脱烦琐编程后的眉眼舒展。 对于那些经过大学基本数学教程的读者来说,通过本章,MATLAB精良完善的计算指令,自然易读的程序将使他们感悟“教程”数学的基础地位和局限性,看到从“理想化”

简单算例通向科学研究和工程设计实际问题的一条途径。 对于那些熟悉MATLAB基本指令的读者来说,通过本章,围绕基本数值问题展开的内容将使他们体会到各别指令的运用场合和内在关系,获得综合运用不同指令解决具体问题

的思路和借鉴。 由于 MATLAB的基本运算单元是数组,所以本章内容将从矩阵分析、线性代数的数值计算开始。然后再介绍函数零点、极值的求取,数值微积分,数理统计和分析,拟合和插

值,Fourier 分析,和一般常微分方程初值问题。本章的最后讨论稀疏矩阵的处理,因为这只有在大型问题中,才须特别处理。 从总体上讲,本章各节之间没有依从关系,即读者没有必要从头到尾系统阅读本章内

容。读者完全可以根据需要阅读有关节次。除特别说明外,每节中的例题指令是独立完整

的,因此读者可以很容易地在自己机器上实践。

5.2 LU分解和恰定方程组的解

5.2.1 LU分解、行列式和逆 (1)LU分解 (2)行列式和逆

5.2.2 恰定方程组的解 【*例 5.2.2-1】“求逆”法和“左除”法解恰定方程的性能对比 (1)为对比这两种方法的性能,先用以下指令构造一个条件数很大的高阶恰定方程。 rand('state',12); %选定随机种子,目的是可重复产生随机阵 A。 A=rand(100,100)+1.e8; %rand(100,100)生成(100×100)均匀分布随机矩阵。 %每个随机阵元素加108

的目的是使 A阵条件数升高。 x=ones(100,1); %令解向量 x 为全 1的 100元列向量。 b=A*x; %为使 Ax=b 方程一致,用 A和 x 生成 b 向量。 cond(A) %求 A阵的条件数。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

2

ans = 1.4426e+012 (2)“求逆”法解恰定方程的误差、残差、运算次数和所用时间 flops(0);tic %浮点运算计数器置 0 ;启动计时器 Stopwatch Timer xi=inv(A)*b; % xi 是用“求逆”法解恰定方程所得的解。 ti=toc %关闭计时器,并显示解方程所用的时间。 ci=flops %“求逆”法解方程所用的运算次数 eri=norm(x-xi) %解向量 xi 与真解向量 x 的范-2误差。 rei=norm(A*xi-b)/norm(b) %方程的范-2相对残差 ti = 0.9300 ci = 2070322 eri = 3.0708e-004 rei = 6.6280e-007 (3)“左除”法解恰定方程的误差、残差、运算次数和所用时间 flops(0);tic;xd=A\b; %是用“左除”法解恰定方程所得的解。 td=toc,cd=flops,erd=norm(x-xd),red=norm(A*xd-b)/norm(b) td = 0.2200 cd = 741872 erd = 3.2243e-004 red = 2.0095e-016

5.2.3 范数、条件数和方程解的精度 【*例 5.2.3-1】Hilbert矩阵是著名的病态矩阵。MATLAB中有专门的 Hilbert矩阵及其准确逆矩阵的生成函数。本例将对方程 bHx = 近似解和准确解进行比较。所谓 n阶 Hilbert矩阵

的形式是: { }

≠=

−+

+==× ji

ji

ji

jihhH ijnnijn

11

1

, 。

N=[6 8 10 12 14]; %本例计算的矩阵阶数 for k=1:length(N) n=N(k); %矩阵的阶 H=hilb(n); %产生 n阶 Hilbert矩阵 Hi=invhilb(n); %产生完全准确的 n阶逆 Hilbert矩阵 b=ones(n,1); %生成 n阶全 1向量 x_approx=H\b; %利用左除 H求近似解 x_exact=Hi*b; %利用准确逆 Hilbert矩阵求准确解 ndb=norm(H*x_approx-b);nb=norm(b); ndx=norm(x_approx - x_exact);nx=norm(x_approx); er_actual(k)=ndx/nx; %实际相对误差 K=cond(H); %计算 Hilbert矩阵的条件数

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

3

er_approx(k)=K*eps; %最大可能的近似相对误差 er_max(k)=K*ndb/nb; %最大可能的相对误差 end disp('Hilbert矩阵阶数'),disp(N) format short e disp('实际误差 er_actual'),disp(er_actual),disp('') disp('近似的最大可能误差 er_approx'),disp(er_approx),disp('') disp('最大可能误差 er_max'),disp(er_max),disp('') Hilbert矩阵阶数 6 8 10 12 14 实际误差 er_actual 5.0339e-011 8.5981e-008 2.2819e-004 1.3381e-001 3.9641e+000 近似的最大可能误差 er_approx 3.3198e-009 3.3879e-006 3.5583e-003 3.9259e+000 3.4573e+002 最大可能误差 er_max 6.0095e-007 2.4531e-002 1.4094e+003 2.9206e+007 2.4178e+010

5.3 矩阵特征值和矩阵函数

5.3.1 特征值和特征向量的求取 【例 5.3.1-1】简单实阵的特征值问题。 A=[1,-3;2,2/3];[V,D]=eig(A) V = -0.7728 + 0.0527i -0.7728 - 0.0527i 0 + 0.6325i 0 - 0.6325i D = 0.8333 + 2.4438i 0 0 0.8333 - 2.4438i 【*例 5.3.1-2】本例演示:如矩阵中有元素与截断误差相当时的特性值问题。 A=[3 -2 -0.9 2*eps -2 4 -1 -eps -eps/4 eps/2 -1 0 -0.5 -0.5 0.1 1 ]; [V1,D1]=eig(A);ER1=A*V1-V1*D1 [V2,D2]=eig(A,'nobalance');ER2=A*V2-V2*D2 ER1 = 0 -0.0000 -0.0000 0.0000 0.0000 -0.0000 0.0000 0.0000 0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 0.0000 1.1227 ER2 = 1.0e-015 * 0.4441 -0.2220 0.1471 -0.2220 0 0.0555 -0.3629 0.2776 -0.0172 -0.0015 0.0066 0 0 -0.2220 -0.1110 0.1388

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

4

【*例 5.3.1-3】指令 eig与 eigs的比较。 rand('state',1),A=rand(100,100)-0.5; t0=clock;[V,D]=eig(A);T_full=etime(clock,t0)%指令 eig的运作时间。 options.tol=1e-8; %为 eigs设定计算精度。 options.disp=0; %使中间迭代结果不显示。 t0=clock;[v,d]=eigs(A,1,'lr',options);%计算最大实部特征值和特征向量。 T_part=etime(clock,t0) %指令 eigs的运作时间。 [Dmr,k]=max(real(diag(D))); %在 eig求得的全部特征值中找最大实部的那个。 d,D(1,1) T_full = 2.8000 T_part = 19.5500 d = 3.0140 - 0.2555i ans = 3.0140 + 0.2555i vk1=V(:,k+1); %与 d相同的特征向量应是 V的第 k+1列。 vk1=vk1/norm(vk1);v=v/norm(v); %向量长度归一。 V_err=acos(norm(vk1'*v))*180/pi %求复数向量之间的夹角(度)。 D_err=abs(D(k+1,k+1)-d)/abs(d) %求两个特征值间的相对误差。 V_err = 8.5377e-007 D_err =

1. 7098e-010

5.3.2 特征值问题的条件数 【例 5.3.2-1】矩阵的代数方程条件数和特征值条件数。 B=eye(4,4);B(3,4)=1;B format short e,c_equ=cond(B),c_eig=condeig(B) B = 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 1 c_equ = 2.6180e+000 Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 1.500000e-018. > In E:\MAT53\toolbox\matlab\matfun\condeig.m at line 30 c_eig = 1.0000e+000 1.0000e+000 3.3333e+017 3.3333e+017 【*例 5.3.2-2】对亏损矩阵进行 Jordan分解。 A=gallery(5) %MATLAB设置的特殊矩阵,它具有五重特征值。 [VJ,DJ]=jordan(A); %求出准确的特征值,使 A*VJ=VJ*D成立。 [V,D,c_eig]=condeig(A);c_equ=cond(A); DJ,D,c_eig,c_equ A =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

5

-9 11 -21 63 -252 70 -69 141 -421 1684 -575 575 -1149 3451 -13801 3891 -3891 7782 -23345 93365 1024 -1024 2048 -6144 24572 DJ = 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 D = Columns 1 through 4 -0.0328 + 0.0243i 0 0 0 0 -0.0328 - 0.0243i 0 0 0 0 0.0130 + 0.0379i 0 0 0 0 0.0130 - 0.0379i 0 0 0 0 Column 5 0 0 0 0 0.0396 c_eig = 1.0e+010 * 2.1016 2.1016 2.0251 2.0251 1.9796 c_equ = 5.2133e+017

5.3.3 复数特征值对角阵与实数块特征值对角阵的转化 【*例5.3.3-1】把例5.3.1-1中的复数特征值对角阵D转换成实数块对角阵,使VR*DR/VR=A。 [VR,DR]=cdf2rdf(V,D) VR = -0.7728 0.0527 0 0.6325 DR = 0.8333 2.4438 -2.4438 0.8333

5.3.4 矩阵的谱分解和矩阵函数 【*例 5.3.4-1】数组乘方与矩阵乘方的比较。 clear,A=[1 2 3;4 5 6;7 8 9]; A_Ap=A.^0.3 %数组乘方 A_Mp=A^0.3 %矩阵乘方 A_Ap = 1.0000 1.2311 1.3904 1.5157 1.6207 1.7118 1.7928 1.8661 1.9332

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

6

A_Mp = 0.6962 + 0.6032i 0.4358 + 0.1636i 0.1755 - 0.2759i 0.6325 + 0.0666i 0.7309 + 0.0181i 0.8292 - 0.0305i 0.5688 - 0.4700i 1.0259 - 0.1275i 1.4830 + 0.2150i 【*例 5.3.4- 2】标量的数组乘方和矩阵乘方的比较。(A取自例 5.3.4-1) pA_A=(0.3).^A %标量的数组乘方 pA_M=(0.3)^A %标量的矩阵乘方 pA_A = 0.3000 0.0900 0.0270 0.0081 0.0024 0.0007 0.0002 0.0001 0.0000 pA_M = 2.9342 0.4175 -1.0993 -0.0278 0.7495 -0.4731 -1.9898 -0.9184 1.1531 【*例 5.3.4-3】sin的数组运算和矩阵运算比较。(A取自例 5.3.4-1) A_sinA=sin(A) %数组运算 A_sinM=funm(A,'sin') %矩阵运算 A_sinA = 0.8415 0.9093 0.1411 -0.7568 -0.9589 -0.2794 0.6570 0.9894 0.4121 A_sinM = -0.6928 -0.2306 0.2316 -0.1724 -0.1434 -0.1143

0.3479 -0.0561 -0.4602

5.4 奇异值分解

5.4.1 奇异值分解和矩阵结构

5.4.1.1 奇异值分解定义

5.4.1.2 矩阵结构的奇异值分解描述 (1)秩 rArank =)( (2)零空间(Null space)和值空间(Range space) (3)范数(Norm) (4)矩阵条件数 (5)子空间夹角 (6)广义逆(Moore-Penrose pseudoinverse)

5.4.2 线性二乘问题的解

5.4.2.1 矩阵除运算的广义化

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

7

5.4.2.2 线性模型的最小二乘解 【*例 5.4.2.2-1】对于超定方程 Axy = ,进行三种解法比较。其中 A取 MATLAB库中的特殊函数生成。 (1)生成矩阵 A及 y,并用三种方法求解 A=gallery(5);A(:,1)=[];y=[1.7 7.5 6.3 0.83 -0.082]'; x=inv(A'*A)*A'*y,xx=pinv(A)*y,xxx=A\y Warning: Matrix is close to singular or badly scaled. Results may be inaccurate. RCOND = 7.087751e-018. x = 3.4811e+000 5.1595e+000 9.5342e-001 -4.6562e-002 xx = 3.4759e+000 5.1948e+000 7.1207e-001 -1.1007e-001 Warning: Rank deficient, rank = 3 tol = 1.0829e-010. xxx = 3.4605e+000 5.2987e+000 0 -2.9742e-001 (2)计算三个解的范数 nx=norm(x),nxx=norm(xx),nxxx=norm(xxx) nx = 6.2968e+000 nxx = 6.2918e+000 nxxx = 6.3356e+000 (3)比较三种解法的方程误差 e=norm(y-A*x),ee=norm(y-A*xx),eee=norm(y-A*xxx) e = 1.1020e+000 ee = 4.7424e-002 eee = 4.7424e-002

5.5 函数的数值导数和切平面

5.5.1 法线 【*例 5.5.1-1】曲面法线演示。 y=-1:0.1:1;x=2*cos(asin(y)); %旋转曲面的“母线” [X,Y,Z]=cylinder(x,20); %形成旋转曲面 surfnorm(X(:,11:21),Y(:,11:21),Z(:,11:21)); %在曲面上画法线

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

8

view([120,18]) %控制观察角

-5

0

5

-3 -2 -1 0 1

-0.2

0

0.2

0.4

0.6

0.8

1

1.2

图 5.5.1-1 旋转半椭球面和法线

5.5.2 偏导数和梯度

5.5.2.1 理论定义

5.5.2.2 数值计算指令 【*例 5.5.2.2-1】用一个简单矩阵表现 diff和 gradient指令计算方式。 F=[1,2,3;4,5,6;7,8,9] Dx=diff(F) %相邻行差分 Dx_2=diff(F,1,2) %相邻列差分。第三输入宗量 2表示“列”差分。 [FX,FY]=gradient(F) %数据点步长默认为 1 [FX_2,FY_2]=gradient(F,0.5) %数据点步长为 0.5 F = 1 2 3 4 5 6 7 8 9 Dx = 3 3 3 3 3 3 Dx_2 = 1 1 1 1 1 1 FX = 1 1 1 1 1 1 1 1 1 FY = 3 3 3 3 3 3 3 3 3 FX_2 = 2 2 2 2 2 2

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

9

2 2 2 FY_2 = 6 6 6 6 6 6 6 6 6 【*例 5.5.2.2-2】研究偶极子(Dipole)的电势(Electric potential)和电场强度(Electric field density)。设在 ),( ba 处有电荷 q+ ,在 ),( ba −− 处有电荷 q− 。那么在电荷所在平面上任

何 一 点 的 电 势 和 场 强 分 别 为 )11(4

),(0 −+

−=rr

qyxVπε

, VE −∇=r

。 其 中

2222 )()(,)()( byaxrbyaxr +++=−+−= −+ 。 9

0

1094

1⋅=

πε。 又 设 电 荷

6102 −⋅=q , 5.1=a , 5.1−=b 。 clear;clf;q=2e-6;k=9e9;a=1.5;b=-1.5;x=-6:0.6:6;y=x; [X,Y]=meshgrid(x,y); %设置坐标网点 rp=sqrt((X-a).^2+(Y-b).^2);rm=sqrt((X+a).^2+(Y+b).^2); V=q*k*(1./rp-1./rm); %计算电势 [Ex,Ey]=gradient(-V); %计算场强 AE=sqrt(Ex.^2+Ey.^2);Ex=Ex./AE;Ey=Ey./AE;%场强归一化,使箭头等长 cv=linspace(min(min(V)),max(max(V)),49);%产生 49个电位值 contourf(X,Y,V,cv,'k-') %用黑实线画填色等位线图 %axis('square') %在 Notebook中,此指令不用 title('\fontname{隶书}\fontsize{22}偶极子的场'),hold on quiver(X,Y,Ex,Ey,0.7) %第五输入宗量 0.7使场强箭头长短适中。 plot(a,b,'wo',a,b,'w+') %用白线画正电荷位置 plot(-a,-b,'wo',-a,-b,'w-') %用白线画负电荷位置 xlabel('x');ylabel('y'),hold off

-6 -4 -2 0 2 4 6-6

-4

-2

0

2

4

6偶极子的场

x

y

图 5.5.2.2-1 电偶极子的场和等位线

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

10

5.6 函数的零点

5.6.1 多项式的根

5.6.2 一元函数的零点

5.6.2.1 利用MATLAB作图指令获取初步近似解

5.6.2.2 任意一元函数零点的精确解

【*例 5.6.2.2-1】通过求 tbettf at −= −)(sin)( 2 的零点,综合叙述相关指令的用法。

(1)构造一个内联函数对象 被解函数 tbettf at −= −)(sin)( 2 以 t为自变量,a和b为参数。假如在 fzero中直接采

用字符串表示被解函数,容易出错。因此先构造内联函数如下: y=inline('sin(t)^2*exp(-a*t)-b*abs(t)','t','a','b'); %<1> (2)作图法观察函数零点分布 a=0.1;b=0.5;t=-10:0.01:10; %对自变量采样,采样步长不宜太大。 y_char=vectorize(y); %为避免循环,把 y改写成适合数组运算形式。 <4> Y=feval(y_char,t,a,b); %在采样点上计算函数值。 clf,plot(t,Y,'r');hold on,plot(t,zeros(size(t)),'k'); %画坐标横轴 xlabel('t');ylabel('y(t)'),hold off

-10 -5 0 5 10-5

-4

-3

-2

-1

0

1

t

y(t)

图 5.6.2.2-1 函数零点分布观察图

(3)利用 zoom和 ginput指令获得零点的初始近似值(在 MATLAB指令窗中进行) zoom on %在 MATLAB指令窗中运行,获局部放大图 [tt,yy]=ginput(5);zoom off %在 MATLAB指令窗中运行,用鼠标获 5个零点猜测值。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

11

图 5.6.2.2-2 局部放大和利用鼠标取值图

tt %显示所得零点初始猜测值(该指令可在 Notebook中运行)。 tt = -2.0032 -0.5415 -0.0072

0.5876 1.6561

(4)求靠近 tt(4) 的精确零点 [t4,y4,exitflag]=fzero(y,tt(4),[],a,b) %<11> Zero found in the interval: [0.57094, 0.60418]. t4 =

0。5993 y4 = 0 exitflag = 1 (5)求在 tt(3)附近的精确零点 从理论分析可知, 0=t 是函数的一个零点。但即便是以十分靠近该零点的

0072.0)3( −=tt 为搜索的初始值,也找不到 0=t ,而却找到了另一个零点。原因是曲线没

有穿越横轴。请看下面指令的运行结果。 [t3,y3,exitflag]=fzero(y,tt(3),[],a,b) Zero found in the interval: [0.58266, -0.59706]. t3 = -0.5198 y3 = 0 exitflag = 1 (6)观察 fzero所采用的 options缺省设置,并更改控制计算精度的相对误差设置。 op=optimset('fzero') %提取 fzero所采用的 options缺省设置 op = ActiveConstrTol: [] ...... Display: 'final' ...... TolX: 2.2204e-016 TypicalX: []

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

12

op=optimset('tolx',0.01); %把终止计算的相对误差阈值设置得较大 op.TolX %观察新设置值。注意 TolX字母的大小写。 ans =

0.0100 (7)利用新设置的选项参数重新求 tt(4)附近的零点,以便比较。 [t4n,y4n,exitflag]=fzero(y,tt(4),op,a,b) %采用新的 op设置参数。 Zero found in the interval: [0.57094, 0.60418]. t4n =

0。6042 y4n =

0。0017 exitflag = 1 〖说明〗 l 本例是采用内联函数形式求取函数零点的。 l 若采用如下 M函数文件(该文件必须放在搜索路径上)

[y_M.m] function y=y_M(t,a,b) y=sin(t).^2.*exp(-a*t)-b*abs(t); 则相应的求零点指令是[t4m,y4m,exitflag]=fzero('y_M',tt(4),[],a,b)

l 若直接用字符串表达函数,则应把被解函数自变量 t改成 x,参数 a、b改成 P1、P2。相应的具体指令如下

P1=0.1;P2=0.5; y_C='sin(x).^2.*exp(-P1*x)-P2*abs(x)'; [t4c,y4c,exitflag]=fzero(y_C,tt(4),[],P1,P2)

5.6.3 多元函数的零点

【例 5.6.3-1】求解二元函数方程组

=+==−=

0)cos(),(0)sin(),(

2

1

yxyxfyxyxf

的零点。

(0)从三维坐标初步观察两函数图形相交情况 x=-2:0.05:2;y=x;[X,Y]=meshgrid(x,y); %产生 x-y平面上网点坐标 F1=sin(X-Y);F2=cos(X+Y); F0=zeros(size(X)); surf(X,Y,F1), xlabel('x'),ylabel('y'), view([-31,62]),hold on, surf(X,Y,F2),surf(X,Y,F0), shading interp, hold off

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

13

图 5.6.3-0 两函数的三维相交图

(1)在某区域观察两函数 0等位线的交点情况 clear; x=-2:0.5:2;y=x;[X,Y]=meshgrid(x,y); %产生 x-y平面上网点坐标 F1=sin(X-Y);F2=cos(X+Y); v=[-0.2, 0, 0.2]; %指定三个等位值,是为了更可靠地判断 0等位线的存在。 contour(X,Y,F1,v) %画 F1的三条等位线。 hold on,contour(X,Y,F2,v),hold off %画 F2的三条等位线。

-2 -1.5 -1 -0.5 0 0.5 1 1.5 2-2

-1.5

-1

-0.5

0

0.5

1

1.5

2

图 5.6.3-1 两个二元函数 0等位线的交点图

(2)从图形获取零点的初始近似值 在图 5.6.3-1中,用 ginput获取两个函数 0等位线(即三线组中间那条线)交点的坐标。 [x0,y0]=ginput(2); %在图上取两个点的坐标 disp([x0,y0]) -0.7926 -0.7843 0.7926 0.7843 (3)利用 fsolve求精确解。以求(0.7926,7843)附近的解为例。 本例直接用字符串表达被解函数。注意:在此,自变量必须写成 x(1), x(2)。假如写成xy(1), xy(2),指令运行将出错。 fun='[sin(x(1)-x(2)),cos(x(1)+x(2))]'; %<12> xy=fsolve(fun,[x0(2),y0(2)]) %<13> xy =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

14

0.7854 0.7854 (4)检验 fxy1=sin(xy(1)-xy(2));fxy2=cos(xy(1)+xy(2));disp([fxy1,fxy2]) 1.0e-006 * -0.0994 0.2019 〖说明〗 l 指令<12><13>可用以下任何一组指令取代。

(A)内联函数形式指令 fun=inline('[sin(x(1)-x(2)), cos(x(1)+x(2))]', 'x'); %项'x'必须有。 xy=fsolve(fun,[x0(2), y0(2)]); (B)M函数文件形式及指令 先用如下 fun.m表示被解函数(并在搜索路径上) [fun.m] function ff=fun(x) ff(1)=sin(x(1)-x(2)); ff(2)=cos(x(1)+x(2)); 然后运行指令 xy=fsolve('fun',[x0(2),y0(2)]) 。

l 第四步检验中的结果表明:所找零点处的函数值小于 610−,是一个十分接近零的小数。

该精度由 options.TolFun控制。 options.TolFun的缺省值是 1.0000e-006。它可以用下列指令看到 options=optimset('fsolve');

options.TolFun ans = 1.0000e-006

5.7 函数极值点

5.7.1 一元函数的极小值点

5.7.2 多元函数的极小值点

【*例 5.7.2-1】求 222 )1()(100),( xxyyxf −+−= 的极小值点。它即是著名的 Rosenbrock's "Banana" 测试函数。该测试函数有一片浅谷,许多算法难以越过此谷。 (0)从三维等位线图初步观察测试函数 x=-3:0.1:3;y=-2:0.1:4; [X,Y]=meshgrid(x,y); F=100*(Y-X.^2).^2+(1-X).^2; contour3(X,Y,F,300), xlabel('x'),ylabel('y'),axis([-3,3,-2,4,0,inf]),view([161,22]) hold on,plot3(1,1,0,'.r','MarkerSize',20),hold off

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

15

图 5.7.2-1-0 三维等位线图显示出一条香蕉形浅谷

(1)本例采用内联函数表示测试函数如下 ff=inline('100*(x(2)-x(1)^2)^2+(1-x(1))^2','x'); (2)用单纯形法求极小值点 x0=[-1.2,1];[sx,sfval,sexit,soutput]=fminsearch(ff,x0) Optimization terminated successfully: the current x satisfies the termination criteria using OPTIONS.TolX of 1.000000e-004 and F(X) satisfies the convergence criteria using OPTIONS.TolFun of 1.000000e-004 sx = 1.0000 1.0000 sfval = 8.1777e-010 sexit = 1 soutput = iterations: 85 funcCount: 159 algorithm: 'Nelder-Mead simplex direct search' (3)用拟牛顿法求极小值点 [ux,sfval,uexit,uoutput,grid,hess]=fminunc(ff,x0) Warning: Gradient must be provided for trust-region method; using line-search method instead. > In D:\MAT53\toolbox\optim\fminunc.m at line 202 Optimization terminated successfully: Current search direction is a descent direction, and magnitude of directional derivative in search direction less than 2*options.TolFun ux = 1.0000 1.0000 sfval = 1.9118e-011 uexit =

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

16

1 uoutput = iterations: 26 funcCount: 162 stepsize: 1.2992 firstorderopt: 5.0023e-004 algorithm: 'medium-scale: Quasi-Newton line search' grid = 1.0e-003 * -0.5002 -0.1888 hess = 820.4031 -409.5497 -409.5497 204.7720

5.8 数值积分

5.8.1 一元函数的数值积分

5.8.1.1 闭型数值积分

【*例 5.8.1.1-1】求 dxeI x∫ −=1

0

2

,其精确值为 L74684204.0 。

(1)符号解析法 syms x;IS=int('exp(-x*x)','x',0,1) %求解析积分 vpa(IS) %求所得解析积分的 32位精度近似值 IS = 1/2*erf(1)*pi^(1/2) ans = .74682413281242702539946743613185 (2)MATLAB指令 quad和 quad8求积 fun=inline('exp(-x.*x)','x'); %注意:数组乘符号.*的采用是必须的。 Isim=quad(fun,0,1),I8=quad8(fun,0,1) Isim = 0.7468 I8 = 0.7468 (3)10参数 Gauss法 Ig=gauss10(fun,0,1) Ig = 0.7463 (4)样条函数积分法 xx=0:0.1:1.5;ff=exp(-xx.^2); %产生被积函数的“表格”数据 pp=spline(xx,ff); %由“表格”数据构成样条函数 int_pp=fnint(pp); %求样条积分 Ssp=ppval(int_pp,[0,1])*[-1;1] %据样条函数计算[0,1]区间的定积分 Ssp = 0.7468

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

17

(5)SIMULINK积分法

图 5.8.1.1-1 积分模型 exm5811_1_5.mdl

5.8.1.2 开型数值积分 (1)Gaussian求积法的基本思想 (2)Gaussian求积法的实施举例 (3)任意区间上的 10参数 Gaussian求积法 [gauss10.m] function g = gauss10(fun,a,b) %GAUSS10(fun,a,b) 利用10参数Gauss求积法近似计算a<x<b 区间上的积分 % fun 被积函数。字符串、内联函数名、M函数文件名都可。 %====================================================== x = [0.1488743390;0.4333953941;0.6974095683;... 0.8650633667;0.9739065285]; w = [0.2955242247;0.2692667193;0.2190863625;... 0.1494513492;0.0666713443]; t = .5*(b+a)+.5*(b-a)*[-flipud(x);x]; W = [flipud(w);w]; g = sum(W.*feval(fun,t))*(b-a)/2; 【*例 5.8.1.2-1】当 )cos()( xxf = 时,比较解析积分和近似积分。 (1)用符号法求解: syms x;F=int('cos(x)','x',-1,1),vpa(F) F = 2*sin(1) ans = 1.6829419696157930133050046432606 (2)用式(5.8.1.2-4)近似计算: aF=cos(1/sqrt(3))+cos(-1/sqrt(3)) aF = 1.6758

【*例 5.8.1.2-2】求 ∫=1

0

1ln dxx

I ,准确结果是 L.886226922

(1)符号法 syms x;IS=int('sqrt(log(1/x))','x',0,1) Warning: Explicit integral could not be found. > In D:\MAT53\toolbox\symbolic\@sym\int.m at line 58 In D:\MAT53\toolbox\symbolic\@char\int.m at line 9 IS = int(log(1/x)^(1/2),x = 0 .. 1)

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

18

(2)用 quad指令求积 ff=inline('sqrt(log(1./x))','x');Isim=quad(ff,0,1) Warning: Divide by zero. > In D:\MAT53\toolbox\matlab\funfun\@inline\feval.m at line 30 In D:\MAT53\toolbox\matlab\funfun\quad.m at line 40 Isim = Inf (3)10参数 Gauss法 Ig=gauss10(ff,0,1) Ig = 0.8861 (4)通过变量置换后再进行

令 ξ−= ex ,于是积分成为 ξξξ

deI−∞

∫ ⋅=0

%对变量置换后的积分利用符号法求解 syms xi;Isxi=int('sqrt(xi)*exp(-xi)','xi',0,inf),vpa(Isxi) Isxi = 1/2*pi^(1/2) ans = .88622692545275801364908374167055 %对变量置换后的积分利用 quad求解 gg=inline('sqrt(xi).*exp(-xi)','xi'),Igg=quad(gg,0,inf) gg = Inline function: gg(xi) = sqrt(xi).*exp(-xi) Igg = NaN

5.8.2 多重数值积分

5.8.2.1 积分限为常数的二重积分指令

5.8.2.2 内积分限为函数的二重积分 [double_int.m] function SS=double_int(fun,innlow,innhi,outlow,outhi) %double_int 采用8阶多项式近似的二重数值积分 % 内积分变量为x,其积分区间上下限可以是变量y的表达式。 %fun 被积函数,以x,y为积分变量。 %innlow,innhi 内积分区间上下限,可以是标量,或函数文件名字符串 %outlow,outhi 外积分区间上下限,是标量。 y1=outlow;y2=outhi;x1=innlow;x2=innhi;f_p=fun; SS=quad8('G_yi',y1,y2,[],[],x1,x2,f_p); [G_yi.m]

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

19

function f=G_yi(y,x1,x2,f_p) %G_yi 实现"内重"积分的函数文件,专供double_int.m调用。 %y "外重"积分的积分变量 %x1,x2 内积分区间的下、上限。 % 它们由double_int.m中quad8指令以参数方式传递过来。 %f_p 被积原函数,它由double_int.m中quad8指令以参数方式传递过来。 y=y(:);n=length(y); if isstr(x1)==1;xx1=feval(x1,y);else xx1=x1*ones(size(y));end if isstr(x2)==1;xx2=feval(x2,y);else xx2=x2*ones(size(y));end for i=1:n f(i)=quad8(f_p,xx1(i),xx2(i),[],[],y(i)); end f=f(:);

【*例 5.8.2.2-1】计算 dydxyxIy∫ ∫

+=

4

1

2 22 )( 。

(1)编写内积分区间上下限的 M函数文件 [x_low.m] function f=x_low(y) f=sqrt(y); (2)编写被积函数 被积函数函数采用内联函数 ff=inline('x.^2+y.^2','x','y')表示。 (3)被积函数用内联函数表达时,运行以下指令,即得结果 ff=inline('x.^2+y.^2','x','y'); %被积函数的内联函数表达 SS=double_int(ff,'x_low',2,1,4) SS = 9.5810 (4)本题用符号计算很容易获得高精度解 Ssym=vpa(int(int('x^2+y^2','x','sqrt(y)',2),'y',1,4)) Ssym = 9.580952380952381

5.8.3 卷积

5.8.3.1 “完整”离散序列的数值卷积 (1)求和运算上下界的确定 (2)卷积C n( )“非平凡”区间的确定

5.8.3.2 “截尾”离散序列的数值卷积

5.8.3.3 多项式乘法与离散卷积的算法同构

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

20

5.8.3.4 连续时间函数的数值卷积 (1)“零阶”近似算法 (2)“积分-插值”混合算法 (3)SIMULINK卷积法

5.8.3.5 卷积的MATLAB实现

【*例 5.8.3.5-1】有序列 =

=else

nnA

12,,4,301

)(L

和 =

=else

nnB

9,,3,201

)(L

(A)求这两个完整序列的卷积,并图示。(B)假设 )7(A 及其后的 4个非零值未知,而成为截尾序列,求卷积并图示。 %完整序列卷积 a=ones(1,10);n1=3;n2=12; %完整 A(n)序列的非平凡值和区间端点 b=ones(1,8);n3=2;n4=9; %完整 B(n)序列的非平凡值和区间端点 c=conv(a,b);nc1=n1+n3;nc2=n2+n4; %计算卷积和确定卷积非平凡区间端点 kc=nc1:nc2; %构成非平凡区间的序号自变量 %截尾序列卷积 aa=a(1:6);nn1=3;nn2=8; %截尾 A(n)序列的非平凡值和区间端点 cc=conv(aa,b);ncc1=nn1+n3; nx=nn2+n4; %“非平凡”区间右端点 ncc2=min(nn1+n4,nn2+n3); %截尾序列卷积被正确计算区间的右端点 kx=(ncc2+1):nx;kcc=ncc1:ncc2;N=length(kcc); stem(kcc,cc(1:N),'r','filled') axis([nc1-2,nc2+2,0,10]),grid,hold on stem(kc,c,'b'),stem(kx,cc(N+1:end),'g'),hold off

4 6 8 10 12 14 16 18 20 220

1

2

3

4

5

6

7

8

9

10

图 5.8.3.5-1 “完整”序列卷积和“截尾”序列卷积

【*例 5.8.3.5-2】求函数 )()( tUetu t−= 和 )()( 2/ tUteth t−= 的卷积。本例展示:(A)符号Laplace 变换求卷积的理论表示;(B)SIMULINK 卷积法的执行过程和它的快速精确性。(C)从理论符号解产生相应的理论数值序列。 (1)符号卷积法(得解析结果) syms tao;t=sym('t','positive'); %把 t定义为“取正”符号变量 US1=laplace(exp(-t)); %u(t)的 L氏变换

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

21

HS1=laplace(t*exp(-t/2)) %h(t)的 L氏变换 yt1=simple(ilaplace(US1*HS1)) %L氏反变换得卷积的理论解 HS1 = 1/(1/2+s)^2 yt1 = 4*exp(-t)+(2*t-4)*exp(-1/2*t) (2)SIMULINK卷积法

根据 )(th 的传递函数25.0

1)2/1(

1)( 22 ++=

+=

ssssH ,构作 SIMULINK 模型

exm5835_2_2.mdl ,并运行,可从示波器上看到卷积结果。

图 5.8.3.5-2-1 卷积解算模型 exm5835_2_2.mdl

(3)比较两种卷积方法的结果,并用图形表示 t=yt2(:,1); %exm5835_2.mdl示波器所保存的仿真采样时间序列 yyt1=eval(vectorize(char(yt1))); %理论解的数值序列 [dy,kd]=max(abs(yyt1-yt2(:,2))); dy12=dy/abs(yyt1(kd)) dy12 = 2.8978e-006 【*例 5.8.3.5-3】用“零阶”近似法求 )()( tUetu t−= 和 )()( 2/ tUteth t−= 的卷积。本例演示:

(A)连续函数的有限长度采样。(B)卷积数值计算三个误差(“截尾”误差、“零阶”近似误差、计算机字长误差)的影响。(C)卷积“无截尾误差”区间、“非平凡”区间端点的确定。(D)离散卷积和连续卷积之间的关系。(E)指令 conv的使用。(F)绘图分格线的运用。 (1)离散卷积运算前的准备 由于数值计算只能对有限长度序列进行,所以必须对被卷函数做截尾处理。假如把 5%作为函数的截断阈值,那么 )(tu 在 t=3处截尾, )(th 在 t=11处截尾,即取 32 =t , 114 =t 。 取采样周期 01.0=T 。 (2)实施计算 %“零阶”法计算卷积 t2=3;t4=11;T=0.01; tu=0:T:t2;N2=length(tu); th=0:T:t4;N4=length(th); u=exp(-tu);h=th.*exp(-th/2); tx=0:T:(t2+t4);Nx=length(tx); yt3=T*conv(u,h); %把计算结果与理论值比较 t=tx;yyt1=eval(vectorize(char(yt1)));%例 5.8.3.5-2第(1)步的计算结果 [dy,kd]=max(abs(yyt1(1:N2)-yt3(1:N2))); dy13(1)=dy/abs(yyt1(kd)); [dy,kd]=max(abs(yyt1(N2+1:N4)-yt3(N2+1:N4))); dy13(2)=dy/abs(yyt1(N2+kd)); [dy,kd]=max(abs(yyt1(N4+1:Nx)-yt3(N4+1:Nx))); dy13(3)=dy/abs(yyt1(N4+kd));

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

22

(3)不同区间段的误差及图示 disp('与理论结果的相对误差') disp([blanks(4),'[0,3]段 [3,11]段 [11,14]段']),disp(dy13) plot(t,yyt1,':b',t,yt3,'r') set(gca,'Xtick',[0,3,11,14]),grid 与理论结果的相对误差 [0,3]段 [3,11]段 [11,14]段 0.0068 0.0810 0.6974

0 3 11 140

0.1

0.2

0.3

0.4

0.5

0.6

0.7

图 5.8.3.5-3-1 “零阶”近似法卷积在不同区间上的精度图示

5.9 随机数据的统计描述

5.9.1 统计分布的数字特征 【*例 5.9.1-1】样本统计特征量计算示例。 %生成样本数据 X(:,1)=ones(10,1);X(1,1)=100;X(10,1)=0.01; rand('state',1);randn('state',1) %使均布及正态两随机发生器初始化 X(:,2)=rand(10,1); X(:,3)=randn(10,1);X(:,3)=2*abs(min(X(:,3)))+X(:,3); %计算一阶矩 Moment1.arithmetic=mean(X);Moment1.median=median(X); Moment1.geometric=geomean(X);Moment1.harmmonic=harmmean(X); %计算二阶矩 Moment2.Standard=std(X);Moment2.variance=var(X); Moment2.absolute=mad(X);Moment2.range=range(X); %结果显示 X,Moment1,Moment2 X = 100.0000 0.9528 3.0699 1.0000 0.7041 2.2997 1.0000 0.9539 1.3535 1.0000 0.5982 3.0790

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

23

1.0000 0.8407 1.7674 1.0000 0.4428 1.7758 1.0000 0.8368 1.1027 1.0000 0.5187 2.6017 1.0000 0.0222 1.2405 0.0100 0.3759 2.3739 Moment1 = arithmetic: [10.8010 0.6246 2.0664] median: [1 0.6511 2.0377] geometric: [1 0.4691 1.9463] harmmonic: [0.0926 0.1682 1.8276] Moment2 = Standard: [31.3429 0.2951 0.7273] variance: [982.3760 0.0871 0.5289] absolute: [17.8398 0.2331 0.6184] range: [99.9900 0.9317 1.9762]

5.9.2 样本分布的频数直方图描述 【*例 5.9.2-1】hist指令的使用示例。 randn('state',1),rand('state',31) %初始化 x=randn(100,1);y=rand(100,1); %生成正态和均匀分布实验样本 %观察正态数据组的频数直方图 5.9.2-1在不同区间分段数时的变化 subplot(1,2,1),hist(x,7) %7区间情况 subplot(1,2,2),histfit(x,20) %15区间情况(带正态拟合线)

-5 0 50

5

10

15

20

25

30

-5 0 50

2

4

6

8

10

12

图 5.9.2-1 正态分布实验数据在不同分段下的频数直方图

%观察均匀数据组的频数直方图 5.9.2-2在不同区间分段数时的变化 n_y1=min(y):0.1:max(y);n_y2=min(y):0.05:max(y); subplot(1,2,1),hist(y,n_y1) %较大区间情况 subplot(1,2,2),hist(y,n_y2) %较小区间情况

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

24

-0.5 0 0.5 10

2

4

6

8

10

12

-0.5 0 0.5 10

1

2

3

4

5

6

7

8

9

图 5.9.2-2 均匀分布实验数据在不同分段下的频数直方图

5.9.3 概率函数、分布函数、逆分布函数和随机数的发生

5.9.3.1 泊松分布(Poisson distribution) 【*例 5.9.3.1-1】 泊松分布与正态分布的关系 当泊松分布的 10>λ 时,该泊松分布十分接近正态分布 ))(,( 2λλN 。 (1)泊松分布概率函数和相应正态分布概率密度函数的计算 Lambda=20;x=0:50;yd_p=poisspdf(x,Lambda); yd_n=normpdf(x,Lambda,sqrt(Lambda)); (2)两种概率函数的图形比较 plot(x,yd_n,'b-',x,yd_p,'r+') text(30,0.07,'\fontsize{12} {\mu} = {\lambda} = 20') %MATLAB新指令

0 10 20 30 40 500

0.01

0.02

0.03

0.04

0.05

0.06

0.07

0.08

0.09

µ = λ = 20

图 5.9.3.1-1 20=λ 的泊松分布和 20=µ 正态分布的关系

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

25

5.9.3.2 正态分布(Normal distribution) 【*例 5.9.3.2-1】正态分布标准差意义的图示。 mu=3;sigma=0.5; %正态分布参数设定 x=mu+sigma*[-3:-1,1:3];yf=normcdf(x,mu,sigma); P=[yf(4)-yf(3),yf(5)-yf(2),yf(6)-yf(1)];%计算 )( σµσµ ⋅+≤≤⋅− kxkP xd=1:0.1:5;yd=normpdf(xd,mu,sigma); %计算概率密度函数,供图示。 %为各区域填色而进行的计算 for k=1:3 xx{k}=x(4-k):sigma/10:x(3+k); %用元胞数组存放采样数不同的数据 yy{k}=normpdf(xx{k},mu,sigma); %用元胞数组存放采样数不同的数据 end subplot(1,3,1),plot(xd,yd,'b');hold on fill([x(3),xx{1},x(4)],[0,yy{1},0],'g') text(mu-0.5*sigma,0.3,num2str(P(1))),hold off subplot(1,3,2),plot(xd,yd,'b');hold on fill([x(2),xx{2},x(5)],[0,yy{2},0],'g') text(mu-0.5*sigma,0.3,num2str(P(2))),hold off subplot(1,3,3),plot(xd,yd,'b');hold on fill([x(1),xx{3},x(6)],[0,yy{3},0],'g') text(mu-0.5*sigma,0.3,num2str(P(3))),hold off

0 50

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.68269

0 50

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9545

0 50

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9973

图 5.9.3.2-1 均值两侧一、二、三倍标准差之间的概率

5.9.3.3 2χ 分布(Chi-square distribution)

【*例 5.9.3.3-1】 演示逆累计分布函数的应用。 clf;v=4;xi=0.9;x_xi=chi2inv(xi,v);%设置信水平ξ 为 90%,确定置信区间。 x=0:0.1:15;yd_c=chi2pdf(x,v); %计算 )4(2χ 的概率密度函数,供绘制曲线用。 %绘制图形,并把置信区间填色。 plot(x,yd_c,'b'),hold on xxf=0:0.1:x_xi;yyf=chi2pdf(xxf,v); %为填色而计算 fill([xxf,x_xi],[yyf,0],'g') %注意:加入点(x_xi,0)以使填色区域封闭。 text(x_xi*1.01,0.01,num2str(x_xi)) %注写置信区间边界值 text(10,0.16,['\fontsize{16} x~{\chi}^2' '(4)']) %<8>

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

26

text(1.5,0.08,'\fontname{隶书}\fontsize{22}置信水平 0.9') %<9> hold off

0 5 10 150

0.02

0.04

0.06

0.08

0.1

0.12

0.14

0.16

0.18

0.2

7.7794

x~χ2(4)

置信水平0.9

图 5.9.3.3-1 )4(2χ 分布水平为 90%的置信区间

5.10 多项式拟合和非线性最小二乘

5.10.1 多项式拟合

5.10.1.1 多项式拟合原理

5.10.1.2 拟合多项式阶数的确定

5.10.1.3 多项式拟合的MATLAB实现 【*例5.10.1.3-1】实施函数拟合的较完整描述示例。 在进行函数拟合时,有几个问题要回答:(1)采用什么函数模型?(2)模型的结构参数是什么?(3)参数的估计值如何计算?(4)估计参数的离差? 本例采用多项式模型,模型阶数(结构参数)通过 2χ 量确定,多项式系数运用最小二

乘估计,并给出相应的离差。具体如下。 %被拟合的原始数据 x=0:0.1:1;y=[2.1,2.3,2.5,2.9,3.2,3.3,3.8,4.1,4.9,5.4,5.8]; dy=0.15; %原数据 y的标准差 for n=1:6 %依次用 1到 6阶多项式去拟合 [a,S]=polyfit(x,y,n); %计算拟合多项式系数 A{n}=a; %用元胞数组记录不同阶次多项式的系数 da=dy*sqrt(diag(inv(S.R'*S.R))); %计算各系数的误差 DA{n}=da'; %用元胞数组记录不同阶次多项式系数的误差 freedom(n)=S.df; %记录自由度 [ye,delta]=polyval(a,x,S); %计算拟合多项式值的范围 YE{n}=ye; %用元胞数组记录不同阶次拟合多项式的均值 D{n}=delta; %用元胞数组记录不同阶次拟合多项式的离差

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

27

chi2(n)=sum((y-ye).^2)/dy/dy; %计算不同阶次的2χ 量。

end Q=1-chi2cdf(chi2,freedom); %用于判断拟合良好度 %适当度的图示 subplot(1,2,1),plot(1:6,abs(chi2-freedom),'b') xlabel('阶次'),title('chi 2与自由度') subplot(1,2,2),plot(1:6,Q,'r',1:6,ones(1,6)*0.5) xlabel('阶次'),title('Q 与 0.5 线')

0 2 4 60

2

4

6

8

10

12

14

16

阶 次

chi 2与 自 由 度

0 2 4 60

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

阶 次

Q 与 0.5 线

图 5.10.1.3-1 利用适当度选定拟合多项式的阶次

%适当的三阶多项式拟合情况图示 clf,plot(x,y,'b+');axis([0,1,1,6]);hold on errorbar(x,YE{3},D{3},'r');hold off title('较适当的三阶拟合') text(0.1,5.5,['chi2=' num2str(chi2(3)) '~' int2str(freedom(3))]) text(0.1,5,['freedom=' int2str(freedom(3))]) text(0.6,1.7,['Q=' num2str(Q(3)) '~0.5'])

0 0.2 0.4 0.6 0.8 11

1.5

2

2.5

3

3.5

4

4.5

5

5.5

6较适 当的三阶 拟合

chi2=4.9707~7

freedom=7

Q=0.66353~0.5

图 5.10.1.3-2 三阶多项式的拟合情况

A{3},DA{3} %拟合多项式的系数和离差

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

28

ans = 0.6993 1.2005 1.8869 2.1077 ans =

1.9085 2.9081 1.2142 0.1333

〖说明〗由于原始数据较少,被估多项式系数有较大的离差。

5.10.2 非线性最小二乘估计

5.10.2.1 伪线性最小二乘

5.10.2.2 借助 fminsearch指令进行非线性最小二乘估计

【*例 5.10.2.2-1】取发生信号的原始模型为 xx eexy 2.34.0 123)( −− += 。 x在[0, 4]中; y受到

噪声 0.3*(rand(n,1)-0.5) 的污染。本例演示:如何以xaxa eaeay 43

21−− += 为模型,通过

fminsearch从受污染数据中,估计出参数 ],,,[)]4(),3(),2(),1([ 4321 aaaaaaaaa == 。 (1)编写两个 M函数文件:仿真数据产生文件和二乘残差计算文件。 [xydata.m] function [x,y,STDY]=xydata(k_noise) %xydata.m 产生仿真数据 x=[0:0.2:4]'; %自变量采样向量 yo=3*exp(-0.4*x)+12*exp(-3.2*x); %产生未受干扰的函数量 rand('seed',234) %均布随机发生器初始化(为读者重复本例结果而设) y_noise=k_noise*(rand(size(x))-0.5); %产生均布随机数 y=yo+y_noise; %生成受干扰函数量 STDY=std(y_noise); %计算噪声的标准差 [twoexps.m] function E=twoexps(a,x,y) %twoexps.m 计算二乘残差的程序 x=x(:);y=y(:);Y=a(1)*exp(-a(3)*x)+a(2)*exp(-a(4)*x); %计算估计函数值 E=sum((y-Y).^2); %二乘残差 (2)编写M脚本文件作为主文件 [exm051022_1.m] %exm051022_1.m 利用fminsearch指令进行非线性参数估计 k_noise=0.3; %控制噪声水平 [x,y,STDY]=xydata(k_noise); %运行仿真数据产生程序,产生数据 a0=[1 1 1 1]; %被估参数的初试猜测 options.TolX=0.01; %控制被估参数的迭代精度 options.Display='off'; %避免显示收敛信息 a=fminsearch('twoexps',a0,options,x,y); %计算二乘残差最小时的参数估计 chi_est=twoexps(a,x,y)/STDY^2; %估计参数下的Chi2量计算 freedom=length(x)-length(a0); %自由度 Q=1-chi2cdf(chi_est,freedom); %适当度 %以下用于绘图 y_est=a(1)*exp(-a(3)*x)+a(2)*exp(-a(4)*x);

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

29

ych='y_e_s_t='; %注意:该格式使图形中est三个字母成为下标 a1=num2str(a(1));a2=num2str(a(2));a3=num2str(a(3));a4=num2str(a(4)); char_y_est=[ych,a1,'*exp(-',a3,'*x) + ',a2,'*exp(-',a4,'*x)']; plot(x,y,'b+');hold on,plot(x,y_est,'r');hold off,axis([0,4,0,16]) text(0.4,14,'y=3*exp(-0.4*x)+12*exp(-3.2*x)') text(0.4,12,char_y_est),text(2.5,9,['chi2=' , num2str(chi_est)]) text(2.5,7,['freedom=' , num2str(freedom)]) text(2.5,5,['Q=' , num2str(Q)]) (3)以上文件都存放在用户自己的工作目录上,再使该目录成为当前目录,则在 Notebook中就可以进行以下指令的运行,并得到如图 5.10.2.2-1所示的图形结果。 exm051022_1

0 0.5 1 1.5 2 2.5 3 3.5 40

2

4

6

8

10

12

14

16

y=3*exp(-0.4*x)+12*exp(-3.2*x)

yest=2.8967*exp(-0.38045*x) + 11.983*exp(-3.0985*x)

chi2=17.7066

freedom=17

Q=0.40757

图 5.10.2.2-1 借助 fminsearch指令估计非线性模型参数

【*例 5.10.2.2-2】以xaxa ebeby 21

21−− += 为模型,从受污染的数据中,使用伪线性法估

计 [ ]21 bbb = ,使用 fminsearch估计 [ ]21 aaa = 。 (1)编写两个 M函数文件:仿真数据产生文件(与上例相同)和二乘残差计算文件。 [twoexps2.m] function E=twoexps2(a,x,y,b) %twoexps2.m 计算二乘残差的程序 x=x(:);y=y(:);Y=b(1)*exp(-a(1)*x)+b(2)*exp(-a(2)*x); %计算估计函数值 E=sum((y-Y).^2); %二乘残差 (2)编写M脚本文件作为主文件 [exm051022_2.m] %exm051022_2.m 利用伪线性和fminsearch混合法进行非线性参数估计 k_noise=0.3; %控制噪声水平 [x,y,STDY]=xydata(k_noise); %运行仿真数据产生程序,产生数据 a0=[1 2]'; %非线性参数的初试猜测 options.TolX=0.001; %控制被估参数的迭代精度 options.Display='off'; %避免显示收敛信息

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

30

%下面是伪线性和fminsearch交互使用的迭代循环 while 1 Mb=exp(-x*a0'); %利用初试猜测a0,构成线性估计的系数矩阵。 b=Mb\y; %线性最小二乘求线性参数b a=fminsearch('twoexps2',a0,options,x,y,b); %利用b估计非线性参数 r=norm(a-a0)/norm(a);%计算非线性参数估计的相对误差 if r<0.001;break;end %估计精度控制 a0=a; end chi_est=twoexps2(a,x,y,b)/STDY^2; %估计参数下的Chi2量计算 freedom=length(x)-length([a;b]); %自由度 Q=1-chi2cdf(chi_est,freedom); %适当度 %以下用于绘图 y_est=b(1)*exp(-a(1)*x)+b(2)*exp(-a(2)*x); ych='y_e_s_t='; %注意:该格式使图形中est三个字母成为下标 b1=num2str(b(1));b2=num2str(b(2));a1=num2str(a(1));a2=num2str(a(2)); char_y_est=[ych ,b1,'*exp(-',a1,'*x) + ',b2,'*exp(-',a2,'*x)']; plot(x,y,'b+');hold on;plot(x,y_est,'r');hold off;axis([0,4,0,16]) text(0.4,14,'y=3*exp(-0.4*x)+12*exp(-3.2*x)');text(0.4,12,char_y_est) text(2.5,9,['chi2=' , num2str(chi_est)]) text(2.5,7,['freedom=' , num2str(freedom)]) text(2.5,5,['Q=' , num2str(Q)]) (3)以上文件都存放在用户自己的工作目录上,再使该目录成为当前目录,则在 Notebook中就可以进行以下指令的运行,并得到如图 5.10.2.2-2所示的图形结果。 exm051022_2

0 0.5 1 1.5 2 2.5 3 3.5 40

2

4

6

8

10

12

14

16

y=3*exp(-0.4*x)+12*exp(-3.2*x)

yest=3.0187*exp(-0.39739*x) + 11.8737*exp(-3.1466*x)

chi2=18.0087

freedom=17

Q=0.38829

图 5.10.2.2-2 伪线性和 fminsearch混合法估计非线性模型参数

5.10.2.3 非线性最小二乘估计指令

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

31

5.11 插值和样条

5.11.1 一维插值 【*例 5.11.1-1】已知一组原始数据,确定它们所代表函数穿越 95.0=y 线的时刻。 (1)为仿真,生成原始数据对 ),( yt 。 t=linspace(0,5,100);y=1-cos(3*t).*exp(-t); (2)通过图形初步判断穿越时刻 步骤:先在指令窗中运行以下指令绘图;再利用运用图形窗上的放大功能,对第一穿

越点附近局部放大;然后,利用 t_ginput=ginput(1) ,从图上获得穿越点的坐标。 plot(t,y,'b');grid;hold on,plot(t,0.95*ones(size(t)),'r');hold off

0 1 2 3 4 50

0.2

0.4

0.6

0.8

1

1.2

1.4

图 5.11.1-1 据原始数据确定穿越时刻

t_ginput=ginput(1) %它的第一个元素就是穿越时刻。 t_ginput = 0.4965 0.9500 (3)利用插值获得较准确的穿越时刻 步骤: 先确定原始数据中第一次穿越 0.95的元素位置;然后取该元素前后各 3个元素作为插值的“基准”数据,进行插值;再用所得插值数据确定穿越时刻。 it=min(find(y>0.95)); %确定原始数据中第一次使 y>0.95的元素“下标” T=(it-3):(it+3); %在第一穿越点两侧,各取 3点,作为插值“基准” <2> t_nearst=interp1(y(T),t(T),0.95,'nearst'); % <3> t_linear=interp1(y(T),t(T),0.95); % <4> t_cubic=interp1(y(T),t(T),0.95,'cubic'); % <5> t_spline=interp1(y(T),t(T),0.95,'spline'); % <6> disp([' t_nearst t_linear t_cubic t_spline']) disp([t_nearst t_linear t_cubic t_spline]) t_nearst t_linear t_cubic t_spline 0.5051 0.4965 0.4962 0.4962 (4)利用 fzero求穿越时刻,以便比较。 t_zero=fzero('1-cos(3*x).*exp(-x)-0.95',0.5) Zero found in the interval: [0.48586, 0.5]. t_zero = 0.4962

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

32

5.11.2 高维函数的插值 【*例 5.11.2-1】假设有一组海底深度测量数据,采用插值方式绘制海底形状图。 (1)为仿真,用以下模型产生一组分度稀疏的“海底深度测量数据”。 randn('state',2) %为仿真的可重复性而设 x=-5:5;y=-5:5;[X,Y]=meshgrid(x,y); %产生“经纬”矩阵 %以下两条指令本可写成一条。因 Notebook无法正确处理续行号,不得不如此。 zz=1.2*exp(-((X-1).^2+(Y-2).^2))-0.7*exp(-((X+2).^2+(Y+1).^2)); Z=-500+zz+randn(size(X))*0.05; %使数据带标准差为 0.05的随机误差 surf(X,Y,Z);view(-25,25)

-50

5

-5

0

5-501

-500.5

-500

-499.5

-499

-498.5

图 5.11.2-1 据基准数据绘制的曲面图

(2)通过插值画更细致的海底图 xi=linspace(-5,5,50);yi=linspace(-5,5,50);[XI,YI]=meshgrid(xi,yi); ZI=interp2(X,Y,Z,XI,YI,'*cubic'); surf(XI,YI,ZI),view(-25,25)

图 5.11.2-2 由插值数据生成的曲面

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

33

5.12 样条函数及其应用

5.12.1 样条插值

【*例 5.12.1-1】根据连续时间函数 tetw −=)( 的采样数据,利用 spline重构该连续函数,并检查重构误差。 t=-5:0.5:5;w=exp(-abs(t)); %产生采样数据 N0=length(t);tt=linspace(t(1),t(end),10*N0);%产生重构函数用的自变量数据 ww=spline(t,w,tt); %进行重构 error=max(abs(ww-exp(-abs(tt)))) %检查误差 plot(tt,ww,'b');hold on %重构函数曲线 stem(t,w,'filled','r');hold off %原采样数据杆图 error = 0.0840

-5 0 50

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

1

图 5.12.1-1 样条插值进行信号重构

【*例 5.12.1-2】用样条插值产生长、短轴分别在 45度、135度线上的椭圆。 theta=[0:0.5:2]*pi; %产生四个样点 y=[-0.5 1 -0.5 -1 0.5 1 -0.5;0.5 1 0.5 -1 -0.5 1 0.5]; %<3> theta2=linspace(theta(1),theta(end),50*length(theta)); %参量稠密化 yy=spline(theta,y,theta2); %求稠密点上的插值 plot(yy(1,:),yy(2,:),'b');hold on plot(y(1,:),y(2,:),'or');hold off,axis('image')

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

34

-1 -0.5 0 0.5 1

-1

-0.8

-0.6

-0.4

-0.2

0

0.2

0.4

0.6

0.8

1

图 5.12.1-2 利用四个样点产生的椭圆

5.12.2 样条函数用于数值积分和微分

【 *例 5.12.2-1】对于函数 xy sin= ,很容易求得 ∫ −==x

xxdxxS0

cos1sin)( ,

xy cos=′ 。本例将借此演示样条函数求数值不定积分、导函数的能力。 (1)不定积分样条函数、导数样条函数的求取和精度分析 x=(0:0.1:1)*2*pi;y=sin(x); % 获得样点数据 pp=spline(x,y); % 求 PP形式的样条函数 pp,它近似表示 xy sin= int_pp=fnint(pp); % 样条函数 pp的数值不定积分 int_pp,应近似 )(xS 。 der_pp=fnder(pp); % 样条函数 pp的数值导函数 der_pp,应近似 y′。 % 在基础区间上,计算三个样条函数与理论值的最大误差 xx=(0:0.01:1)*2*pi; err_yy=max(abs(ppval(pp,xx)-sin(xx))) err_int=max(abs(ppval(int_pp,xx)-(1-cos(xx)))) err_der=max(abs(ppval(der_pp,xx)-cos(xx))) err_yy = 0.0026 err_int = 0.0010 err_der = 0.0253 (2)不定积分样条函数、导数样条函数的使用 不定积分样条函数可用来计算基础区间中任何区间上的定积分。导数样条函数可方便

地计算基础区间内任何一点的导数。 % 计算 y(x)在区间[1,2]上的定积分 DefiniteIntegral.bySpline=ppval(int_pp,[1,2])*[-1;1]; % <2> DefiniteIntegral.byTheory=(1-cos(2))-(1-cos(1)); % 计算 dy(3)/dx Derivative.bySpline=fnval(der_pp,3); Derivative.byTheory=cos(3); Derivative.byDiference=(sin(3.01)-sin(3))/0.01; %前向差分近似

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

35

DefiniteIntegral,Derivative DefiniteIntegral = bySpline: 0.9563 byTheory: 0.9564 Derivative = bySpline: -0.9895 byTheory: -0.9900 byDiference: -0.9907 (3)绘制三个样条函数的图形 fnplt(pp,'b-');hold on fnplt(int_pp,'m:'),fnplt(der_pp,'r--');hold off legend('y(x)','S(x)','dy/dx')

0 1 2 3 4 5 6 7-1

-0.5

0

0.5

1

1.5

2

2.5y(x) S(x) dy/dx

图 5.12.2-1 原函数、不定积分样条函数、导函数

5.13 Fourier分析

5.13.1 快速 Fourier变换和逆变换指令

5.13.2 连续时间函数的 Fourier级数展开

5.13.2.1 展开系数的积分求取法

5.13.2.2 Fourier级数与 DFT之间的数学联系

5.13.2.3 MATLAB算法实现

【*例 5.13.2.3-1】已知时间函数else

tttw

5.15.00

5.0)(

≤≤

= ,运用符号法求该函数

的 Fourier级数展开系数。 (1)编写函数文件 fzzysym.m 。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

36

[fzzysym.m] function [A_sym,B_sym]=fzzysym(T,Nf,Nn) % 采用符号计算求[0,T]内时间函数的三角级数展开系数。 % 函数的输入输出都是数值量 % Nf 谐波的阶数 % Nn 输出数据的准确位数 % A_sym 第1元素是直流项,其后元素依次是1,2,3...次谐波cos项展开系数 % B_sym 第2,3,4,...元素依次是1,2,3...次谐波sin项展开系数 syms ttt n if nargin<2;Nf=6;end if nargin<3;Nn=32;end yy=time_fun_s(ttt); A0=int(yy,ttt,0,T)/T; As=int(yy*cos(2*pi*n*ttt/T),ttt,0,T); Bs=int(yy*sin(2*pi*n*ttt/T),ttt,0,T); A_sym(1)=double(vpa(A0,Nn)); for k=1:Nf A_sym(k+1)=double(vpa(subs(As,n,k),Nn)); B_sym(k+1)=double(vpa(subs(Bs,n,k),Nn)); end %------------------------------------------- function yy=time_fun_s(ttt) % 该函数是fzzysym.m的子函数。它由符号变量和表达式写成。 y1=sym('Heaviside(ttt-0.5)')*(ttt-0.5); yy=y1-sym('Heaviside(ttt-1.5)')*((ttt-1.5)+1); (2)在 MATLAB指令窗中运行以下指令,就可得到结果。 [A_sym,B_sym]=fzzysym(2) A_sym = 0.2500 -0.3183 0.0000 0.1061 -0.0000 -0.0637 0.0000 B_sym = 0 -0.2026 0.1592 0.0225 -0.0796 -0.0081 0.0531 【*例 5.13.2.3-2】运用数值积分法,按式(5.13.2.1-4)和(5.13.2.1-5),求上例时间函数的 Fourier级数展开系数。(注意:由于要做比较,本例必须在上例 5.13.2.3-1运行情况下进行) (1)编写函数文件 fzzyquad.m ,cos_y.m ,sin_y.m ,time_fun.m 。 [fzzyquad.m] function [t,y,S,A,B]=fzzyquad(a,T,Nf,K) % 用数值积分求Fourier级数展开系数A,B和近似波形S 。如调用本指令时,没有任何 % 输出宗量,那么将自动随积分进程动态地画出原波形和各阶近似波形。 % a 是被展开函数的时间区间的左端。 % T 是被展开函数的周期。 % Nf 是所需展开的最高谐波阶次 % K 绘波形图所采用的数据长度 % t,y 是被展开的时间函数数据。 % S 是一个矩阵。它每行的长度与t,y相同。 % 它的第(n+1)行是所有n次及更低次谐波迭加生成的近似波形。 % A,B 是展开系数向量。A(n+1),B(n+1)分别存放cos,sin项n次谐波的展开系数。 % A(1)是直流项

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

37

if nargin<4;K=100;end if (nargin<3|isempty(Nf));Nf=15;end k=1:K; t=a+k*T/length(k); y=time_fun(t,T); %调用函数文件,产生被展开函数。 S=zeros(Nf+1,length(k)); a0=mean(y); S(1,:)=a0; A=zeros(1,Nf+1);B=zeros(1,Nf+1); A(1)=a0; for n = 1:Nf A(n+1) = quad8('cos_y',a,a+T,[],[],n,T)/T*2; B(n+1) = quad8('sin_y',a,a+T,[],[],n,T)/T*2; S(n+1,:)=S(n,:)+A(n+1)*cos(2*n*pi*t/T)+B(n+1)*sin(2*n*pi*t/T); if nargout==0 plot(t,y,'b');hold on plot(t,S(n+1,:),':r'); aa=axis;dx=aa(2)-aa(1);dy=aa(4)-aa(3); text(aa(1)+0.1*dx,aa(3)+.75*dy,'n = ') text(aa(1)+0.2*dx,aa(3)+.75*dy,num2str(n)); pause(1);hold off end end [cos_y.m] function wcos=cos_y(t,n,T) % 生成求cos项展开系数的被积函数。 y=time_fun(t,T);wcos=cos(2*n*pi*t/T).*y; [sin_y.m] function wsin=sin_y(t,n,T) % 生成求sin项展开系数的被积函数。 y=time_fun(t,T);wsin=sin(2*n*pi*t/T).*y; [time_fun.m] function y=time_fun(t,T) % 这是需要用户自己编写的待展开的时间函数 y(t+k*T)=y(t) % 编写程序时,一定要注意使表达式适于数组运算 % t 是时间数组 % T 是周期 y=zeros(size(t));ii=find(t>=0.5 & t<=1.5); y(ii)=ones(size(ii)).*(t(ii)-0.5);y(y==1.0)=0.5; (2)先在MATLAB指令窗中,运行指令<1>;然后再在 Notebook中运行其下指令 [t,y,S,A_quad,B_quad]=fzzyquad(0,2,15); %计算 0到 15次谐波 <1> AA=abs(A_sym);AA(AA<1e-10)=NaN; %在那些实际应为 0的很小数处,考虑相对误差

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

38

%没有意义,故予以排除。 BB=abs(B_sym);BB(BB<1e-10)=NaN; asq=abs(A_quad(1:7)-A_sym)./AA %偶函数系数与符号计算值的相对误差 bsq=abs(B_quad(1:7)-B_sym)./BB %奇函数系数与符号计算值的相对误差 asq = 1.0e-008 * 0 0.0173 NaN 0.3851 NaN 0.0581 NaN bsq = 1.0e-007 * NaN 0.0000 0.4109 0.0914 0.0006 0.0162 0.0385 (3)图形显示截断余项后三角展开近似波形 SS=[S;y]';ribbon(t,SS);%把原始波形列在图形最前方 view([96,36]),colormap(jet),shading flat,light,lighting gouraud

图 5.13.2.3-1 近似波形和原波形

【*例 5.13.2.3-3】运用 FFT,按式(5.13.2.2-2)和(5.13.2.2-3),求上例时间函数的 Fourier级数展开系数。(注意:由于要做比较,本例必须在例 5.13.2.3-1运行情况下进行) (1)编写函数文件 fzzyfft.m 。 [fzzyfft.m] function [A,B,C,fn,t,w]=fzzyfft(T,M,Nf) % 利用FFT,计算[0,T}区间上定义的时间波形的Fourier级数展开系数A,B和频谱C,fn 。 % T 时间波形周期 % M 用作2的幂次 % Nf 输出谐波的阶次,决定A,B的长度为(Nf+1)。Nf不要超2^(M-1)。 % A,B 分别是Fourier级数中cos,sin展开项的系数。A(1)是直流量。 % C 是定义在[-fs/2,fs/2]上的频谱 % t,w 是原时间波形数据对 if (nargin<2 | isempty(M));M=8;end % <9> if nargin<3;Nf=6;end % <10> N=2^M; %使总采样点是2的整数倍

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

39

f=1/T; %被变换函数的频率 w0=2*pi*f; dt=T/N; %时间分辨率 n=0:1:(N-1); %采样点序列 t=n*dt; %采样时间序列 w=time_fun(t,T); %被变换时间函数的采样序列 <17> % W=fft(w); %给出n=0,1,...,N-1上的DFT数据值 cn=W/N; %据式(5.13.2.2-2)计算n=0,1,...,N-1上的FS系数 % z_cn=find(abs(cn)<1.0e-10);%寻找有限字长运算而产生(原应为0)的"小"复数 cn(z_cn)=zeros(length(z_cn),1); %强制那些"小"复数为0 <23> cn_SH=fftshift(cn); %据式(5.13.2.2-3)计算 <24> %n=-N/2,...,-1,0,1,...,(N/2)-1上的FS系数 C=[cn_SH cn_SH(1)]; %形成关于0对称的(N+1)个FS系数 A(1)=C(N/2+1); A(2:N/2+1)=2*real(C((N/2+2):end)); B(2:N/2+1)=-2*imag(C((N/2+2):end)); if Nf>N/2;error(['第三输入宗量 Nf 应小于 ' int2str(N/2-1)]);end A(Nf+2:end)=[]; B(Nf+2:end)=[]; n1=-N/2:1:N/2; %产生总点数为(N+1)关于0对称的序列 fn=n1*f; %关于0对称的频率分度序列 (2)运行以下指令 [A_fft,B_fft]=fzzyfft(2); AA=abs(A_sym);AA(AA<1e-10)=NaN;BB=abs(B_sym);BB(BB<1e-10)=NaN; ast=abs(A_sym-A_fft)./AA %偶函数系数与符号计算值的相对误差 bst=abs(B_sym-B_fft)./BB %奇函数系数与符号计算值的相对误差 ast = 0 0.0001 NaN 0.0005 NaN 0.0013 NaN bst = NaN 0.0001 0.0002 0.0005 0.0008 0.0013 0.0018

5.13.3 利用 DFT计算一般连续函数的 Fourier变换 CFT

5.13.3.1 CFT与 DFT之间的数学联系

5.13.3.2 MATLAB算法实现

【*例 5.13.3.2-1】运用 FFT求取矩形脉冲else

ttw

1001

)(≤≤

= 的谱,说明采样频率低

引起的混迭现象。 (1)编写有一定通用性的函数文件 cftbyfft.m [cftbyfft.m] function [AW,f]=cftbyfft(wt,t,flag) %cftbyfft.m %本程序采用FFT计算连续时间Fourier变换。输出幅频谱数据对(f,AW)。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

40

% 输入量(wt,t)为已经窗口化了的时间函数wt(t),它们分别是长度为N的向量。 % 对于"非平凡"取值时段有限的情况,应使该时段与窗口长度相比足够小。以 % 提高频率分辨率。 % 对于"非平凡"取值时段无限的情况,窗口长度的选取应使窗口外的函数值小 % 到可忽略,以提高近似精度。 % 输入宗量flag控制输出CFT的频率范围。 % flag取非0时(缺省使用),频率范围在[0,fs); % flag取0时,频率范围在[-fs/2,fs/2)。 if nargin==2;flag=1;end N=length(t); %采样点数,应为2的幂次,以求快速。 T=t(length(t))-t(1); %窗口长度 dt=T/N; %时间分辨率。 W0=fft(wt); %施行FFT变换 <16> W=dt*W0; %算得[0,fs)上的N点CFT值 df=1/T; %频率分辨率 n=0:1:(N-1); %把以上计算结果改写到[-fs/2,fs/2]范围 if flag==0 n=-N/2:(N/2-1); W=fftshift(W); %产生满足式(5.13.3.1-6)的频谱 end f=n*df; %频率分度向量 AW=abs(W); %福频谱数据向量 if nargout==0 plot(f,AW);grid,xlabel('频率f');ylabel('|w(f)|') end (2)运行以下指令,绘制时域波形和幅频谱 M=5; %做 2的幂次用。本例把 M设得较小,是为了观察混迭。 <1> tend=1; %波形取非零值的时间长度。 T=10; %窗口化长度应足够大,以减小窗口化引起的泄露“旁瓣”效应。 <3> N=2^M; %采样点数,取 2的幂是为使 FFT运算较快。 dt=T/N; %以上 T、N的取值应使 N/T=fs采样频率大于两倍时间波形带宽,以克服 %采样引起的频谱混迭。 %在本例中,据理论分析知 W(f=7.5)=Sa(7.5*pi)=1/(7.5*pi)<5% 。 %因此,可近似认为本例时间信号带宽为 7.5Hz 。 n=0:N-1; %采样序列 t=n*dt; %采样点时间序列 w=zeros(size(t,2),1); Tow=find((tend-t)>0); %产生非零波形时段的相应序列 w(Tow,1)=ones(length(Tow),1); %在窗口时段内定义的完整波形 plot(t,w,'b','LineWidth',2.5),title('Time Waveform');xlabel('t --- >')

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

41

0 2 4 6 8 100

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

1Time Waveform

t --- > 图 5.13.3.2-1 被窗口化的时间波形

[AW,f]=cftbyfft(w,t,0); ff=f+eps; %为避免下面指令出现 0/0而采取的措施 AWW=abs(sin(pi*ff)./(pi*ff)); plot(f,AW,'b-',ff,AWW,'r:') title('Aliasing caused by undersampling') xlabel('f --- >');ylabel('|W(f)|'),legend('by FFT','Theoretical')

-2 -1.5 -1 -0.5 0 0.5 1 1.5 20

0.2

0.4

0.6

0.8

1

1.2

1.4Aliasing caused by undersampling

f --- >

|W(f)

|

by FFT Theoretical

图 5.13.3.2-2 “欠”采样时引起的混迭

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

42

5.14 常微分方程

5.14.1 初值常微分方程的解算指令

5.14.1.1 解 ODE的基本机理

5.14.1.2 solver解算指令的使用说明

5.14.2 ODE解算指令的使用演示

5.14.2.1 解算指令简洁格式使用示例 【*例 5.14.2.1-1】采用最简洁格式的 ODE文件和解算指令,研究围绕地球旋转的卫星轨道。

图 5.14.2.1-1 地球轨道卫星运动加速度

(1)问题的形成

轨道上运动的卫星,在 Newton 第二定律 2

2

dtrdmmaFr

== ,和万有引力定律

rr

mMGF E r3−= 作 用 下 , 有 r

rmMG

dtrda E rr

32

2

−== 。 即 3rxGMa Ex −= ,

3ryGMa Ey −= ,而

22 yxr += 。这里 )/(10672.6 2211 kgmNG ⋅×= − 是引力常数,

)(1097.5 24 kgM E ×= 是地球的质量。又假定卫星以初速度 )/(4000)0( smv y = 在

)(102.4)0( 7 mx ×−= 处进入轨道。 (2)构成一阶微分方程组 令 [ ] [ ] [ ]TT

yxT yxyxvvyxyyyyY ′′=== 4321 ,则

+⋅−

+⋅−=

′′′′

=′

2/3222

2/3221

4

3

4

3

2

1

)(

)()(

yxyGM

yxyGM

yy

yyyy

tY

E

E (5.14.2.1-5)

初始条件为 [ ]TyvxY )0(00)0()0( = (5.14.2.1-6)

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

43

(3)根据式(5.14.2.1-5)编写最简洁格式的 ODE文件 [dYdt.m] function Yd=DYdt(t,Y) % t 一定是标量形式的自变量 % Y 必须是列向量 global G ME %在函数中定义全局变量传递参数 xy=Y(1:2);Vxy=Y(3:4); %前两个元素是"位移量",后两个是"速度量"。 r=sqrt(sum(xy.^2)); Yd=[Vxy;-G*ME*xy/r^3]; %Yd必须按式(5.14.2.1-5)编写,是与Y同维的列向量。 (4)对微分方程进行解算 global G ME %在主程序中定义全局变量传递参数 <1> G=6.672e-11;ME=5.97e24;vy0=4000;x0=-4.2e7;t0=0;tf=60*60*24*9; tspan=[t0,tf]; %指定解算微分方程的时间区间 Y0=[x0;0;0;vy0]; %按式(5.14.2.1-6)给定初值向量 [t,YY]=ode45('DYDt',tspan,Y0); %<8> X=YY(:,1); %输出 Y的第一列是位移数据 x(t) Y=YY(:,2); %输出 Y的第二列是位移数据 y(t) plot(X,Y,'b','Linewidth',2); hold on axis('image') %保证 x、y轴等长刻度,且坐标框恰包容图形 [XE,YE,ZE] = sphere(10); %产生单位球面数据 RE=0.64e7; %地球半径 XE=RE*XE;YE=RE*YE;ZE=0*ZE; %坐标纸上的地球平面数据 mesh(XE,YE,ZE),hold off %绘地球示意图

0 5 10 15 20

x 107

-8

-6

-4

-2

0

2

4

6

8

x 107

图 5.14.2.1-2 卫星轨道

【*例 5.14.2.1-2】上例中,程序间的参数(如 G和 ME)传送,是依靠全局变量形式实现的。一般说来,编写程序时,应尽量少用全局变量,以免引起混乱。本例演示参数如何在指令

间直接传送。 要实现参数直接传送,必须对上例中的程序进行修改,具体如下: (1)重写 ODE文件 [DYDt2.m] function Yd=DYDt2(t,Y,flag,G,ME)

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

44

% flag 按ODE文件格式规定,必须是第三输入宗量。对它的赋值由ode45指令自动产生。 % 第4、5宗量是被传递的参数 switch flag case '' %按规定:这里必须是空串。在此为"真"时,完成以下导数计算。 X=Y(1:2);V=Y(3:4);r=sqrt(sum(X.^2));Yd=[V;-G*ME*X/r^3]; otherwise error(['Unknown flag ''' flag '''.']); end (2)按以下方法修改上例第(4)步中的程序,并运行之,可得相同结果。 删去原主程序第<1>条指令;把原主程序的第<8>条指令改写为 [t,YY]=ode45('DYDt2',tspan,Y0,[],G,ME); %第 4宗量取缺省设置 %第 5、6宗量是被传递参数

5.14.2.2 解算指令较复杂格式的使用示例 【*例 5.14.2.2-1】带事件设置的 ODE文件及主程序编写演示。本例将以较高精度计算卫星经过近地点和远地点的时间,并在图上标志。 (1)ODE文件的编写 [DYDt3.m] function varargout=DYDt3(t,Y,flag,G,ME,tspan,Y0) % DYDt3.m 供主程序调用的ODE函数文件 % 本文件自带三个子函数:f,fi,fev。 % t, Y 分别是自变量和一阶函数向量,是最基本的输入宗量。 % flag 第三输入宗量,它专供解算指令(如ode45)作调用通知。 % 在运行中,解算指令会根据需要向flag发不同的字符串。 % varargout 是"变"输出宗量。它由变维的元胞数组构成。每个元胞中可以存放指令 % 所产生的任意形式的数据。 switch flag case '' % 必须用空串符。情况为"真"时,计算导数 dY/dt = f(t,Y)。 varargout{1} = f(t,Y,G,ME); %输出为一个元胞,容纳f子函数的一个输出Yd case 'init' % 必须用'init',情况为"真"时,传送计算区间、初值、设置参数。 [varargout{1:3}] = fi(tspan,Y0); %输出为三个元胞,容纳fi子函数的三个输出量 case 'events' % 必须用'events',情况为"真"时,设置事件性质。 [varargout{1:3}] = fev(t,Y,Y0); %输出三个元胞,容纳fev子函数的三个输出量 otherwise error(['Unknown flag ''' flag '''.']); end % ------------------------------------------------------------------ function Yd = f(t,Y,G,ME) %计算导数子函数,被"父"函数DYDt3调用。 X=Y(1:2);V=Y(3:4);r=sqrt(sum(X.^2));Yd=[V; -G*ME*X/r^3]; % ------------------------------------------------------------------ function [ts,y0,options] = fi(tspan,Y0) %设置时间区间、初值、算法参数子函数,被"父"函数DYDt3调用。 ts=tspan;y0 = Y0; options = odeset('Events','on','Reltol',1e-5,'Abstol',1e-4); %开动ode45的"事件判断"功能,设置相对误差和绝对误差。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

45

% ------------------------------------------------------------------ function [value,isterminal,direction] = fev(t,Y,Y0) %事件判断子函数,被"父"函数DYDt3调用。 dDSQdt = 2 * ((Y(1:2)-Y0(1:2))' * Y(3:4)); %dDSQdt是离初始点的二乘距离u的时间导数du/dt,而u=(x-x0)^2+(y-y0)^2 。 value = [dDSQdt; dDSQdt]; %定义两个穿越0的事件 direction = [1; -1]; %第一事件:以渐增方式穿越0。第二事件:以渐减方式穿越0 isterminal = [1; 0]; %第一事件发生后,终止计算;而第二事件发生后,继续计算。 (2)运行以下主程序 G=6.672e-11;ME=5.97e24;vy0=4000; x0=-4.2e7;t0=0;tf=60*60*24*9; tspan=[t0,tf];Y0=[x0;0;0;vy0]; [t,YY,Te,Ye,Ie]=ode45('DYDt3',[],[],[],G,ME,tspan,Y0); % <3> X=YY(:,1);Y=YY(:,2); plot(X,Y,'b','Linewidth',2);hold on text(0,6e7,'轨道','Color','b') %产生蓝色文字注释 axis('image'); %保证x、y轴等长刻度,且坐标框恰包容图形 %在三个事件发生点上画标记 plot(Ye(1,1),0.4e7+Ye(1,2),'r^','MarkerSize',10) plot(Ye(2,1),0.4e7+Ye(2,2),'bv','MarkerSize',10) plot(Ye(3,1),-0.4e7+Ye(3,2),'b^','MarkerSize',10) %把轨道的半周期和全周期标在图上 text(0.8*Ye(3,1),-2e7+Ye(3,2),['t3=' sprintf('%6.0f',Te(3))]) text(0.8*Ye(2,1),1.5e7+Ye(2,2),['t2=' sprintf('%6.0f',Te(2))]) %在x-y坐标上画地球 [XE,YE,ZE] = sphere(10);RE=0.64e7;XE=RE*XE;YE=RE*YE;ZE=0*ZE; mesh(XE,YE,ZE) text(1e7,1e7,'地球','Color','r'), hold off %产生红色文字注释

0 5 10 15 20

x 107

-8

-6

-4

-2

0

2

4

6

8

x 107

轨道

t3=489593

t2=244796地 球

图 5.14.2.2-1 带事件标注的卫星轨道图

5.14.3 关于 ODE文件的说明 (1)ODE文件的模板 下面就是 MATLAB的模板文件 odefile.m ,为便于读者阅读,本书作者适当地给以注解说明。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

46

[odefile.m] function varargout = odefile(t,y,flag,p1,p2) % odefile.m 是MATLAB提供的模板文件。用户可根据需要,使用任何其他文件名。 % varargout 是MATLAB专门设计的"变长度"输出宗量。它由元胞数组构成,因此 % 可适应任意多个、任意形式的输出宗量。请参看第8.5.2节。 % t 自变量。不管在下面指令中是否出现,自变量t必须作为第一输入宗量。 % y 一阶微分方程组的列向量形式函数。它必须作为第二输入宗量。 % flag 切换变量。它必须处在第三输入宗量位置。用户无须也不要对它直接赋 % 值;它的赋值由微分方程解算指令(solver),自动产生。 % p1, p2 是被传递的参数。这里,作为示意,仅列出两个。 % 根据需要,传递参数的数目不受限制。 % 以下是switch-case构成的多向选择控制。应注意: % (A)各情况的情况表达式是MATLAB规定的,不得任意改变。 % (B)各情况所执行的任务也是规定的,不得任意改变。 % (C)各情况内,变长输出宗量元胞数是规定的,不得任意改变。 % (D)各情况内,(等式右边的)函数名称可以改变,但相应子函数名称要一致。 % (E)各情况内,(等式右边的)函数中所包含的t , y 是必须的, % 不管它们是否以显式出现相应子函数体中。 % (F)各情况内,(等式右边的)函数中所包含的p1, p2 是传递参数的示意性表示。 % 具体参数视需要而定,只要该参数已经传入odefile.m 函数内存。 switch flag case '' % 规定空字符串 '' 情况:专管一阶导数 dy/dt = f(t,y)的计算 varargout{1} = f(t,y,p1,p2); case 'init' % 规定 'init' 情况:专管三个宗量 [tspan , y0 , options]的设置。 [varargout{1:3}] = init(p1,p2); case 'jacobian' % 规定 'jacobian' 情况:专管计算解析的 Jacobian 矩阵 df/dy。 varargout{1} = jacobian(t,y,p1,p2); case 'jpattern' % 规定 'jpattern' 情况:专管计算稀疏的数值 Jacobian 矩阵 df/dy。 varargout{1} = jpattern(t,y,p1,p2); case 'mass ' % 规定 'mass' 情况:专管计算质量矩阵(mass matrix)。 varargout{1} = mass(t,y,p1,p2); case 'events' % 规定'events'情况:专管事件定义和判断 [varargout{1:3}] = events(t,y,p1,p2); otherwise error(['Unknown flag ''' flag '''.']); end % 以下是odefile.m 的子函数,它们分别与"父"函数中各情况对应。 %--------------------------------------------------------------------------- function dydt = f(t,y,p1,p2) % 空字符串 '' 情况内调用的子函数:专管一阶导数 dy/dt的计算 % dydt 一阶导数。该变量名可由用户按需要取名。 % 下面函数内容,由用户自己编写,最后产生输出dydt 。 dydt =〈由用户编写〉 % --------------------------------------------------------------------------- function [tspan,y0,options] = init(p1,p2) % 'init' 情况内调用的子函数:专管三个宗量 [tspan , y0 , options]的设置。

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

47

% 三个输出宗量的名称可由用户自起,但各位置上宗量的性质不能改变。 % 下面函数内容,由用户自己编写,最后产生输出三个输出 。 tspan =〈积分的时间区段或时间点集〉 y0 =〈初值〉 options =〈或用 odeset 设置算法参数,或用空阵符 [ ] 表示缺省设置〉 % --------------------------------------------------------------------------- function dfdy = jacobian(t,y,p1,p2) % 'jacobian' 情况调用的子函数:专管计算解析的 Jacobian 矩阵 df/dy。 % 输出宗量的名称可由用户自起。 % 下面函数内容,由用户自己编写,最后产生输出输出dfdy 。 dfdy =〈 Jacobian 矩阵〉 % --------------------------------------------------------------------------- function S = jpattern(t,y,p1,p2) % 'jpattern' 情况调用的子函数:专管计算解析的 Jacobian 矩阵 df/dy。 % 输出宗量的名称可由用户自起。 % 下面函数内容,由用户自己编写,最后产生输出S 。 S =〈稀疏形式的数值 Jacobian 矩阵〉 % --------------------------------------------------------------------------- function M = mass(t,y,p1,p2) % 'mass' 情况调用的子函数:专管计算质量矩阵(mass matrix)。解刚性方程时用。 % 输出宗量的名称可由用户自起。 % 下面函数内容,由用户自己编写,最后产生输出M 。 M =〈质量矩阵〉 % -------------------------------------------------------------------------- function [value,isterminal,direction] = events(t,y,p1,p2) % 'events' 情况内调用的子函数:专管三个宗量 [value,isterminal,direction]的设置。 % 三个输出宗量的名称可由用户自起,但各位置上宗量的性质不能改变。 % 下面函数内容,由用户自己编写,最后产生输出三个输出 。 value =〈各元素是标量事件函数,即函数穿越0点为事件〉 direction =〈各元素定义事件函数穿越方式:1为向正穿越0;-1为向负穿越0;0不管方向〉 isterminal =〈各元素定义事件发生后计算是否继续:1为终止计算;0为继续计算〉 % -------------------------------------------------------------------------- (2)ODE模板的使用方法

5.14.4 关于解算指令选项 options的属性设置

5.14.4.1 options的属性域名

5.14.4.2 options属性处理和输出函数使用演示 【*例 5.14.4.2-1】仍以卫星轨道问题为例(原题见例 5.14.2.1-1, 5.14.2.1-2 , 5.14.2.2-1)。本例演示如何通过对 options域的直接设置,借助微分方程解算输出指令,表现解算的中间结

果。具体目标是:画出解向量 [ ] [ ]TyxT vvyxyyyyY == 4321 中由 xvx, 构成

的相平面。相平面的绘制是在微分方程解算中间逐步完成的。 (1)编写 ODE文件 DYDt4.m (在 DYDt3.m 基础上删改而成)

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

48

[DYDt4.m] function varargout=DYDt4(t,Y,flag,G,ME,tspan,Y0) switch flag case '' varargout{1} = f(t,Y,G,ME); case 'init' [varargout{1:3}] = fi(tspan,Y0); otherwise error(['Unknown flag ''' flag '''.']); end % ------------------------------------------------------------------ function Yd = f(t,Y,G,ME) X=Y(1:2);V=Y(3:4);r=sqrt(sum(X.^2));Yd=[V; -G*ME*X/r^3]; % ------------------------------------------------------------------ function [ts,y0,options] = fi(tspan,Y0) ts=tspan;y0 = Y0; % 采用向域直接赋值法,设置options属性。以供与odeset使用方法对照。 options.RelTol=1e-5;options.AbsTol=1e-4; options.OutputFcn='odephas2'; %在积分进程中,绘制相平面图。 options.OutputSel=[1 3];%解向量的第1、3分量分别为相平面图的横、纵坐标量。 (2)编写脚本文件 odeexp4.m [odeexp4.m] %odeexp4.m G=6.672e-11;ME=5.97e24;vy0=4000;x0=-4.2e7;t0=0;tf=60*60*24*9; tspan=[t0,tf];Y0=[x0;0;0;vy0]; % 以下四条指令,为相平面图预置一个坐标轴范围 clf,set(gca,'xlim',[-5 25]*1e7,'ylim',[-3 3]*1e3);%设置适当坐标范围 <5> box on %框形坐标 hold on; %使中间结果绘在同一幅图上 ode45('DYDt4',[],[],[],G,ME,tspan,Y0);hold off (3)在 MATLAB指令窗中运行以下指令,即可在图形窗中见到相平面图的逐步绘制。 shg,odeexp4

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

49

图 5.14.4.2-1 微分方程输出函数相平面图的实时绘制

5.14.5 MATLAB提供的微分方程帮助资源

5.15 稀疏矩阵

5.15.1 稀疏矩阵的存储方式

5.15.2 稀疏矩阵的创建

5.15.2.1 稀疏矩阵创建指令:sparse

5.15.2.2 稀疏带状矩阵创建指令:spdiags

5.15.2.3 外部数据转换为稀疏矩阵的指令:spconvert 【*例 5.15.2.3-1】用两种不同方式创建三对角稀疏矩阵。 n=5;SM1=sparse(1:n,1:n,-2*ones(1,n),n,n,n); SM2=sparse(2:n,1:n-1,ones(1,n-1),n,n,n-1);S1=SM1+SM2+SM2' e=ones(n,1);S2=spdiags([e,-2*e,e],[-1,0,1],n,n),SF=full(S1) S1 = (1,1) -2 (2,1) 1 (1,2) 1 (2,2) -2 (3,2) 1 (2,3) 1 (3,3) -2 (4,3) 1 (3,4) 1 (4,4) -2 (5,4) 1 (4,5) 1 (5,5) -2 S2 = (1,1) -2 (2,1) 1 (1,2) 1 (2,2) -2 (3,2) 1 (2,3) 1 (3,3) -2 (4,3) 1 (3,4) 1 (4,4) -2 (5,4) 1 (4,5) 1 (5,5) -2 SF = -2 1 0 0 0 1 -2 1 0 0 0 1 -2 1 0

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn

50

0 0 1 -2 1 0 0 0 1 -2

5.15.3 稀疏矩阵的运算

5.15.3.1 基本规则

5.15.3.2 常用指令及应用举例 【*例 5.15.3.2-1】全元素矩阵、稀疏矩阵、最小排序稀疏矩阵三角分解所需时间的比较。 clear all,n=200; %给出矩阵的阶数 rand('state',1),randn('state',2) %为重复产生相同的矩阵而设 A=sprandsym(n,0.015,0.1,1); %建立(200*200)随机正定稀疏矩阵。 subplot(1,2,1),spy(A,'b',10),title('Spy plot of matrix A') subplot(1,2,2),d=symmmd(A); %采用最小度排序算法 spy(A(d,d),'b',10),title('Matrix A with Minimun degree ordering'); B=full(A); %给出 A 的全元素形式 % 比较三个矩阵的 cholesky 三角分解的运算时间(相对值) format short e tic, L1=chol(B);t1=toc; %全元素时,cholesky分解的计算时间 tic, L2=chol(A);t2=toc/t1; %稀疏时,cholesky分解的计算时间 tic, L3=chol(A(d,d));t3=toc/t1; %最小度排序时,cholesky分解的计算时间 disp(' 全元素阵 稀疏矩阵 最小排序阵'),disp([1,t2,t3]) 全元素阵 稀疏矩阵 最小排序阵 1.0000e+000 1.8182e-001 0

0 100 200

0

50

100

150

200

nz = 592

Spy plot of matrix A

0 100 200

0

50

100

150

200

nz = 592

Matrix A with Minimun degree ordering

图 5.15.3.2-1 稀疏结构

PDF 文件使用 "pdfFactory Pro" 试用版本创建 www.fineprint.cn