Bölme işleminden kurtulmak için logaritma kullanabilirsiniz. İçin ( x , y) birinci kadran:
z= günlük2( y) - günlük2( x )atan2 ( y, x ) = atanmış ( y/ x)=atanmış( 2z)
Şekil 1. atan ( 2z)
Sen yaklaşık gerekir atan ( 2z) aralığında - 30 < z< 30 1E-9'un sizin gerekli doğruluğu almak için. Atanmış simetriden yararlanabilirsiniz ( 2 - z ) = πatan ( 2- z) = π2- atan ( 2z)veya alternatif olarak( x , y)nin bilinen bir oktantta olduğundan emin olun. günlük2( a )yaklaşmak için:
b=floor(log2(a))c=a2blog2(a)=b+log2(c)
b , en anlamlı sıfır olmayan bitin yerini bularak hesaplanabilir. c , bir bit kaydırma ile hesaplanabilir. 1 ≤ c < 2 aralığındalog2(c) ye yaklaşmanız gerekir.1≤c<2
Şekil 2. Log 2 ( c ) ' nin log2(c)
Doğruluk gereksinimleriniz için, doğrusal enterpolasyon ve düzgün örnekleme için, 0 < z < 30 için 214+1=16385log2(c) örnekleri ve 30×212+1=122881atan(2z) örnekleri yeterli olmalıdır. İkinci tablo oldukça büyük. Bununla birlikte, enterpolasyondan kaynaklanan hata büyük ölçüde z'ye bağlıdır :0<z<30z
Şekil 3. atan(2z) farklı aralıklarını yaklaşım büyük mutlak hata z birim aralığı başına örneklerin farklı sayıda (8192 32) için (yatay eksen) z . 0≤z<1 (atlanmış) için en büyük mutlak hata, floor(log2(z))=0 biraz daha azdır ( log 2 ( z ) ) = 0 .
atan(2z) Tablo tekabül için birden çok subtables yarık olabilir 0≤z<1 ve farklı floor(log2(z)) ile z≥1 hesaplamak kolaydır. Tablo uzunlukları, Şekil 3'te gösterildiği gibi seçilebilir. İç-alt indeks, basit bir bit dizisi manipülasyonu ile hesaplanabilir. Senin doğruluk gereksinimleri için atan(2z) Eğer aralığını uzatmak eğer subtables 29217 numunelerin toplam sahip olacak z için ≤0≤z<32basitlik için z < 32 .
Daha sonra başvurmak için, yaklaşık hataları hesaplamak için kullandığım hantal Python betiği:
from numpy import *
from math import *
N = 10
M = 20
x = array(range(N + 1))/double(N) + 1
y = empty(N + 1, double)
for i in range(N + 1):
y[i] = log(x[i], 2)
maxErr = 0
for i in range(N):
for j in range(M):
a = y[i] + (y[i + 1] - y[i])*j/M
if N*M < 1000:
print str((i*M + j)/double(N*M) + 1) + ' ' + str(a)
b = log((i*M + j)/double(N*M) + 1, 2)
err = abs(a - b)
if err > maxErr:
maxErr = err
print maxErr
y2 = empty(N + 1, double)
for i in range(1, N):
y2[i] = -1.0/16.0*y[i-1] + 9.0/8.0*y[i] - 1.0/16.0*y[i+1]
y2[0] = -1.0/16.0*log(-1.0/N + 1, 2) + 9.0/8.0*y[0] - 1.0/16.0*y[1]
y2[N] = -1.0/16.0*y[N-1] + 9.0/8.0*y[N] - 1.0/16.0*log((N+1.0)/N + 1, 2)
maxErr = 0
for i in range(N):
for j in range(M):
a = y2[i] + (y2[i + 1] - y2[i])*j/M
b = log((i*M + j)/double(N*M) + 1, 2)
if N*M < 1000:
print a
err = abs(a - b)
if err > maxErr:
maxErr = err
print maxErr
y2[0] = 15.0/16.0*y[0] + 1.0/8.0*y[1] - 1.0/16.0*y[2]
y2[N] = -1.0/16.0*y[N - 2] + 1.0/8.0*y[N - 1] + 15.0/16.0*y[N]
maxErr = 0
for i in range(N):
for j in range(M):
a = y2[i] + (y2[i + 1] - y2[i])*j/M
b = log((i*M + j)/double(N*M) + 1, 2)
if N*M < 1000:
print str(a) + ' ' + str(b)
err = abs(a - b)
if err > maxErr:
maxErr = err
print maxErr
P = 32
NN = 13
M = 8
for k in range(NN):
N = 2**k
x = array(range(N*P + 1))/double(N)
y = empty((N*P + 1, NN), double)
maxErr = zeros(P)
for i in range(N*P + 1):
y[i] = atan(2**x[i])
for i in range(N*P):
for j in range(M):
a = y[i] + (y[i + 1] - y[i])*j/M
b = atan(2**((i*M + j)/double(N*M)))
err = abs(a - b)
if (i*M + j > 0 and err > maxErr[int(i/N)]):
maxErr[int(i/N)] = err
print N
for i in range(P):
print str(i) + " " + str(maxErr[i])
Bir fonksiyon yaklaşan yerel maksimum hata f(x) lineer interpolasyon ile f ( x ) numunelerinden f ( x ) , ara örnekleme ile homojen numune alınan Δ X ile analitik olarak yaklaşık olarak hesaplanabilir:f^(x)f(x)Δx
fˆ(x)−f(x)≈(Δx)2limΔx→0f(x)+f(x+Δx)2−f(x+Δx2)(Δx)2=(Δx)2f′′(x)8,
burada , in ikinci türevidir ve , mutlak hatanın yerel maksimumundadır. Yukarıdakilerle yaklaşık değerleri elde ederiz:f′′(x)f(x)x
atanˆ(2z)−atan(2z)≈(Δz)22z(1−4z)ln(2)28(4z+1)2,log2ˆ(a)−log2(a)≈−(Δa)28a2ln(2).
İşlevler içbükey ve örnekler işlevle eşleştiğinden, hata her zaman bir yöndedir. Hatanın işareti her örnekleme aralığında bir kez ileri geri değişmek için yapılırsa, yerel maksimum mutlak hata yarıya indirilebilir. Doğrusal enterpolasyon ile, her tablonun önceden filtrelenmesiyle optimum sonuçlara yakın olarak elde edilebilir:
y[k]=⎧⎩⎨⎪⎪b2x[k−2]c1x[k−1]+b1x[k−1]b0x[k]+c0x[k]+b0x[k]+b1x[k+1]+c1x[k+1]+b2x[k+2]if k=0,if 0<k<N,if k=N,
burada ve orijinaldir ve filtrelenmiş tablo hem hem de ağırlıkları . Uç koşullandırma (yukarıdaki denklemdeki ilk ve son satır), tablonun dışındaki fonksiyon örneklerine kıyasla tablonun uçlarındaki hatayı azaltır, çünkü ilk ve son örneğin enterpolasyondan kaynaklanan hatayı azaltmak için ayarlanması gerekmez ve masanın hemen dışındaki bir örnek arasında. Farklı örnekleme aralıklarına sahip alt tablolar ayrı olarak önceden filtrelenmelidir. ağırlıklarının değerleri, üs arttırmak için sırayla en aza bulunduxy0≤k≤Nc0=98,c1=−116,b0=1516,b1=18,b2=−116c0,c1N yaklaşık hatanın maksimum mutlak değeri:
(Δx)NlimΔx→0(c1f(x−Δx)+c0f(x)+c1f(x+Δx))(1−a)+(c1f(x)+c0f(x+Δx)+c1f(x+2Δx))a−f(x+aΔx)(Δx)N=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪(c0+2c1−1)f(x)01+a−a2−c02(Δx)2f′′(x)if N=0,∣∣∣c1=1−c02if N=1,if N=2,∣∣∣c0=98
örnekler arası enterpolasyon pozisyonları için , içbükey veya dışbükey fonksiyon (örneğin ). Çözülen bu ağırlıklar ile, uç koşullandırma ağırlıklarının maksimum mutlak değerini en aza indirerek bulundu:0≤a<1f(x)f(x)=exb0,b1,b2
(Δx)NlimΔx→0(b0f(x)+b1f(x+Δx)+b2f(x+2Δx))(1−a)+(c1f(x)+c0f(x+Δx)+c1f(x+2Δx))a−f(x+aΔx)(Δx)N=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪(b0+b1+b2−1+a(1−b0−b1−b2))f(x)(a−1)(2b0+b1−2)Δxf′(x)(−12a2+(2316−b0)a+b0−1)(Δx)2f′′(x)if N=0,∣∣∣b2=1−b0−b1if N=1,∣∣∣b1=2−2b0if N=2,∣∣∣b0=1516
için . Yaklaşık ön filtrenin kullanılması yaklaşıklık hatasını yarıya indirir ve tabloların tam optimizasyonundan daha kolaydır.0≤a<1
Şekil 4. 11 numuneden 'nın ön ve filtresiz ve son şartlandırmasız ve sonlandırmasız yaklaşım hatası . Uç koşullandırma olmadan ön filtre, tablonun hemen dışındaki işlevin değerlerine erişebilir.log2(a)
Bu makale muhtemelen çok benzer bir algoritma sunmaktadır: R. Gutierrez, V. Torres ve J. Valls, “ atanan (Y / X) logaritmik dönüşüm ve LUT tabanlı tekniklere dayalı FPGA uygulaması, ” Journal of Systems Architecture , cilt . Özet, uygulamalarının hızda önceki CORDIC tabanlı algoritmaları ve ayak izi boyutunda LUT tabanlı algoritmaları geçtiğini söylüyor.