3.8  MATLAB程序的调试和优化

在MATLAB的程序调试过程中,不仅要求程序能够满足设计者的设计需求,而且还要求程序调试能够优化程序的性能,这样使得程序调试有时比程序设计更为复杂。MATLAB提供了强大的程序调试功能,合理的运用MATLAB提供的程序调试工具尤其重要。本节从MATLAB程序调试的方法和过程开始介绍,先让用户懂得合理运用MATLAB的程序调试功能,再总结MATLAB程序优化的方法,从而达到实现提高程序性能的目的。

3.8.1  MATLAB程序调试方法和过程(1)

MATLAB是一种解释和执行同时进行的语言,这使得程序的调试变得相对便利,尤其是MATLAB具有良好的所见即所得特性。在MATLAB程序调试过程中,可运用的除了一系列调试函数外,MATLAB还提供了专门的调试器,即M文件编译器,通过该M文件编译器和调试函数的共同使用,用户能够完成大部分的程序调试工作。

1.调试的基本任务

程序调试(Debug)的基本任务就是要找到并去除程序中的错误。程序的错误大致可以分为如下三类。

语法错误:由于程序员疏忽、输入不正确等原因而造成的代码违背程序语言规则的错误。

运行错误:由于对所求解问题的理解差异,导致程序流程出错或对程序本身的特性认识有误而造成的程序执行结果错误的情况。

异常:程序执行过程中由于不满足条件而造成的程序执行错误。

语法错误是初学者最常犯的错误,例如,变量或函数名拼写错误、缺少引号或括号等。这类错误对于熟练掌握MATLAB的用户来说很容易避免,并且当MATLAB运行发现这些错误时会立即标识出这些错误,并向用户说明错误的类型以及在M文件中的位置,下面用一个例子来说明,在debug.m文件中输入如下内容:

  A=[  ,  ,  ];                                  %定义矩阵A
B=[ , , , ]; %定义矩阵B
C=A*B %C为矩阵A和B相乘

运行时则会出现如下错误:

  1. ??? Error using ==> mtimes
  2. Inner matrix dimensions must agree.

在上述矩阵四则运算的例子中,矩阵A和矩阵B的维数不满足运算前置条件,即两个矩阵的维数不同不能进行运算。

运行错误也能够被MATLAB发现,但是用户却不知道错误到底发生在何处,也就不能通过查询函数工作区域的方法来查询错误来源,更多时候是MATLAB无法发现运行错误,但是运行结果在验证时出错。这类错误的处理方法多是依靠编程经验解决,下面就求解方程组的例子来进行说明,在命令窗口中输入以下指令:

  1. >> A=[1 2 3;4 5 6;7 8 9];
  2. >>B=[9 8 7;6 5 4;3 2 1];
  3. >>x = B/A                                       %x为矩阵B除以A

运行结果为:

  1. x =
  2. -2.6667         0    1.6667
  3. -2.1667         0    1.1667
  4. -1.6667         0    0.6667

该结果在不同计算机的不同版本的MATLAB下可能不完全相同。为了验证这个结果,在命令窗口中输入如下命令:

  1. >> A*x-B;                               %矩阵A,x和B进行计算
  2. >> norm(A*x-B)                          %返回表达式计算结果的最大奇异值

运算结果为:

  1. ans =
  2. 74.4236

显然x不是A*x=B的解。

说明这就是一个简单的运行错误,MATLAB同样有运行结果,但是进行验证时结果却不正确。原因是在求解A*x=B方程的解时,应该不能用B右除A,而应该是左除,例如,在MATLAB命令窗口输入如下命令:

  1. >> x=A\B

运行结果为:

  1. x =
  2. -27   -26   -17
  3. 42    41    24
  4. -16   -16    -8

验证结果为:

  1. >> A*x-B
  2. ans =
  3. 0     0     0
  4. 0     0     0
  5. 0     0     0
  6. >> norm(A*x-B)
  7. ans =
  8. 0

运行错误通常很难发现,用户在分析问题时要做到非常细心,并且有时需要做必要的验证。

异常的错误往往出现在规模较大的MATLAB程序中,并且涉及多个函数的调研以及数据的调用,异常的种类也很多,例如,被调用的文件不存在、数据传输路径错误、异常的数据输入等。

3.8.1  MATLAB程序调试方法和过程(2)

2.调试工具

MATLAB提供了大量的调试函数供用户使用,这些函数可以通过help指令获得,在MATLAB命令执行窗口输入如下指令:

  1. >> help debug

用户便可获得这些函数,这些函数都有一个特点,就是以"db"开头,具体功能和作用如下:

  1. dbstop     - Set breakpoint                             %设置断点
  2. dbclear    - Remove breakpoint                  %清除断点
  3. dbcont     - Resume execution                       %重新执行
  4. dbdown    - Change local workspace context      %下移本地工作空间内容
  5. dbmex     - Enable MEX-file debugging               %使MEX文件调试有效
  6. dbstack    - List who called whom                   %列出函数调用关系
  7. dbstatus    - List all breakpoints                  %列出所有断点
  8. dbstep     - Execute one or more lines              %单步或多步执行
  9. dbtype     - List M-file with line numbers          %列出M文件
  10. dbup      - Change local workspace context          %上移本地工作空间内容
  11. dbquit     - Quit debug mode                        %退出调试模式

