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 xve yilgileniyorum. Hesaplanan ve karşılaştırmak için doğru yolu nedir analitik kayan nokta sayıları?
Diyelim ki iki sayı ave 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 ave 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_errorFonksiyonu 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)) / 2m = 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.