Matlab中的数值精度问题

前言

最近在做导师给的论文仿真任务。在看完一些相关论文后,还是有了一些思路。但是在用matlab进行实际仿真的时候,才发现我处于一个脑子会了,手还不太会的状况。随着反复折腾取得一定进展后,又进一步发现我可能脑子都没有会。ovo!又才又把公式重新推导了一遍。又开始了新的折腾。

尽管我会用“我有课”、“这学期很多课在结课,任务多”等来当进度缓慢的借口。但是,我自己都觉得很慢了,慢得没脸去实验室跟老师对线那种。因此,本周末打算肝进度。

好在思路逐渐清晰,但是今天上午、下午的仿真结果总是存在一定的状况。有些情形下的结果看一眼就不对劲。Debug也可是真滴累。先是把主函数顺着走了一遍再去检查子函数。再发现都没问题的时候,仿真还是有问题。没办法,只有一个迭代一个迭代的观察。。

没办法,菜鸟的debug过程是这样的。

终于发现问题出现在第一个迭代,却又贯穿整个迭代。让我接着叨叨。疫情期间,呆在宿舍腻了,话多。

问题所在

我的初衷是,对一串数值大小在[0,1]区间的序列进行集合划分。将满足下列表达式\mathbb{N}_i(t)=\left \{ j|-\varepsilon _l\leq x_j(t)-x_i(t)\leq \varepsilon _r \right \}的数值点j成为数值点i的邻近点。集合\mathbb{N}_i(t)成为数值点i的邻近集。

以比如集合元素个数N等于151时,此时的集合X0初始取值为X0=0:1/(N-1):1。即[0,1]上均匀取值。当给定\varepsilon _l\varepsilon _r都等于0.1时,不出意外对于中间0.5附近的数值点,他们的邻近集元素个数应该相等。当我进行排查的时候,却发现两者不等。自己单独拎出来进行逻辑比较才发现,好家伙!出现了如下的问题

百度查了下,早在2011年就有类似的状况。我试了下当时的提问答案,现在还是那样报错。然后问了下老程序员师兄,他说到了C语言中的浮点型数据的精度问题。上图也可以发现,我试着去加个round也无济于事。

问题解决

发现这个问题,我是喜忧参半的。喜的是终于发现了那个操蛋的bug,迷惑的仿真结果问题所在。忧的是,之前做的结果图全部都算错了。在解决过程中,师兄让加个容许误差eps。通常取e^{-16}.最终得到目前没发现错误的正确结果。

原有的代码逻辑if (value>=-\varepsilon _l)&&(dis<=\varepsilon _r) 在加上了容许误差后变为if (value>=-\varepsilon _l-eps)&&(dis<=\varepsilon _r+eps)

当然,在自己查找解决方法的过程中,也有看见说更改matlab变量预设格式的。有兴趣的同学可以试试。

体会

之所以选择在快一年后再写这篇文章,是有点感触:编程过程中逻辑判定挺考虑技巧性的。尽管编程语言中的浮点数精度问题我自己也曾在书上看到过。但可能代码量不够,直到今天才真实地遇到。又着实被摆了一道。好在发现了问题并解决了问题。小记。

另外,分享个另一个学长在朋友圈分享的代码逻辑小技巧。当我们需要对变量逻辑值进行真假判断时,把真值放在==前面。即 if 1==Flag。这样在我们可能存在的输入错误 if Flag=1的情况下,1=Flag能够立马发现错误。

以上~

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值