在MATLAB中,这些调试函数都有相应的图形化调试工具,使得程序的调试更加方便、快捷。这些图形化调试工具在MATLAB编译器的"debug"和"Breakpoints"菜单中,以方便调试使用。

3.调试方法

对于简单的MATLAB程序中出现的语法错误,可以采用直接调试法,即直接运行该M文件,MATLAB将直接找出语法错误的类型和出现的地方,根据MATLAB的反馈信息对语法错误进行修改。

当M文件很大或M文件中含有复杂的嵌套时,则需要使用MATLAB调试器来对程序进行调试,即使用MATLAB提供的大量调试函数以及与之相对应的图形化工具。

下面通过一个判断2000年至2010年间的闰年年份的示例来介绍MATLAB调试器的使用方法。

(1)创建一个leapyear.m的M函数文件,并输入如下函数代码程序。

  1. %程序为判断2000年至2010年10年间的闰年年份
  2. %本程序没有输入/输出变量
  3. %函数的使用格式为leapyear,输出结果为2000年至2010年10年间的闰年年份
  4. function leapyear                   %定义函数leapyear
  5. for year=2000:2010              %定义循环区间
  6. sign=1;
  7. a = rem(year,100);            %求year除以100后的剩余数
  8. b = rem(year,4);                  %求year除以4后的剩余数
  9. c = rem(year,400);                %求year除以400后的剩余数
  10. if a =0                             %以下根据a、b、c是否为0对标志变量sign进行处理
  11. signsign=sign-1;
  12. end
  13. if b=0
  14. signsign=sign+1;
  15. end
  16. if c=0
  17. signsign=sign+1;
  18. end
  19. if sign=1
  20. fprintf('%4d \n',year)
  21. end
  22. end

(2)运行以上M程序,此时MATLAB命令窗口会给出如下错误提示:

  1. ??? Error: File: leapyear.m Line: 10 Column: 6
  2. The expression to the left of the equals sign is not a valid target for an assignment.

由错误提示可知,在程序的第10行存在语法错误,检测可知if选择判断语句中,用户将"=="写成了"="。因此将"="改成"==",同时也更改第13、16、19行中的"="为"=="。

3.8.1  MATLAB程序调试方法和过程(3)

(3)程序修改并保存完成后,可直接运行修正后的程序,程序运行结果为:

  1. 2001
  2. 2002
  3. 2003
  4. 2005
  5. 2006
  6. 2007
  7. 2009
  8. 2010

显然,2001年至2010年间不可能每年都是闰年,由此判断程序存在运行错误。

(4)分析原因。可能由于在处理年号是否是100的倍数时,变量sign存在逻辑错误。

(5)断点设置。断点为MATLAB程序执行时人为设置的中断点,程序运行至断点时便自动停止运行,等待用户的下一步操作。设置断点只需要用鼠标单击程序左侧的" "使得" "变成红色的圆点(当存在语法错误时圆点颜色为灰色),如图3.2所示。应该在可能存在逻辑错误或需要显示相关代码执行数据附近设置断点,例如,本例中的12、15和18行。如果用户需要去除断点,可以再次单击红色圆点去除,也可以单击工具栏中的 工具去除所有断点。

(6)运行程序。按"F5"键或单击工具栏中的 按钮执行程序,这时其他调试按钮将被激活。程序运行至第一个断点暂停,在断点右侧则出现向右指向的绿色箭头,如图3.3所示。

 
图3.2  断点标记
 
图3.3  程序运行至断点处暂停

程序调试运行时,在MATLAB的命令窗口中将显示如下内容:

  1. K>>

此时可以输入一些调试指令,更加方便对程序调试的相关中间变量进行查看。

(7)单步调试。可以通过按"F10"键或单击工具栏中相应的单步执行图形按钮,此时程序将一步一步按照用户需求向下执行,如图3.4所示。

(8)查看中间变量。可以将鼠标停留在某个变量上,MATLAB将会自动显示该变量的当前值,也可以在MATLAB的workspace中直接查看所有中间变量的当前值,如图3.5所示。

 
图3.4  程序单步执行
 
图3.5  中间变量查看

3.8.1  MATLAB程序调试方法和过程(4)

(9)修正代码。通过查看中间变量可知,在任何情况下sign的值都是1,此时调整修改代码程序如下所示。

  1. %程序为判断2000年至2010年10年间的闰年年份
  2. %本程序没有输入/输出变量
  3. %函数的使用格式为leapyear,输出结果为2000年至2010年10年间的闰年年份
  4. function leapyear
  5. for year=2000:2010
  6. sign=0;
  7. a = rem(year,400);
  8. b = rem(year,4);
  9. c = rem(year,100);
  10. if a ==0
  11. signsign=sign+1;
  12. end
  13. if b==0
  14. signsign=sign+1;
  15. end
  16. if c==0
  17. signsign=sign-1;
  18. end
  19. if sign==1
  20. fprintf('%4d \n',year)
  21. end
  22. end

