我想把一个旧的目标-c项目更新为斯威夫特。我需要生成高斯随机数。在目标-c中,我使用了这样的方法:
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中产生高斯随机数的方法?
发布于 2015-12-28 01:12:44
注意,当您定义它时,您希望gaussRand
是一个计算属性。Swift中的计算属性不能存储其他属性,因此在Swift版本的Box-Muller转换方法实现示例中,我将计算属性gaussRand
封装在一个类中,并将s
、v2
和cachedNumberExists
作为存储属性保存在同一个类中,从而使第二个调用gaussRand
能够返回上一个类中缓存的结果。
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
}
}
我们断言,我们取得了预期的结果:
// 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
好的。
发布于 2016-05-05 04:29:34
以下是将Java非常有效的Random.nextGaussian()
方法转换为Swift的方法:
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
}
}
现在,要生成给定均值和标准差的高斯随机数,只需:
let myGaussian = nextGaussian() * myStandardDeviation + myMean
https://stackoverflow.com/questions/34481843
复制相似问题