Floating point Fortran遗留代码
我被要求改进我们多年来一直使用的奇异值分解代码(它来自于Fortran可用的Numerical Recipes的最新版本),但有人将其改编为不同的realFloating point Fortran遗留代码,floating-point,fortran,svd,Floating Point,Fortran,Svd,我被要求改进我们多年来一直使用的奇异值分解代码(它来自于Fortran可用的Numerical Recipes的最新版本),但有人将其改编为不同的real类型。我有一些问题,一个是关于精度,另一个是关于浮点比较,但首先这里有一些代码(仅显示相关内容): scale=0.0应该是scale=0.0\u R12,对吗 用scale.ne.0交换scale.gt.0(因为它不可能eps)然后而不是尝试在单个If语句中比较两个值可能是有意义的 请注意,数字配方是,即使在修改后,由于此版权,您也不允许分发
类型。我有一些问题,一个是关于精度,另一个是关于浮点比较,但首先这里有一些代码(仅显示相关内容):
scale=0.0
应该是scale=0.0\u R12
,对吗
用scale.ne.0
交换scale.gt.0
(因为它不可能<0)来避免显式的.ne.
-比较,是可以的,还是应该将它与某个ε进行比较
关于最后一点,在上述比较中,哪一个内在函数tiny
和epsilon
更适合选择epsilon值
如果测试不等于0的值可能为正或负,则(value.gt.eps.或.value.lt.-1.0_R12*eps)
是否为合理条件
谢谢你的帮助 据我所知
编译器应该为您解决这个问题,但是为了将来的代码编辑器,显式地将其声明为0.0r12
可能更合理。将real(r12),parameter::zero=0.0r12
定义为全局变量可能更为谨慎
与稍大一点的机器相比,epsilon可能是个好主意
我会使用epsilon
overtiny
如果value
可以是正数或负数,那么使用If(abs(value)>eps)然后而不是尝试在单个If语句中比较两个值可能是有意义的
请注意,数字配方是,即使在修改后,由于此版权,您也不允许分发它。最好使用或其他GPL/BSD许可的线性代数软件包,而不是那些(古老且通常缓慢的)材料。是否可以选择使用专用的优化库,如?究竟.gt.0.0比.ne.0.0更精确?我很惊讶有这么多人知道比较浮动会导致假阳性/假阴性,但神奇地认为不平等会表现得更好或免疫。。。如果你有一些愚蠢的皮棉规则。然后它必须同样应用于.gt。注意隐式语句使参数R12为实。@george感谢您指出这一点@damienfrancois我对此表示怀疑,我认为团队的其他成员将希望坚持我们多年来一直使用的方法……没有理由关心像0这样的整数值的种类。我会毫不犹豫地完全省略“.0”部分。@VladimirF:同意,实际上我经常在我的值中省略小数点,但实际上我是唯一一个使用代码的人,所以我知道我的意思。当您将代码交给不太熟悉该语言的人时,该人可能会认为它是一个整数。在这方面,假设未来的用户/编辑是#$%^白痴可能更安全一些。@AlexanderVogt:必须这么说。这对于学习如何获取一两个方程式并将其转换为有用的子程序是很有用的,但作者对其设置了如此严格的版权限制,这太糟糕了。谢谢你回答我所有的问题,你确实帮了我很大的忙!
implicit real(kind=selected_real_kind(12)) (a-h,o-z) ! not from Numerical Recipes
parameter R12 = selected_real_kind(12), eps=tiny(1.0_R12) ! not from Numerical Recipes
do i=1,n
scale=0.0
if (i.le.m) then
do k=i,m
scale=scale+abs(a(k,i))
end do
if (scale.ne.0.0) then