การใช้ตัวแปรสุ่มแบบเกาส์โดยใช้ตัวแปรสุ่มแบบสุ่ม


11

ฉันกำลังพยายามเขียนฟังก์ชั่น C ++ ที่จะคืนค่าสุ่มแบบเกาส์ตามค่าเฉลี่ยและความแปรปรวน

มีฟังก์ชั่นห้องสมุดrand()ซึ่งจะส่งกลับตัวเลขสุ่มระหว่างและ0 ไม่ได้มีค่าคงที่ แต่มันก็ guarantied ว่ามันจะมีอย่างน้อย2 15 - 1 PDF มันเหมือนกันRAND_MAXRAND_MAX2151

ฉันใช้ทฤษฎีขีด จำกัด กลางเพื่อแปลงrand()ให้เป็นตัวแปรเกาส์เซียน สิ่งที่ฉันทำอย่างแน่นอนคือการโทรหาrand()เวลาที่ผู้ใช้ระบุจากนั้นเพิ่มค่าส่งคืนจากนั้นเลื่อนค่าเฉลี่ยเป็นค่าเฉลี่ยของผู้ใช้ที่ระบุ

Gaussian PDF
ในการวางแผนข้างต้นผมเรียกว่ากำเนิดของฉัน Gaussian สุ่มสำหรับครั้งและความถี่ที่พล็อตของค่าผลตอบแทน อย่างที่คุณเห็นความแปรปรวนของมันนั้นใหญ่มากเนื่องจากมันถูกสร้างขึ้นโดยผลรวมของค่าสุ่มอื่น ๆ มากมาย107

มันจะส่งกลับตัวแปร Gaussian ที่ประสบความสำเร็จด้วย Gaussian PDF และค่าเฉลี่ยที่ระบุ อย่างไรก็ตามปัญหาคือความแปรปรวน ฉันติดอยู่ที่จุดนี้เพราะฉันไม่รู้วิธีเปลี่ยนความแปรปรวนเป็นค่าที่ผู้ใช้ระบุ

นี่คือรหัสของฉัน (ไม่สมบูรณ์ในตอนนี้ระบบจะละเว้นพารามิเตอร์ "Variance"):

template <class T>
T Random::GetGaussian(T Mean /*= 0*/, T Variance /*= 1*/)
{
    T MeanOfSum = NUM_GAUSSIAN_SUMS / static_cast<T>(2);
    T Rand = 0;
    for (uint64_t i=0; i<NUM_GAUSSIAN_SUMS; i++)
    {
        Rand += static_cast<T>(rand()) / RAND_MAX;
    }
    return Rand - (MeanOfSum - Mean);
}

สมมติว่าNUM_GAUSSIAN_SUMSเป็น 100 และRAND_MAX32767

ฉันต้องการเปลี่ยนความแปรปรวนของตัวแปรสุ่มตามพารามิเตอร์ของฟังก์ชัน คำถามของฉันคือฉันจะเปลี่ยนความแปรปรวนของตัวแปรสุ่มนี้ได้อย่างไร ฉันจะทำมันได้อย่างไร


3
มีวิธีที่ดีกว่าและเร็วกว่าทฤษฎีบทขีด จำกัด กลางสำหรับการสร้างตัวแปรสุ่มแบบเกาส์ ค้นหาวิธี Box-Muller สำหรับหนึ่ง; วิธี ziggurat นั้นดีกว่า
Dilip Sarwate


3
12 U(0,1)1006N(0,1)Y=σX+μN(μ,σ2)(μ6σ,μ+6σ)

@DilipSarwate บางทีคุณควรโพสต์ทางเลือกเหล่านั้นเป็นคำตอบพร้อมเหตุผลว่าทำไมเราถึงต้องการมัน
Ivo Flipse