按"F5"键再次执行程序,得到的运行结果如下:

  1. 2000
  2. 2004
  3. 2008

分析发现,结果正确,此时程序调试结束。

【matlab】MATLAB程序调试方法和过程的更多相关文章

  1. 嵌入式linux应用程序调试方法

    嵌入式linux应用程序调试方法 四 内存工具 五 C/C++代码覆盖.性能profiling工具 四 内存工具 您肯定不想陷入类似在几千次调用之后发生分配溢出这样的情形. 许多小组花了许许多多时间来 ...

  2. WinCE程序调试方法【转】

    刚刚接触WinCE编程,感觉大部分跟WinForm一样.刚开始的时候,不知道怎么进行断点调试,后来同事告诉我,可以直接连接进行断点调试,一试之下,果然好用,所以拿出来分享一下. 必备工具: Micro ...

  3. linux下的程序调试方法汇总

    搞电子都知道,电路不是焊接出来的,是调试出来的.程序员也一定认同,程序不是写出来的,是调试出来的.那么调试工具就显得尤为重要,linux作为笔者重要的开发平台,在linux中讨论调试工具主要是为那些入 ...

  4. web程序调试方法

    1.火狐浏览器查看链接指向的后台方法(controller方法) f12 进入firebug 点击bug旁边的按钮 即第一排第二个按钮 将鼠标划到想要找的链接 在firebug中显示响应的后台跳转.d ...

  5. Xilinx Zynq ZC-702 开发(02)—— 软件程序调试方法

    1.简介 本教程将指导您使用 SDK 调试应用程序项目,本教程中描述的调试步骤是非常基础的:有关更多信息,请参考 SDK 帮助中的调试任务. 在使用本教程之前,您应该已经创建了一个应用程序项目,并在工 ...

  6. C++和QML混合的QT程序调试方法

    以前调试只是QML或者只是C++的QT程序很简单,断点打上,直接debug按钮一点,喝一口水,自然就停在断点了. 这次遇到C++和QML混合的程序,把CONFIG+=declarative_debug ...

  7. php程序调试方法

    可以参考鸟哥等人写的的"php调试技术手册.pdf" 主要分为内置api调试包括:echo.var_dump.print_f,error_log等 前端浏览器插件辅助调试 开源扩展 ...

  8. 二十四、【开源】EFW框架Winform前端开发之项目结构说明和调试方法

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan ...

  9. Keil 程序调试窗口

    上一讲中我们学习了几种常用的程序调试方法,这一讲中将介绍Keil提供各种窗口如输出窗口.观察窗口.存储器窗口.反汇编窗口.串行窗口等的用途,以及这些窗口的使用方法,并通过实例介绍这些窗口在调试中的使用 ...

随机推荐

  1. transition、animation在macbook air上图片动画边缘抖动

    示例: BUG描述: 最近同事一项目中,产品提出在macbook air上,列表图片放大效果边缘出现抖动现象.在retina屏上没有此问题. 调试过程: 1.单独把结构分离.确定是否由其他元素引起. ...

  2. php用mysql函数出错

    很可能只是因为你忘了装mysql扩展 apt-get install php5-mysql

  3. Packets(模拟 POJ1017)

    Packets Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 47750 Accepted: 16182 Description ...

  4. Poj(1251),Prim字符的最小生成树

    题目链接:http://poj.org/problem?id=1251 字符用%s好了,方便一点. #include <stdio.h> #include <string.h> ...

  5. SELinux深入理解

    ps:今天在远程给服务器配置https的时候,一直乱码,以前做系统的系统第一件事情,就是关闭selinx,今天忘记了,然后就悲剧了... 弄了半天才弄好,镇定思痛,好好的来看下selinux 1. 简 ...

  6. Python多进程编程

    转自:Python多进程编程 阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiproces ...

  7. Ubuntu+Win7双系统grub的修复问题

    最近,在grub引导的Ubuntu+Win7双系统上作业,用的是Ubuntu14.04.2.进行系统更新,更新到一般卡住了,恰好此时在进行grub相关文件的更新,我把机器重启后进入了grub resc ...

  8. jquery总结01-基本概念和选择器

    dom元素和jquery元素的区别 dom元素支持dom元素自带的属性和方法,jquery元素支持jquery元素自带的属性和方法 dom                  var div = doc ...

  9. linux&win7双系统安装

    linux&win7双系统安装 硬盘大小分配方案 按照顺序来建立分区 /swap    4G     ==即交换分区,也是一种文件系统,它的作用是作为Linux的虚拟内存.在Windows下, ...

  10. Oracle新增客户端网络配置使用scott出现错误

    错误一   测试提示用户密码过期 解决方法:使用sys用户登录数据库 sqlplus sys/密码  as sysdba; 修改scott用户密码 alter user scott identifie ...