首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift CORDIC算法给出常数解

Swift CORDIC算法给出常数解
EN

Stack Overflow用户
提问于 2017-07-14 19:27:01
回答 1查看 64关注 0票数 1

我试着在Cordic维基百科网页上翻译MATLAB语言。

但是,当我键入这些内容时:

代码语言:javascript
复制
print(cordic(beta: Double.pi/9, n: 20))
print(cordic(beta: Double.pi/8, n: 20))

我得到了

代码语言:javascript
复制
[-0.17163433840184755, 0.98516072489744066]
[-0.17163433840184755, 0.98516072489744066]

它总是给我一个固定的答案。为什么?我确信“角”和“Kvalue”数组是正确计算的。

下面是代码:

代码语言:javascript
复制
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))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-14 20:07:56

对于不同的输入,您得到相同的结果,因为

代码语言:javascript
复制
let sigma: Double = beta < 0 ? -1 : 1

beta应该是beta1,它是循环中更新的局部变量。

但即使在修正后,结果也是不正确的,这是由两个“一对一”的索引错误造成的。算法描述中的数组是基于1的,Swift数组是基于0的.所以

代码语言:javascript
复制
let Kn = Kvalues[min(n, Kvalues.count - 1)]
// should be
let Kn = Kvalues[min(n-1, Kvalues.count - 1)]

代码语言:javascript
复制
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标准库中有一个函数。

将所有这些放在一起,您的代码将是:

代码语言:javascript
复制
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]
}

这就产生了很好的近似:

代码语言:javascript
复制
print(cordic(beta: Double.pi/9, n: 20)) // [0.93969210812600046, 0.34202155184390554]
print(cordic(beta: Double.pi/8, n: 20)) // [0.92388022188807306, 0.38268176805806309]

确切的值是

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45110321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档