ข้อได้เปรียบของ Box-Muller ผ่านวิธี CDF สำหรับการจำลองการแจกแจงแบบปกติ?


15

เพื่อจำลองการแจกแจงแบบปกติจากชุดของตัวแปรเครื่องแบบมีหลายเทคนิค:

  1. อัลกอริธึม Box-Mullerซึ่งหนึ่งตัวอย่างสองชุดอิสระที่เป็นอิสระแตกต่างกันใน(0,1)และแปลงพวกเขาเป็นสองแจกแจงปกติมาตรฐานอิสระผ่าน:

    Z0=2lnU1cos(2πU0)Z1=2lnU1sin(2πU0)
  2. วิธีการ CDFซึ่งหนึ่งสามารถถือเอา cdfให้เท่ากับชุดรูปแบบ: และสืบทอด F ( Z ) = U Z = F - 1 ( U )(F(Z))

    F(Z)=U
    Z=F1(U)

คำถามของฉันคือ: ซึ่งคำนวณได้มีประสิทธิภาพมากขึ้น? ฉันคิดว่ามันเป็นวิธีหลัง - แต่เอกสารส่วนใหญ่ที่ฉันอ่านใช้ Box-Muller - ทำไม

ข้อมูลเพิ่มเติม:

การผกผันของ CDF ปกติรู้และได้รับจาก:

F1(Z)=2erf1(2Z1),Z(0,1).

ดังนั้น:

Z=F1(U)=2erf1(2U1),U(0,1).

1
อะไรคือสิ่งที่ตรงกันข้ามกับ cdf ปกติ? มันไม่สามารถคำนวณเชิงวิเคราะห์ได้เฉพาะในกรณีที่ CDF ดั้งเดิมนั้นประมาณด้วยฟังก์ชันเชิงเส้นเป็นเส้นตรง
Artem Sobolev

ทั้งสองคนนั้นไม่เกี่ยวข้องกันอย่างนั้นเหรอ? ฉันเชื่อว่า Box Muller เป็นกรณีเฉพาะสำหรับการสร้าง 2 รูปแบบ
ttnphns

สวัสดี Barmaley ฉันได้เพิ่มข้อมูลเพิ่มเติมด้านบน Inverse CDF มีนิพจน์ - แต่ต้องคำนวณคำนวณ - ดังนั้นอาจเป็นเพราะเหตุใดกล่อง Muller จึงเป็นที่ต้องการ ฉันสันนิษฐานว่า erf 1จะถูกคำนวณในตารางการค้นหาค่าของบาปและโคไซน์เป็นอย่างไร ดังนั้นไม่ว่าราคาแพงกว่าการคำนวณมากขึ้น? ฉันอาจจะผิด erf1erf1sincosine
2350366

2
มีเวอร์ชั่นของ Box-Muller ที่ไม่มีบาปและโคไซน์
ซีอาน

2
@Dilip สำหรับแอปพลิเคชันที่มีความแม่นยำต่ำมากเช่นคอมพิวเตอร์กราฟิกไซน์และโคไซน์สามารถปรับให้เหมาะสมได้โดยใช้ตารางการค้นหาที่เหมาะสม อย่างไรก็ตามสำหรับแอปพลิเคชันทางสถิติการเพิ่มประสิทธิภาพดังกล่าวไม่เคยใช้ ในท้ายที่สุดมันไม่ได้จริงๆใด ๆ ยากที่จะคำนวณกว่าเข้าสู่ระบบหรือsqrtแต่ในระบบคอมพิวเตอร์ที่ทันสมัยฟังก์ชั่นที่เกี่ยวข้องกับการประถมexp --including ฟังก์ชั่นหนุน - การมีแนวโน้มที่จะได้รับการปรับ ( cosและบันทึกเป็นพื้นฐานกลับคำแนะนำวิธีการเกี่ยวกับอินเทล ชิป 8087!) ในขณะที่ erf ไม่สามารถใช้งานได้หรือได้รับรหัสในระดับที่สูงขึ้น (= ช้าลง) erf1logsqrtexpcoslog
whuber

คำตอบ:


16

