24
Context RcppZiggurat Accuracy Speed Summary RcppZiggurat: Faster Random Normal Draws Dr. Dirk Eddelbuettel [email protected] [email protected] @eddelbuettel useR! 2014 UCLA, 1 July 2014 Dirk Eddelbuettel RcppZiggurat

RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary

RcppZiggurat:Faster Random Normal Draws

Dr. Dirk [email protected]

[email protected]@eddelbuettel

useR! 2014UCLA, 1 July 2014

Dirk Eddelbuettel RcppZiggurat

Page 2: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Overview Ziggurat

Outline

1 ContextOverviewZiggurat

Dirk Eddelbuettel RcppZiggurat

Page 3: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Overview Ziggurat

R and RNGs

R has “batteries included”:

Excellent support for random number generationDocumentation isn’t all that easy to find: RNGkindThere are four Normal RNGs in R (and six Uniforms)

Dirk Eddelbuettel RcppZiggurat

Page 4: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Overview Ziggurat

R Normal RNGs

library(microbenchmark)res <- microbenchmark({RNGkind(,"Kinderman-Ramage"); rnorm(1e6)},

{RNGkind(,"Ahrens-Dieter"); rnorm(1e6)},{RNGkind(,"Box-Muller"); rnorm(1e6)},{RNGkind(,"Inversion"); rnorm(1e6)},times=100)

Dirk Eddelbuettel RcppZiggurat

Page 5: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Overview Ziggurat

R Normal RNGs

Time for 100 times 1e6 normal draws

Tim

e in

mse

c

100

200

300

400

AH KR Inv BM

Dirk Eddelbuettel RcppZiggurat

Page 6: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Overview Ziggurat

Marsaglia and Tsang, JSS, 2000

Introduce a very small, very fast generatorJust a few lines of C code (in MACROS)Plus two support functionsBut 32-bit only (which was ok at the time...)

Dirk Eddelbuettel RcppZiggurat

Page 7: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Overview Ziggurat

Marsaglia and Tsang, JSS, 2000

#include <math.h>static unsigned long jz,jsr=123456789;

#define SHR3 (jz=jsr, jsr^=(jsr<<13), jsr^=(jsr>>17), \jsr^=(jsr<<5),jz+jsr)

#define UNI (.5 + (signed) SHR3*.2328306e-9)#define IUNI SHR3

static long hz;static unsigned long iz, kn[128], ke[256];static float wn[128],fn[128], we[256],fe[256];

#define RNOR (hz=SHR3, iz=hz&127, \

(fabs(hz)<kn[iz])? hz*wn[iz] : nfix())

Dirk Eddelbuettel RcppZiggurat

Page 8: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Overview Ziggurat

Leong, Zhang et al, JSS, 2005

Three page note extending ZigguratShow a flaw in the underlying U(0,1) generator SHR3Plugging in KISS, another Marsaglia U(0,1), as fixThis correction is not always used (!!)And is still 32-bit only

Dirk Eddelbuettel RcppZiggurat

Page 9: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Overview Ziggurat

Widely used Open Source generators

Lots of other scripting languages have ZigguratIt is sometimes their defaultGNU GSL has a widely used implementation by VossGNU Gretl borrows from it, as does QuantLib

Dirk Eddelbuettel RcppZiggurat

Page 10: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Base Derived Performance

Outline

2 RcppZigguratBaseDerivedPerformance

Dirk Eddelbuettel RcppZiggurat

Page 11: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Base Derived Performance

Virtual Base Class

#include <cmath>#include <stdint.h> // cstdint needs C++11

namespace Ziggurat {

class Zigg {public:virtual ∼Zigg() {};virtual void setSeed(const uint32_t s)=0;// no getSeed() as GSL has nonevirtual double norm() = 0;

};

}

Dirk Eddelbuettel RcppZiggurat

Page 12: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Base Derived Performance

Our package provides several implementationsOur default Ziggurat class implements LZLLV in 32and 64 bit modeFor comparison, we also have implementations

ZigguratMT of Marsaglia and TsangZigguratLZLLV of Leong, Zhang et al (also the default)ZigguratGSL using the GNU GSL (by linking to GSL)ZigguratGl using the GNU Gretl generator (as anadapted copy)ZigguratQL using the QuantLib generator (as anadapted copy)

Dirk Eddelbuettel RcppZiggurat

Page 13: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Base Derived Performance

Ziggurat RNGs

Time for 100 times 1e6 normal draws

Tim

e in

mse

c

50

100

150

Zigg ZiggGSL ZiggQL ZiggGretl RInv

Dirk Eddelbuettel RcppZiggurat

Page 14: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Standard Test Normal Test Chi-Square Test

Outline

3 AccuracyStandard TestNormal TestChi-Square Test

Dirk Eddelbuettel RcppZiggurat

Page 15: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Standard Test Normal Test Chi-Square Test

Use standard test for any Uniform generator

Invert each Ziggurat draw from N(0,1) to U(0,1)n draws from a U(0,1); compute sum of the n values.Repeat m times to create m sums of uniform RNGs.With n large, the m results converge towardsN(n/2,

√n/12) (Irwin-Hall distribution of sum of

uniformly distributed values).Construct a p-value pi for each of m values using theinverse of the Normal using the known mean andstandard dev. from the Irwin-Hall distribution.With m uniformly distributed values: standard testssuch as Kolmogorov-Smirnow or Wilcoxon can beused to test for departures from uniform.

