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_errsı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_errkayan noktalı aritmetiğin standart modelini ve ortaya çıkan zve çalışan hataları x_errve y_err.
- Fonksiyonunuzun dönüş değeri de
_errona 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/2birim 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 abir 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 _errdeğişkenleri tanıtırız. Not girişler olduğunu ave xkabul edilir tam olarak, ama biz sadece yanı da değerlerini tekabül geçmek için kullanıcı gerektirebilir a_errve 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_errveya 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, _errterim 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.