Fortran遗留代码

时间:2013-11-21 16:42:36

标签: floating-point fortran svd

我被要求改进我们多年来一直使用的奇异值分解代码(它来自Numerical Recipes的可用于Fortran的最后一版),但有人将其改编为不同的真实kind类型。我有一些问题,一个关于精度,另一个关于浮点比较,但首先是一些代码(仅显示相关内容):

  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 
  1. scale=0.0应为scale=0.0_R12,对吧?
  2. scale.ne.0.0替换为scale.gt.0.0(因为它不能<0)以避免显式.ne. - 比较,或者我应该将其与某些epsilon进行比较是否可以代替?
  3. 关于最后一点,哪个内在函数tinyepsilon更适合在上述比较中选择epsilon值?
  4. 如果测试的值不等于0可能既是正面也是负面,那么(value.gt.eps .or. value.lt.-1.0_R12*eps)会是一个明智的条件吗?
  5. 感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

据我所知,

  1. 编译器应该为您解决这个问题,但是对于代码的未来编辑器,明确地将其声明为0.0_R12可能更合理。将real(r12), parameter :: zero = 0.0_r12定义为全局变量
  2. 可能更为谨慎
  3. 比较稍微大一点的机器epsilon可能是个好主意
  4. 我会epsilon使用tiny
  5. 如果value可能是肯定的否定,那么使用if(abs(value) > eps) then可能是有意义的,而不是尝试在单个if语句中比较两个值。< / LI>

    请注意,数字食谱是copyrighted material,即使在修改后,由于此版权,您也不允许分发它。最好使用LAPACK或其他一些GPL / BSD许可的线性代数包,而不是那种(古老和通常很慢)的材料。