Dirk Eddelbuettel RcppZiggurat

Page 16: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Standard Test Normal Test Chi-Square Test

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

Ziggurat

x

Fn(

x)

pKS: 0.3597pWil.: 0.3741

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

MT

x

Fn(

x)

pKS: 0pWil.: 0.7583

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

LZLLV

x

Fn(

x)

pKS: 0.3597pWil.: 0.3741

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

GSL

x

Fn(

x)

pKS: 0.6294pWil.: 0.5647

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

QL

x

Fn(

x)

pKS: 0.0435pWil.: 0.0335

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

Gretl

xF

n(x)

pKS: 0.2133pWil.: 0.3365

Standard test results

Draws:5e+09 Repeats: 100 Seed: 123456789 Created at: 2014−06−18 18:59:41 Version: 0.1.2.2

Dirk Eddelbuettel RcppZiggurat

Page 17: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Standard Test Normal Test Chi-Square Test

Suggested new test for N(0,1) generator

n from a N(0,1), then compute sum of the n values.Repeats m times to create m sums of N(0,1) draws.With n large, the m results converge to N(0,

√n).

Construct a p-value pi for each of the m values usingthe inverse of the Normal distribution.With m uniformly distributed values: standard testssuch as Kolmogorov-Smirnow or Wilcoxon can beused to test for departures from uniform.

Dirk Eddelbuettel RcppZiggurat

Page 18: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Standard Test Normal Test Chi-Square Test

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

Ziggurat

x

Fn(

x)

pKS: 0.4365pWil.: 0.4301

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

MT

x

Fn(

x)

pKS: 0pWil.: 0.0399

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

LZLLV

x

Fn(

x)

pKS: 0.4365pWil.: 0.4301

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

GSL

x

Fn(

x)

pKS: 0.4003pWil.: 0.3704

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

QL

x

Fn(

x)

pKS: 0.0378pWil.: 0.0602

0.0 0.2 0.4 0.6 0.8 1.0

0.0

0.4

0.8

Gretl

xF

n(x)

pKS: 0.7187pWil.: 0.5236

Normal test results

Draws:5e+09 Repeats: 100 Seed: 123456789 Created at: 2014−06−18 10:24:03 Version: 0.1.2.2

Dirk Eddelbuettel RcppZiggurat

Page 19: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Standard Test Normal Test Chi-Square Test

Chi-square test by Leong et al

Divide real line into B equally spaced bins such thatno N(0,1) draw should exceed furthest.Follow Leong et al: range from -7 to 7 with 200 bins.Large number of N(0,1) drawn; for each of a counterin the bin corresponding to the draw is increased.After N draws, the empirical distribution is comparedto the theoretical (provided by the correspondingvalue of the Normal density function) using astandard chi2 test.

Dirk Eddelbuettel RcppZiggurat

Page 20: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary Standard Test Normal Test Chi-Square Test

0e+00 4e+09 8e+09

020

040

060

0

Ziggurat

res[, 1]

res[

, i]

0e+00 4e+09 8e+09

020

040

060

0

MT

res[, 1]

res[

, i]

0e+00 4e+09 8e+09

020

040

060

0

LZLLV

res[, 1]

res[

, i]

0e+00 4e+09 8e+09

020

040

060

0

GSL

res[, 1]

res[

, i]

0e+00 4e+09 8e+09

020

040

060

0QL

res[, 1]

res[

, i]

0e+00 4e+09 8e+09

020

040

060

0

Gretl

res[, 1]re

s[, i

]

Chi−square test results

Total draws:1e+10 Bins: 200 Seed: 123456789 Steps: 50 Created at: 2014−06−18 07:03:45 Version: 0.1.2.2

Dirk Eddelbuettel RcppZiggurat

Page 21: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary

Outline

4 Speed

Dirk Eddelbuettel RcppZiggurat

Page 22: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary

Comparison to R, Boost and C++11

We posted an Rcpp Gallery article ’Timing normal RNGs’comparing the Normal RNG generators of R (via Rcpp),Boost and C++.

We can now include the (default) Ziggurat method:

R> print(res[,1:4])test replications elapsed relative

4 zrnorm(n) 500 1.397 1.0003 cxx11Normals(n) 500 4.917 3.5202 boostNormals(n) 500 5.114 3.6611 rcppNormals(n) 500 6.166 4.414R>

Dirk Eddelbuettel RcppZiggurat

Page 23: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary

Outline

5 Summary

Dirk Eddelbuettel RcppZiggurat

Page 24: RcppZiggurat: Faster Random Normal Draws · 2014-07-02 · n draws from a U(0;1); compute sum of the n values. Repeat m times to create m sums of uniform RNGs. With n large, the m

Context RcppZiggurat Accuracy Speed Summary

RcppZiggurat

RcppZiggurat implements updated Zigguratgenerators which now work for 32- and 64-bit OSsSimple use: Include a single header (per generator)Generator is fast, small, tested and has minimal stateThis makes it particularly useful for thread-local usein parallel simulations.Package has been on CRAN for a few months, willget update in the next few weeks.

Dirk Eddelbuettel RcppZiggurat