2009-12-03 9 views
8

पर वर्दी यादृच्छिक (मोंटे कार्लो) वितरण मुझे अपने पालतू रे-ट्रैसर के लिए यादृच्छिक मूल्य उत्पन्न करने वाले एल्गोरिदम के साथ स्पष्टीकरण की आवश्यकता है।
मैं एक बिंदु से किरणों को उत्सर्जित करता हूं। और मुझे इन किरणों के वितरण में समस्या है: मुझे वितरण होने की आवश्यकता है, लेकिन यह नहीं है ...इकाई क्षेत्र

अब जिस समस्या का सामना करना पड़ रहा है वह यह है कि शुरुआत में वर्दी वितरण मेरे विकृतियों के बाद समान नहीं है परिणामों की जगह।

तो उदाहरण के लिए, मैं ध्रुवीय समन्वय प्रणाली अगर आर और टी कोण उत्पन्न करता हूं। वितरण एक समान नहीं है और यह समान नहीं हो सकता है: प्रत्येक ध्रुव के करीब की जगह भूमध्य रेखा के करीब, कहने के मुकाबले परिणामों की अधिक घनत्व है। कारण स्पष्ट है: मैं बेलनाकार अंतरिक्ष से गोलाकार तक समान रूप से वितरित अंक परिवर्तित करता हूं। और मैं परिणाम विकृत करता हूं। वही समस्या यह है कि अगर मैं घन में यादृच्छिक रूप से उत्पन्न अंक सामान्य करता हूं।

मेरा विचार अब यह है: मैं एक टेट्राहेड्रॉन बनाना चाहता हूं, इसके चरम को सामान्य बनाना चाहता हूं, बीच में बिंदु के साथ प्रत्येक चेहरे (त्रिकोण) को विभाजित करना, इसे सामान्य बनाना और मेरे पास पर्याप्त अंक होने तक दोबारा दोहराएं। फिर मैं इन बिंदुओं को थोड़ा "विकृत" करता हूं। फिर मैं उन्हें फिर से सामान्यीकृत करता हूं। बस।

मैं समझता हूं कि यह विधि शुद्ध गणितीय मोंटे-कार्लो विधि नहीं है, क्योंकि मैं अंतिम चरण को छोड़कर किसी भी चरण में यादृच्छिक वितरण का उपयोग नहीं करता हूं। और मुझे इस जटिलता के लिए इस समाधान को पसंद नहीं है।

अभी तक किसी को अधिक सरल कुछ भी बता सकते हैं अभी भी

  • यादृच्छिक
  • वर्दी
  • तेजी
  • सरल

धन्यवाद!

संपादित करें:
मैं एक तेजी से विधि ही नहीं, सही की जरूरत है। यही कारण है कि मैं मोंटे-कार्लो के बारे में पूछ रहा हूं। प्रदान किए गए उत्तर सही हैं, लेकिन तेज़ नहीं हैं। टेट्राहेड्रॉन के साथ विधि तेज है, लेकिन बहुत "यादृच्छिक" => गलत नहीं है।
मुझे वास्तव में कुछ और उपयुक्त की आवश्यकता है।

उत्तर

9

Here's एक एल्गोरिथ्म आप बेतरतीब ढंग से इकाई क्षेत्र पर वितरित अंक उत्पन्न करने के लिए अनुमति देता है।

1

मैं अगर यह कोई मतलब बिल्कुल भी सुनिश्चित करें कि नहीं कर रहा हूँ, लेकिन यहाँ तुम जाओ:

Uniform Fractional Part: A Simple Fast Method for Generating Continuous Random Variates

+0

आप सही हैं, यह वास्तव में उत्तर नहीं है, लेकिन यह बहुत दिलचस्प है हालांकि। – avp

0

गोलाकार खंडों के लिए आपकी कोण को phi (ध्रुवीय कोण) और cos(theta) (थीटा अजीमुथल कोण के लिए) अपनी सीमाओं के बीच समान रूप से उत्पन्न करें।

छद्म कोड में:

phi = phi_low_limit  + rand()*(phi_high_limit  - phi_low_limit) 
ct = cos(theta_high_limit) + rand()*(cos(theta_low_limit) - cos(theta_high_limit)) 
// The order is inverted here because cos heads down for increasing theta 
theta = arccos(ct) 

यह नियम है कि Jacobian उलटने और उन निर्देशांक की है कि अंतरिक्ष में समान रूप से उत्पन्न कहते हैं की एक विशेष मामला है।

नोट: ध्यान दें कि मैं डेविड नॉर्मन लाइन से फाई और थेटा के लिए विपरीत सम्मेलन का उपयोग कर रहा हूं।

नोट भी: यह वास्तव में सबसे तेज़ तरीका नहीं है, बल्कि एक सामान्य सिद्धांत को दर्शाता है।

1

जब तक कि आप केवल छोटे दृश्यों को रेट्रेस नहीं कर रहे हैं, तो क्या आपका प्रस्तुत समय वास्तव में सैंपल पिकिंग समय का प्रभुत्व होगा? यदि नहीं, तो शायद यह अभी तक अनुकूलन योग्य नहीं है, हालांकि यह अन्य उत्तरों में दी गई समान नमूना तकनीक को पढ़ने और समझने योग्य है।

इसके अलावा, आपके नमूने को नमूना देने वाले किसी भी कार्य के अच्छे अनुमान के उत्पादन के लिए बहुत यादृच्छिक नहीं होना चाहिए। आप Halton sequence जैसे क्वासिरैंडम नंबर अनुक्रम का उपयोग करके जांच करना चाह सकते हैं। आपका tetrahedron उपविभाग विचार बुरा नहीं है। इसका परिणाम अच्छी तरह से वितरित बिंदुओं में होना चाहिए जो अधिकांश दृश्यों के लिए वर्दी छद्म यादृच्छिक नमूने से बेहतर होना चाहिए, हालांकि कुछ परिस्थितियों में भयानक कलाकृतियों का परिणाम हो सकता है।

वैसे भी आपको ompf.org पर फ़ोरम से परामर्श लेना चाहिए। वहाँ पर कुछ सुपर कट्टर raytracing nerds मिला।

+0

अरे, वास्तव में अच्छा लिंक! – avp

+0

मेरा मतलब है, ompf.org =) – avp

5

यहाँ एक जावा कार्यान्वयन मैं अतीत में प्रयोग किया गया है:

public static double[] randomPointOnSphere(Random rnd) 
{ 
    double x, y, z, d2; 
    do { 
     x = rnd.nextGaussian(); 
     y = rnd.nextGaussian(); 
     z = rnd.nextGaussian(); 
     d2 = x*x + y*y + z*z; 
    } while (d2 <= Double.MIN_NORMAL); 
    double s = Math.sqrt(1.0/d2); 
    return new double[] {x*s, y*s, z*s}; 
} 
+0

@DouglasZare अगर 'd2 finnw

+0

ओह, मेरी गलती हो सकती है। –

3

तुम सच में यादृच्छिक वितरण या एक और भी क्षेत्र से अधिक वितरण की ज़रूरत है?

तो मैं जेडसीडब्ल्यू कोणों का सुझाव दूंगा, जो सभी क्षेत्रों में समान रूप से वितरित होते हैं और गणना करने के लिए तेज़ी से वितरित होते हैं। अन्य विधियां द सिडनीऑपरहाउस (सोफ) और प्रतिकृतियां हैं। (repulsion.c के लिए खोजें) प्रतिकृति विधि काफी अच्छी है लेकिन धीमी है: यह एक क्षेत्र में समान रूप से बिंदुओं को समान रूप से वितरित करती है। सौभाग्य से इसे केवल एक बार किया जाना है।

इसका उपयोग क्रिस्टलोग्राफी और एनएमआर में किया जाता है, क्योंकि पाउडर पैटर्न के लिए यह यादृच्छिक वितरण बनाम भी वितरण का उपयोग करना तेज़ है (आपको कम अंक चाहिए)।

Here जेडसीडब्ल्यू के लिए एक पायथन कार्यान्वयन है। इन पेपरों में

अधिक विवरण:

संबंधित मुद्दे