จากมุมมองของความน่าจะเป็นล้วน ๆ วิธีการทั้งสองนั้นถูกต้องและเทียบเท่ากัน จากมุมมองอัลกอริทึมการเปรียบเทียบจะต้องพิจารณาทั้งความแม่นยำและค่าใช้จ่ายในการคำนวณ

Box-Muller อาศัยเครื่องกำเนิดไฟฟ้าที่เหมือนกันและมีราคาเท่ากันกับเครื่องกำเนิดไฟฟ้าที่เหมือนกัน ดังที่ได้กล่าวไว้ในความคิดเห็นของฉันคุณสามารถออกไปได้โดยไม่ต้องใช้สายหรือไซน์ถ้าไม่ใช้ลอการิทึม

  • สร้างจนกระทั่งS = U 2 1 + U 2 21
    U1,U2iidU(1,1)
    S=U12+U221
  • รับและกำหนดX1=ZU1Z=2log(S)/S
    X1=ZU1, X2=ZU2

อัลกอรึทึมการกลับตัวแบบทั่วไปต้องการการเรียกใช้ cdf แบบอินเวอร์สเช่นqnorm(runif(N))ใน R ซึ่งอาจมีค่าใช้จ่ายสูงกว่าที่กล่าวมาข้างต้นและที่สำคัญกว่าอาจล้มเหลวในก้อยในแง่ของความแม่นยำเว้นแต่ฟังก์ชันควอนไทด์

หากต้องการติดตามความคิดเห็นที่ทำโดยwhuberการเปรียบเทียบrnorm(N)และqnorm(runif(N))อยู่ในข้อได้เปรียบของ c ผกผันทั้งในเวลาดำเนินการ:

> system.time(qnorm(runif(10^8)))
sutilisateur     système      écoulé
 10.137           0.120      10.251 
> system.time(rnorm(10^8))
utilisateur     système      écoulé
 13.417           0.060      13.472` `

และในแง่ของความพอดีในหาง: ป้อนคำอธิบายรูปภาพที่นี่

ตามความคิดเห็นของ Radford Neal ในบล็อกของฉันฉันต้องการชี้ให้เห็นว่าค่าเริ่มต้นrnormใน R ใช้วิธีการผกผันดังนั้นการเปรียบเทียบข้างต้นสะท้อนให้เห็นถึงอินเทอร์เฟซไม่ใช่วิธีการจำลองเอง! หากต้องการอ้างอิงเอกสาร R บน RNG:

‘normal.kind’ can be ‘"Kinderman-Ramage"’, ‘"Buggy
 Kinderman-Ramage"’ (not for ‘set.seed’), ‘"Ahrens-Dieter"’,
 ‘"Box-Muller"’, ‘"Inversion"’ (the default), or ‘"user-supplied"’.
 (For inversion, see the reference in ‘qnorm’.)  The
 Kinderman-Ramage generator used in versions prior to 1.7.1 (now
 called ‘"Buggy"’) had several approximation errors and should only
 be used for reproduction of old results.  The ‘"Box-Muller"’
 generator is stateful as pairs of normals are generated and
 returned sequentially.  The state is reset whenever it is selected
 (even if it is the current normal generator) and when ‘kind’ is
 changed.

3
logΦ1Φ1X1X2Ui1101

2
R 3.0.2rowSumsSqnorm(runif(N))InverseCDF[NormalDistribution[], #] &

1
ฉันเห็นด้วยqnorm(runif(N))เร็วกว่า 20%rnorm(N)
ซีอาน

3
Φ1sincos

1
สำหรับการเปรียบเทียบโดยใช้ i7-3740QM @ 2.7Ghz และ R 3.12 สำหรับการโทรต่อไปนี้: RNGkind(kind = NULL, normal.kind = 'Inversion');At <- microbenchmark(A <- rnorm(1e5, 0, 1), times = 100L);RNGkind(kind = NULL, normal.kind = 'Box-Muller');Bt <- microbenchmark(B <- rnorm(1e5, 0, 1), times = 100L)ฉันได้รับmean 11.38363 median 11.18718การกลับรายการและmean 13.00401 median 12.48802สำหรับ Box-Muller
Avraham
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.