@IvoFlipse คำตอบสำหรับคำถามที่ถามว่า "ฉันจะแก้ไขความแปรปรวนได้อย่างไรหลังจากฉันแก้ไขค่าเฉลี่ยแล้ว" โดยพื้นฐานแล้วสิ่งที่คำตอบที่ฮิลมาร์ยอมรับนั้นได้รับการแก้ไขตามความคิดเห็น: แก้ไขความแปรปรวนโดยการปรับขนาดแล้วแก้ไขค่าเฉลี่ยหรือดีกว่ายังไม่เริ่มโดยการแก้ไขค่าเฉลี่ยก่อนเพราะคุณจะต้องแก้ไขอีกครั้ง มันในภายหลัง; แก้ไขความแปรปรวนก่อนโดยปรับขนาดแล้วแก้ไขค่าเฉลี่ย OP ไม่ได้ระบุว่าเขา / เธอสนใจวิธีการที่ดีกว่าและยังไม่ได้อัปเดตลิงก์ของ nibot ซึ่งแม้แต่มีรหัสสำหรับวิธี Box-Muller ดังนั้นฉันจะทิ้งสิ่งต่าง ๆ ตามที่เป็นอยู่
Dilip Sarwate

คำตอบ:


6

อัลกอริทึมเริ่มต้นของคุณสร้างตัวแปรสุ่มที่กระจายอย่างสม่ำเสมอระหว่าง 0 และ 1 ความแปรปรวนของนั่นคือ 1/12 หากคุณสรุปกรณีที่แปรปรวนจะเป็นNUM_GAUSSIAN_SUMS NUM_GAUSSIAN_SUMS/12เพื่อที่จะได้รับการแปรปรวนเป้าหมายคุณจะต้องคูณตัวแปรสุ่มสรุปด้วยVsqrt(V*12/NUM_GAUSSIAN_SUMS)

เทมเพลตจะทำงานได้ดีพอสมควรสำหรับการลอยตัวและเป็นสองเท่า แต่จะมีปัญหาเชิงตัวเลขที่สำคัญกับประเภทจุดคงที่


5

ฉันจะเปลี่ยนความแปรปรวนของตัวแปรสุ่มนี้ได้อย่างไร

cXcXc2X


cXcX

1
จัดตำแหน่งกลางกู้ชีพแล้วเรียกคืนค่าเฉลี่ย การปรับตัวแปรสุ่มแบบกึ่งกลางจะไม่ส่งผลต่อค่าเฉลี่ย (ศูนย์)
Emre

1

ยังมีอีกวิธีหนึ่ง!

ลองคิดดูสิถ้าคุณต้องการการกระจายแบบอื่นที่ไม่ใช่แบบเกาส์เซียนล่ะ ในกรณีนี้คุณไม่สามารถใช้ทฤษฎีขีด จำกัด กลางได้ แล้วคุณจะแก้มันอย่างไร

มีวิธีการแปลงชุดสุ่มตัวแปรเป็น PDF โดยพลการ วิธีนี้เรียกว่าวิธีการแปลงผกผัน

ยู[0-1]

X=FX-1(ยู)

FX(x)

ดังนั้นสิ่งที่คุณต้องทำคือใช้ฟังก์ชั่น inverse CDF กับตัวแปรที่คุณได้รับจากตัวอย่างของ rv

นอกจากนี้ยังแตกต่างจากวิธีการก่อนหน้านี้ซึ่งไม่จำเป็นต้องใช้การวนซ้ำใด ๆ และจะไม่ขึ้นอยู่กับว่าจะใช้การวนซ้ำจำนวนเท่าใดเพื่อให้ผลลัพธ์ใกล้เคียงกับเกาส์เซียน

นี่คือหนึ่งในข้อมูลอ้างอิงที่ให้หลักฐานการนี้


3
> ยังมีอีกวิธีหนึ่ง! จริง แต่ไม่เกี่ยวข้องกับคำถามที่อยู่ระหว่างการพิจารณาซึ่งมีเฉพาะเกี่ยวกับตัวแปรสุ่มแบบเกาส์ CDF แบบเกาส์เซียนหรือแบบผกผันไม่สามารถแสดงในรูปแบบเบื้องต้นโดยใช้จำนวนการดำเนินการที่ จำกัด ดังนั้นจึงไม่สามารถใช้วิธีการที่แนะนำได้
Dilip Sarwate
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.