Source File
zipf.go
Belonging Package
math/rand
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// W.Hormann, G.Derflinger:// "Rejection-Inversion to Generate Variates// from Monotone Discrete Distributions"// http://eeyore.wu-wien.ac.at/papers/96-04-04.wh-der.ps.gzpackage randimport// A Zipf generates Zipf distributed variates.type Zipf struct {r *Randimax float64v float64q float64s float64oneminusQ float64oneminusQinv float64hxm float64hx0minusHxm float64}func ( *Zipf) ( float64) float64 {return math.Exp(.oneminusQ*math.Log(.v+)) * .oneminusQinv}func ( *Zipf) ( float64) float64 {return math.Exp(.oneminusQinv*math.Log(.oneminusQ*)) - .v}// NewZipf returns a Zipf variate generator.// The generator generates values k ∈ [0, imax]// such that P(k) is proportional to (v + k) ** (-s).// Requirements: s > 1 and v >= 1.func ( *Rand, float64, float64, uint64) *Zipf {:= new(Zipf)if <= 1.0 || < 1 {return nil}.r =.imax = float64().v =.q =.oneminusQ = 1.0 - .q.oneminusQinv = 1.0 / .oneminusQ.hxm = .h(.imax + 0.5).hx0minusHxm = .h(0.5) - math.Exp(math.Log(.v)*(-.q)) - .hxm.s = 1 - .hinv(.h(1.5)-math.Exp(-.q*math.Log(.v+1.0)))return}// Uint64 returns a value drawn from the Zipf distribution described// by the Zipf object.func ( *Zipf) () uint64 {if == nil {panic("rand: nil Zipf")}:= 0.0for {:= .r.Float64() // r on [0,1]:= .hxm + *.hx0minusHxm:= .hinv()= math.Floor( + 0.5)if - <= .s {break}if >= .h(+0.5)-math.Exp(-math.Log(+.v)*.q) {break}}return uint64()}