首先,数据:
orig = reshape([0.0000000000000000 0.3480000000000000 0.7570000000000000 1.3009999999999999 2.8300000000000001 4.7519999999999998 5.2660000000000000 5.8120000000000003 14.3360000000000000 15.3390000000000000 ],[10 1])
change = reshape([0.0000000000000000 0.3480000000000000 0.0000000000000000 0.9530000000000000 1.5290000000000001 1.9219999999999997 0.5140000000000002 0.5460000000000003 0.0000000000000000 9.5270000000000010 ],[10 1])
change = cumsum(change)
orig
是经过秒数的向量。 change
是通过获取orig
的(某些)元素之间的差异而得到的向量。 change
的累积总和有一些元素实际上等于orig
中的对应元素。
但是,由于精度问题:
diff = orig - change
给出
diff =
0
0
0.409
0
0
0
0
0
8.524
-1.77635683940025e-15
似乎如果我运行以下命令:
diff(abs(diff) <= eps(orig)) = 0
然后将条目设置为零,但不是由于精度问题,为零。
我的问题是,这是正确的方法吗?为什么比较<=
而不是<
?声明应该是:
diff(abs(diff) < k*eps(orig)) = 0
某些k > 1
给予一些宽容?如果是这样,如何选择k
?
如果有必要知道change
的{{1}}是如何派生的,则以下替代示例也会显示此行为:
orig
答案 0 :(得分:1)
以下陈述只有在“几乎为零”的情况下才会出现,因为1位是非法的。
abs(diff) <= eps(orig)
1位是一个非常高的精度要求,一个你很可能无法实现的精度。通常,您需要自己定义阈值,例如
abs(diff) <= 1e-12
您还会问如何选择此值。答:我们无法告诉你。它的算法,应用,单位,计算机,具体。
你在计算粒子之间的距离?也许你需要一个更小的容差。你在做经济利润演算?然后1e-12是小数,你肯定不会得到现金。请改用1e-4。或者您使用的算法是否进行数值近似?那你需要更高的容差。您可以使用多少容差,并且将始终是用户选择。
注意:您需要了解用于将此最小阈值设置为正确的类型。 MATLAB使用double
作为默认值,但如果您使用其他类型,则此阈值过于严格。作为替代方案,您可以使用
abs(diff) <= 100*eps(class(diff))
如果您的数据类型未修复/已知。