6 Mart 2018 Salı

Logaritma

Giriş
Logaritma bir çok konuya dokunduğu için notlarımı ayrı bir yazıya taşıdım.

Bazı Formüller
Şöyle yaparız.
Log(A * B) = Log(A) + Log(B)
Log(A / B) = Log(A) - Log(B)
Toplama için formül şöyle. la ve lb log(a) ve log(b) sonuçlarını saklayan değişken
log(a + b) = log(a) + log(1 + b/a)
           = log(a) + log(1 + exp(log(b) - log(a)))
           = la + log(1 + exp(lb - la))
Doğal Logartima Nedir?
Doğal logaritma 0'dan büyük değerler için tanımlı. ln (1) = 0 'dır. Döndürdüğü sonuç ise -sonsuz,+ sonsuz aralığındadır. Eksi bir sayının logaritması alınırsa örneğin ln (-2) için invalid input yazar.



Doğal logaritmayı sadece e sayısının üssünü alarak hesaplama yöntemi burada gösterilmiş.
log (x) - Doğal logaritma
log(x) verilen sayının doğal logaritmasını alır. Doğal logaritmada taban yaklaşık 2,718281828 olan e sayısı (Euler sayısı) dır. Genellikle ln (x) ile ifade edilir. Logaritma tabanını değiştirmek için formül şöyle.
Recall the formula for changing the base of logarithm from b to d is
logb(x) = logd(x) / logd(b)
Örnek
Elimizde sadece log(x) varsa aşağıdaki gibi yapılabilir.
#define log2(x) log(x)/log(2)
yani
log2(x) = ln (x) / ln (2)
ya da
log2(x) = log10(x) / log10(2)
Bölme işlemi çarpmaya göre yavaş olduğu için şu optimizasyon da yapılabilir.
log2(x) = (1 / ln  (2)) * ln (x). 
1 / ln (2) sabit sayı olduğu için önceden hesaplanıyor ve hesaplama sadece çarpmaya dönüşüyor. Bu yöntem, işlemcilerin zayıf olduğu gömülü dünyada kullanılıyor.

log (x,n) - N tabanında logaritma
Verilen sayının n tabanında logaritmasını alır.

Örnek
Şöyle yaparız 
private int Log2Ceil(int x)
{
  return (int)Math.Ceiling(Math.Log((double)x, 2));
}
Bu kod ile şu aynıdır. Bu çözüm sayının en yüksek (MSB) kaçıncı bitinin 1 olduğunu bulmaya dayanıyor. Sayıyı 2^N şeklinde düşünürsek sonuç N'inci bitin atandığı bir sayı yani  1 << N olur.
private int Log2Ceil(int n) {
  long bits = BitConverter.DoubleToInt64Bits((double)n);
  return ((int)(bits >> 52) & 0x7ff) - 1022;
}
4 double olarak 0.4 x 10^1 gibi temsil edilecektir. Exponent'i bulmak için 52 biti kaydırıyoruz. Sonra 11 bit ile AND'leyip normalde bias olan 1023 yerine 1022'den çıkarırsak 1 olarak atanmış MSB bitinin indeksini buluruz.

log10 - 10 tabanında logaritma
C++
std::log10 metodu yazısına taşıdım.

10'un katı olacak şekilde yuvarlama
Örnek sayıyı 10'un katı olacak şekilde üste yuvarlar. Şöyle çalışır Log10 ile sayının sağındaki sıfırları sayar ve üste yuvarlar. Daha sonra pow (10) ile üste yuvarlanmış sayı birleşerek 10'un katı bir sayı bulunur.
Math.pow(10, Math.ceil(Math.log10(x)));


Hiç yorum yok:

Yorum Gönder