2017-07-14 36 views
1

我試過但是當我鍵入這些翻譯對Cordic wikipedia webpage斯威夫特CORDIC算法給定答案

的MATLAB語言:

print(cordic(beta: Double.pi/9, n: 20)) 
print(cordic(beta: Double.pi/8, n: 20)) 

我得到

[-0.17163433840184755, 0.98516072489744066] 
[-0.17163433840184755, 0.98516072489744066] 

它總是給我一個常數回答。爲什麼?我確定「角度」和「Kvalues」數組是正確計算的。

下面的代碼:

import Foundation 

var angles: [Double] = [] 

for i: Double in stride(from: 0, to: 27, by: 1) { 
    angles.append(atan(pow(2, -i))) 
} 
var Kvalues: [Double] = [] 

for i: Double in stride(from: 0, to: 23, by: 1) { 
    Kvalues.append(1/sqrt(abs(Double(1) + pow(2,-2 * i)))) 
    if i > 0 { 
     Kvalues[Kvalues.count - 1] *= Kvalues[Kvalues.count - 2] 
    } 
} 
func min(_ a: Int, _ b: Int) -> Int { 
    return a > b ? b : a 
} 
func cordic(beta: Double, n: Int) -> [Double] { 
    var beta1 = beta 
    let Kn = Kvalues[min(n, Kvalues.count - 1)] 
    var v: [Double] = [1,0] 
    var poweroftwo: Double = 1 
    var angle = angles[0] 

    for j in 0 ..< n { 
     let sigma: Double = beta < 0 ? -1 : 1 
     let factor: Double = sigma * poweroftwo 
     v = [v[0] - v[1] * factor, v[1] + v[0] * factor] 
     beta1 -= sigma * angle 
     poweroftwo /= 2 
     angle = j + 2 > angles.count ? angle/2 : angles[j + 2] 
    } 
    return [v[0] * Kn, v[1] * Kn] 
} 
print(cordic(beta: Double.pi/9, n: 20)) 
print(cordic(beta: Double.pi/8, n: 20)) 

回答

1

你得到相同的結果不同的輸入,因爲在

let sigma: Double = beta < 0 ? -1 : 1 

beta應該是beta1,這是局部變量是 在循環更新。

但即使在修復後的結果不正確,並且這是由兩個「off-by-one」索引錯誤引起的 。 algorithm description中的數組基於1,Swift數組基於0。所以

let Kn = Kvalues[min(n, Kvalues.count - 1)] 
// should be 
let Kn = Kvalues[min(n-1, Kvalues.count - 1)] 

angle = j + 2 > angles.count ? angle/2 : angles[j + 2] 
// should be 
angle = j + 1 >= angles.count ? angle/2 : angles[j + 1] 

anglesKvalues陣列應i從0被定義多達幷包括 27 RESP。 23.

最後,沒有必要定義自己的min函數,因爲在Swift標準庫中有一個函數。

全部放在一起你的代碼是:

var angles: [Double] = [] 

for i: Double in stride(from: 0, through: 27, by: 1) { 
    angles.append(atan(pow(2, -i))) 
} 
var Kvalues: [Double] = [] 

for i: Double in stride(from: 0, through: 23, by: 1) { 
    Kvalues.append(1/sqrt(abs(Double(1) + pow(2,-2 * i)))) 
    if i > 0 { 
     Kvalues[Kvalues.count - 1] *= Kvalues[Kvalues.count - 2] 
    } 
} 

func cordic(beta: Double, n: Int) -> [Double] { 
    var beta1 = beta 
    let Kn = Kvalues[min(n-1, Kvalues.count - 1)] 
    var v: [Double] = [1,0] 
    var poweroftwo: Double = 1 
    var angle = angles[0] 

    for j in 0 ..< n { 
     let sigma: Double = beta1 < 0 ? -1 : 1 
     let factor: Double = sigma * poweroftwo 
     v = [v[0] - v[1] * factor, v[1] + v[0] * factor] 
     beta1 -= sigma * angle 
     poweroftwo /= 2 
     angle = j + 1 >= angles.count ? angle/2 : angles[j + 1] 
    } 
    return [v[0] * Kn, v[1] * Kn] 
} 

和產生良好的近似值:

print(cordic(beta: Double.pi/9, n: 20)) // [0.93969210812600046, 0.34202155184390554] 
print(cordic(beta: Double.pi/8, n: 20)) // [0.92388022188807306, 0.38268176805806309] 

的精確值是

print(cos(Double.pi/9), sin(Double.pi/9)) // 0.939692620785908 0.342020143325669 
print(cos(Double.pi/8), sin(Double.pi/8)) // 0.923879532511287 0.38268343236509