• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

MATLAB仿真总结

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

MATLAB仿真过程中,编写MATLAB代码的时候犯了很多错误,做了很多蠢事。记录下自己犯错的点点滴滴,并引以为戒。使用MATLAB版本为2014a,以下内容如有不当还请指正。

1. 仿真开始前清理工作区

    工作区存在的变量可能会对脚本运行产生影响,故代码(脚本)开头需要添加如下命令

clc;clear all;close all;

2. 养成良好的变量、函数命名习惯

    MATLAB中有很多内置的常量、函数等。写代码的时候不能够随意命名,以防造成不必要的麻烦。譬如在循环时不应该使用i,j变量,在MATLAB中这多用于表示虚数符号。更多的内容可以参考《MATLAB 编程风格指南》。

3. 测试完成的代码再写出函数形式

    有时候会把相对独立、固定的内容写成一个函数。但往往直接写成函数后是不利于测试的,即使添加断点后进入函数内部查看各变量取值,此时不能够观测到函数之外的变量。因此测试好代码无误再封装成函数是必要的。

4. 浮点数的精度

    举个例子,下面代码运行结果是什么呢?

a=10^-17;b=1;
if(a+b==1)
    fprintf(\'a+b=1\');
else
    fprintf(\'a+b!=1\');
end

    答案应该是输出 a+b=1,虽然很明显这是不成立的,但我们要知道MATLAB不是万能的,其表示的数的精度是有限的。对于精度问题不做具体的讨论,意识到这个问题后,我们必须将理论和时间区分开。

    譬如在做除法的时候,有些变量依理论而言是不为0的,但实际上可能因为运算过程中的精度损失而使得计算结果产生Inf或是NaN,进而导致程序出现偏差。就拿上述例子来说,运行结果表明a+b-b=0。为避免这些情况的发生,必须对程序做相应的处理。在MATLAB中键入

help eps

      This MATLAB function returns the distance from 1.0 to the next largest double-precision number, that is eps = 2^(-52).

    可以在帮助文档内阅读详细描述,在实际代码中运用eps防止出现异常。(由其是在具有循环迭代的代码中更要注意这一点

5. 写好注释,用好发布功能

    我有个脚本试着发布了一下,如这里所示,实际上要好看些。这部分内容可以在帮助-MATLAB-Programming Scripts and Functions-Scripts中找到相关的介绍。个人觉得还是不错的,注释是肯定要写的,既然要写,为何不好好按照格式写呢?

    当然,MATLAB提供的功能还是比较简单的,具体的功能大概也就这些。使用发布功能后代码会运行一遍,之后将结果也添加到发布的文档中去。

%%文档标题
% 具体描述
%
%    有格式文本
%    最后修改日期:2015-03-07
%    软件版本:MATLAB(R) 2014a
%
% *加粗*
%
% # 编号列表
% # 编号列表

%%有标题节
% 

%%
%

6. 用好帮助,更要看清帮助

    为什么很多仿真都用MATLAB?因为MATLAB很强大,很全面,可以做好很多事情。了解其强大功能的一个很好的途径是看其自身的帮助。当然,我想强调的是看清帮助。

    前几天就犯了个错误,sgn是取符号的函数,MATLAB里面有个函数叫做sign实现了这个功能。然后我就用了,没有看清sign(0)=0……然而我希望的结果是sign(0)=1。所以在实际使用过程中还是要看清楚才行。

7. 适时保存运行结果

    有的仿真要跑1天、两天、很多天,而且往往是可以中断的。为了防止电脑死机、断点,适时保存运行结果是必要的。我们可以让程序在命令行窗口实时输出信息以查看代码运行状态,并利用diary将这些信息保存起来。譬如

diary;
fprintf(\'\n-------------------------------\n\');
fprintf(\'Eb/No = %e \n\',Var1);
fprintf(\'总帧数 = %d, \',Var2);
fprintf(\'误帧数 = %d, \',Var3);

    但我还是觉得新建文件自由一些,命令行窗口实时输出信息的格式还是不太好看。譬如我们可以将运行结果采用表格的形式存储起来,之后用readtable读取。

fid = fopen(FILE_NAME,\'at+\');
fprintf(fid,\'日期 %s\n\',datestr(now,\'yyyymmdd\'));
fprintf(fid,\'EbN0\t T_Frame\t E_Frames\t E_Bits\t A_IterNums\t BER\t FER\n\');
fprintf(fid,\'%3.2g\t %5d\t %4d\t \',EbN0_dB(nEbN0),nF,frameError(nEbN0));
fprintf(fid,\'%8d\t %8.6g\t \',bitError(nEbN0),iterNumTotal(nEbN0)/nF);
fprintf(fid,\'%e\t %e\n\',BER(nEbN0),frameError(nEbN0)/nF);  

readtable(FILE_NAME,\'HeaderLines\',1,\'Delimiter\',\'\t\')

    读取的结果大概是这个样子,还是很好看的(虽然歪了……),而且可以轻松获取每列数据。

EbN0    T_Frame    E_Frames    E_Bits    A_IterNums    BER    FER
    ____    _______    ________    ______    __________    ___    ___

    1       1          0           0         27            0      0

8.待续

……


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi自动适应屏幕分辨率的属性发布时间:2022-07-18
下一篇:
DelphiClientDataSet复制记录发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap