2013-11-21 73 views
1

我被要求改進我們多年來一直使用的奇異值分解的代碼(它來自Fortran的Numerical Recipes的最新版本),但有人將它改編爲不同的真實類型kind類型。我有一些問題,一個關於精度,關於浮點比較別人,而是先在這裏的一些代碼(僅顯示相關的東西):Fortran遺留代碼

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. 爲了避免明確的.ne.比較,還是應該將它與某個epsilon進行比較,是否可以將scale.ne.0.0換成scale.gt.0.0(因爲它不能是< 0)?
  3. 關於最後一點,選擇上述比較中的ε值優選哪個固有函數tinyepsilon
  4. 如果測試值不等於0可能是正數和負數,那麼(value.gt.eps .or. value.lt.-1.0_R12*eps)是否合理?

感謝您的幫助!

+2

是否可以使用像[lapack](http://www.netlib.org/lapack/)這樣的專用優化庫? – damienfrancois

+1

.gt.0.0的準確度如何高於.ne.0.0?令人驚訝的是,有多少人知道,比較浮游物可能會導致假陽性/陰性,但神奇地認爲不平等會表現得更好或免疫......如果你對.eq有一些愚蠢的棉絨規則。那麼它必須同樣適用於.gt。 –

+1

注意隱式聲明使*參數* R12 *真實*。 – agentp

回答

3

據我所知,

  1. 編譯器應該解決這個問題你,但它可能是更合理的明確聲明它作爲0.0_R12的代碼的未來編輯。它可能會更謹慎地定義real(r12), parameter :: zero = 0.0_r12作爲一個全局變量
  2. 的東西比較稍大機器精度可能會是一個好主意
  3. 我會用epsilontiny
  4. 如果value可能是正面負,使用if(abs(value) > eps) then而不是嘗試比較單個if語句中的兩個值可能是有意義的。

請注意,數值食譜是copyrighted material,即使在修改後,由於此版權,您不允許分發它。最好使用LAPACK或其他一些GPL/BSD許可的線性代數包,而不是那些(古代的&通常很慢)的材料。

+1

沒有理由關心像0這樣的整數值。我會毫不猶豫的完全省略「.0」部分。 –

+1

+1我只是在等待數字食譜的評論;-) –

+0

@VladimirF:同意了,在實踐中我經常忽略小數,但我真的是唯一一個*使用*我的代碼,所以我知道我的意思吧。當你把你的代碼給一個不熟悉該語言的人時,它可能會將這個人看作是一個整數。在這方面,假設未來的用戶/編輯是白癡,可能會更安全。 –