首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Gaussian 2.1的高斯随机数

Gaussian 2.1的高斯随机数
EN

Stack Overflow用户
提问于 2015-12-27 15:25:31
回答 2查看 1.2K关注 0票数 3

我想把一个旧的目标-c项目更新为斯威夫特。我需要生成高斯随机数。在目标-c中,我使用了这样的方法:

代码语言:javascript
运行
复制
double gaussrand()
{
    static double V1, V2, S;
    static int phase = 0;
    double X;

    if(phase == 0) {
        do {
            double U1 = (double)rand() / RAND_MAX;
            double U2 = (double)rand() / RAND_MAX;

            V1 = 2 * U1 - 1;
            V2 = 2 * U2 - 1;
            S = V1 * V1 + V2 * V2;
        } while(S >= 1 || S == 0);

        X = V1 * sqrt(-2 * log(S) / S);
    } else
        X = V2 * sqrt(-2 * log(S) / S);

    phase = 1 - phase;

    return X;
}

然而,这并不能很好地转化为迅速。有谁知道在sfift 2.1中产生高斯随机数的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-12-28 01:12:44

注意,当您定义它时,您希望gaussRand是一个计算属性。Swift中的计算属性不能存储其他属性,因此在Swift版本的Box-Muller转换方法实现示例中,我将计算属性gaussRand封装在一个类中,并将sv2cachedNumberExists作为存储属性保存在同一个类中,从而使第二个调用gaussRand能够返回上一个类中缓存的结果。

代码语言:javascript
运行
复制
class MyRandomGenerator {
    // stored properties
    var s : Double = 0.0
    var v2 : Double = 0.0
    var cachedNumberExists = false

    // (read-only) computed properties
    var gaussRand : Double  {
        var u1, u2, v1, x : Double
        if !cachedNumberExists {
            repeat {
                u1 = Double(arc4random()) / Double(UINT32_MAX)
                u2 = Double(arc4random()) / Double(UINT32_MAX)
                v1 = 2 * u1 - 1;
                v2 = 2 * u2 - 1;
                s = v1 * v1 + v2 * v2;
            } while (s >= 1 || s == 0)
            x = v1 * sqrt(-2 * log(s) / s);
        }
        else {
            x = v2 * sqrt(-2 * log(s) / s);
        }
        cachedNumberExists = !cachedNumberExists
        return x
    }
}

我们断言,我们取得了预期的结果:

代码语言:javascript
运行
复制
// Assert expected results
var myRandomGenerator = MyRandomGenerator()

let numGaussNumbers = 1000
var myGaussArr = [Double](count: numGaussNumbers, repeatedValue: 0.0)
for (i,_) in myGaussArr.enumerate() { myGaussArr[i] = myRandomGenerator.gaussRand }

let myMean = myGaussArr.reduce(0.0, combine: +)/Double(numGaussNumbers) // 0.0.. OK
let myVar = myGaussArr.map { pow(($0 - myMean), 2) }.reduce(0.0, combine: +)/Double(numGaussNumbers) // ~1, O

print("(\(myMean),\(myVar))") // ~(0,1), OK

好的。

票数 5
EN

Stack Overflow用户

发布于 2016-05-05 04:29:34

以下是将Java非常有效的Random.nextGaussian()方法转换为Swift的方法:

代码语言:javascript
运行
复制
private var nextNextGaussian: Double? = {
    srand48(Int(arc4random())) //initialize drand48 buffer at most once
    return nil
}()

func nextGaussian() -> Double {
    if let gaussian = nextNextGaussian {
        nextNextGaussian = nil
        return gaussian
    } else {
        var v1, v2, s: Double

        repeat {
            v1 = 2 * drand48() - 1
            v2 = 2 * drand48() - 1
            s = v1 * v1 + v2 * v2
        } while s >= 1 || s == 0

        let multiplier = sqrt(-2 * log(s)/s)
        nextNextGaussian = v2 * multiplier
        return v1 * multiplier
    }
}

现在,要生成给定均值和标准差的高斯随机数,只需:

代码语言:javascript
运行
复制
let myGaussian = nextGaussian() * myStandardDeviation + myMean
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34481843

复制
相关文章

相似问题

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