Yuvarlama hatanızda iyi bir sınır arıyorsanız, mutlaka kesin hassasiyetli bir kütüphaneye ihtiyacınız yoktur. Bunun yerine çalışan hata analizini kullanabilirsiniz.
İyi bir çevrimiçi referans bulamadım, ancak hepsi Nick Higham'ın "Sayısal Algoritmaların Doğruluğu ve Kararlılığı" kitabının Bölüm 3.3'ünde açıklandı. Fikir oldukça basit:
- Kodunuzu, her satırda tek bir aritmetik işlem için tek bir atamanız olacak şekilde yeniden çarpanlarına ayırın.
- Her değişken için, örneğin
x
, bir sabit atandığında x_err
sıfıra başlatılan bir değişken oluşturun x
.
- Her işlem için, örneğin
z = x * y
, değişken z_err
kayan noktalı aritmetiğin standart modelini ve ortaya çıkan z
ve çalışan hataları x_err
ve y_err
.
- Fonksiyonunuzun dönüş değeri de
_err
ona bağlı bir değere sahip olmalıdır . Bu, toplam yuvarlama hatanızdaki verilere bağlı bir sınırdır.
Zor bölüm 3. adımdır. En basit aritmetik işlemler için aşağıdaki kuralları kullanabilirsiniz:
z = x + y
-> z_err = u*abs(z) + x_err + y_err
z = x - y
-> z_err = u*abs(z) + x_err + y_err
z = x * y
-> z_err = u*abs(z) + x_err*abs(y) + y_err*abs(x)
z = x / y
-> z_err = u*abs(z) + (x_err*abs(y) + y_err*abs(x))/y^2
z = sqrt(x)
-> z_err = u*abs(z) + x_err/(2*abs(z))
u = eps/2
birim yuvarlak nerede . Evet, kuralları +
ve -
aynıdır. Diğer herhangi bir işlem için kurallar, op(x)
uygulanan sonucun Taylor serisi genişletmesi kullanılarak kolayca çıkarılabilir op(x + x_err)
. Veya googling'i deneyebilirsiniz. Ya da Nick Higham'ın kitabını kullanarak.
Örnek olarak, Horner şemasını kullanarak a
bir noktada katsayılardaki bir polinomları değerlendiren aşağıdaki Matlab / Octave kodunu düşünün x
:
function s = horner ( a , x )
s = a(end);
for k=length(a)-1:-1:1
s = a(k) + x*s;
end
İlk adım olarak, iki işlemi şu bölümlere ayırdık s = a(k) + x*s
:
function s = horner ( a , x )
s = a(end);
for k=length(a)-1:-1:1
z = x*s;
s = a(k) + z;
end
Sonra _err
değişkenleri tanıtırız. Not girişler olduğunu a
ve x
kabul edilir tam olarak, ama biz sadece yanı da değerlerini tekabül geçmek için kullanıcı gerektirebilir a_err
ve x_err
:
function [ s , s_err ] = horner ( a , x )
s = a(end);
s_err = 0;
for k=length(a)-1:-1:1
z = x*s;
z_err = ...;
s = a(k) + z;
s_err = ...;
end
Son olarak, hata koşullarını almak için yukarıda açıklanan kuralları uygularız:
function [ s , s_err ] = horner ( a , x )
u = eps/2;
s = a(end);
s_err = 0;
for k=length(a)-1:-1:1
z = x*s;
z_err = u*abs(z) + s_err*abs(x);
s = a(k) + z;
s_err = u*abs(s) + z_err;
end
Hiçbir beri o Not a_err
veya x_err
örneğin, bunlar sıfır olduğu varsayılır, ilgili terimler basitçe hata ifadelerde göz ardı edilir.
Et voilà! Şimdi sonucun yanında verilere bağlı bir hata tahmini döndüren bir Horner şemasına sahibiz (not: bu hata üzerinde bir üst sınırdır ).
Bir yan not olarak, C ++ kullandığınız için, _err
terim boyunca hareket eden kayan nokta değerleri için kendi sınıfınızı oluşturmayı ve bu değerleri yukarıda açıklandığı gibi güncellemek için tüm aritmetik işlemleri aşırı yüklemeyi düşünebilirsiniz . Büyük kodlar için, bu, hesaplama açısından daha az verimli de olsa daha kolay olabilir. Bunu söyledikten sonra, böyle bir sınıfı çevrimiçi bulabilirsiniz. Hızlı bir Google araması bana bu bağlantıyı verdi .
± ux ( 1 ± u ) kayan noktada , yani aralığınız sayının kendisine yuvarlanır.