f(x, y)
Bazı formül uygulayan bir çift kayan nokta sayısı döndürerek sayısal bir işlevi var ve parametrelerin tüm birleşimi için analitik ifadelere karşı doğru olup olmadığını kontrol etmek istiyorum x
ve y
ilgileniyorum. Hesaplanan ve karşılaştırmak için doğru yolu nedir analitik kayan nokta sayıları?
Diyelim ki iki sayı a
ve b
. Şimdiye kadar hem mutlak ( abs(a-b) < eps
) hem de relative ( abs(a-b)/max(abs(a), abs(b)) < eps
) hatalarının eps'den daha az olduğundan emin oldum . Bu şekilde, rakamlar 1e-20 civarında olsa bile sayısal yanlışlıkları yakalayacaktır.
Ancak, bugün bir sorun keşfettim, sayısal değer a
ve analitik değer b
:
In [47]: a
Out[47]: 5.9781943146790832e-322
In [48]: b
Out[48]: 6.0276008792632078e-322
In [50]: abs(a-b)
Out[50]: 4.9406564584124654e-324
In [52]: abs(a-b) / max(a, b)
Out[52]: 0.0081967213114754103
Dolayısıyla mutlak hata [50] (açıkçası) küçüktür, ancak göreli hata [52] büyüktür. Bu yüzden programımda bir hatam olduğunu düşündüm. Hata ayıklayarak , bu sayıların denormal olduğunu fark ettim . Bu nedenle, uygun göreceli karşılaştırmayı yapmak için aşağıdaki rutini yazdım:
real(dp) elemental function rel_error(a, b) result(r)
real(dp), intent(in) :: a, b
real(dp) :: m, d
d = abs(a-b)
m = max(abs(a), abs(b))
if (d < tiny(1._dp)) then
r = 0
else
r = d / m
end if
end function
Nerede tiny(1._dp)
bilgisayarımda 2.22507385850720138E-308 döndürür. Şimdi her şey çalışıyor ve göreceli hata olarak 0 alıyorum ve her şey yolunda. Özellikle, yukarıdaki göreceli hata [52] yanlıştır, basitçe denormal sayıların yetersiz doğruluğundan kaynaklanır. rel_error
Fonksiyonu uygulamam doğru mu? Ben sadece abs(a-b)
küçük (= denormal) daha küçük olup olmadığını kontrol ve 0 döndürmek gerekir? Yoksa diğer kombinasyonları kontrol etmeli miyim
max(abs(a), abs(b))
?
Sadece "uygun" yolun ne olduğunu bilmek istiyorum.
exp(log_gamma(m+0.5_dp) - (m+0.5_dp)*log(t)) / 2
m = 234, t = 2000'dir. Ben arttıkça hızla sıfıra giderm
. Tüm sayısal rutin benim en az 12 önemli basamağa (sıfır dönmek için de gayet iyi) "doğru" sayıları döndürmek emin olmak istiyorum. Hesaplama denormal bir sayı döndürürse, o zaman sadece sıfırdır ve sorun olmamalıdır. Dolayısıyla, sadece karşılaştırma rutininin buna karşı sağlam olması gerekir.