स्वर्ण सर्पिल विधि
आपने कहा कि आप काम करने के लिए सुनहरा सर्पिल विधि नहीं प्राप्त कर सकते हैं और यह शर्म की बात है क्योंकि यह वास्तव में, वास्तव में अच्छा है। मैं आपको इसके बारे में पूरी जानकारी देना चाहूंगा ताकि शायद आप समझ सकें कि इसे किस तरह से दूर रखा जा सकता है।
तो यहाँ एक जाली बनाने का एक तेज़, गैर-यादृच्छिक तरीका है जो लगभग सही है; जैसा कि ऊपर चर्चा की गई है, कोई जाली सही नहीं होगी, लेकिन यह काफी अच्छा हो सकता है। यह BendWavy.org पर अन्य तरीकों की तुलना में है, लेकिन यह सिर्फ एक अच्छा और सुंदर लग रहा है और साथ ही सीमा में रिक्ति के बारे में भी गारंटी है।
प्राइमर: यूनिट डिस्क पर सूरजमुखी के सर्पिल
इस एल्गोरिथ्म को समझने के लिए, मैं पहली बार आपको 2 डी सूरजमुखी सर्पिल एल्गोरिथ्म को देखने के लिए आमंत्रित करता हूं। यह इस तथ्य पर आधारित है कि सबसे अपरिमेय संख्या सुनहरा अनुपात है (1 + sqrt(5))/2
और यदि कोई व्यक्ति "केंद्र पर खड़ा हो," पूरे मोड़ का एक सुनहरा अनुपात मोड़ता है, तो उस दिशा में एक और बिंदु उत्सर्जित करता है, "स्वाभाविक रूप से एक का निर्माण करता है" सर्पिल जो, जैसा कि आप अधिक से अधिक संख्या में अंक प्राप्त करते हैं, फिर भी अच्छी तरह से परिभाषित 'बार' होने से इंकार करते हैं जो अंक रेखा पर चलते हैं। (नोट 1।)
डिस्क पर रिक्ति के लिए एल्गोरिथ्म है,
from numpy import pi, cos, sin, sqrt, arange
import matplotlib.pyplot as pp
num_pts = 100
indices = arange(0, num_pts, dtype=float) + 0.5
r = sqrt(indices/num_pts)
theta = pi * (1 + 5**0.5) * indices
pp.scatter(r*cos(theta), r*sin(theta))
pp.show()
और यह ऐसे परिणाम पैदा करता है जो दिखते हैं (n = 100 और n = 1000):
बिंदुओं को रेडियल रूप से फैलाएं
अहम अजीब बात सूत्र है r = sqrt(indices / num_pts)
; मैं उस एक के पास कैसे आया? (नोट 2।)
ठीक है, मैं यहाँ वर्गमूल का उपयोग कर रहा हूँ क्योंकि मैं चाहता हूँ कि ये डिस्क के चारों ओर सम-क्षेत्र रिक्ति हो। यही कारण है कि कह रही है कि बड़े की सीमा में रूप में ही है एन मैं एक छोटे से क्षेत्र चाहते आर ∈ ( आर , आर + डी आर ), Θ ∈ ( θ , θ + d θ ) ने अपने क्षेत्र के लिए आनुपातिक अंकों की संख्या को रोकने के लिए, जो है आर डी आर डी θ । अब यदि हम दिखावा करते हैं कि हम यहां एक यादृच्छिक चर के बारे में बात कर रहे हैं, तो इसकी सीधी व्याख्या यह है कि संयुक्त संभावना घनत्व ( R , Θ ) के लिए केवल cr हैकुछ निरंतर सी के लिए । इकाई डिस्क पर सामान्यीकरण फिर c = 1 / disk को बल देगा ।
अब मैं एक चाल शुरू करता हूँ। यह प्रायिकता सिद्धांत से आता है, जहां इसे प्रतिलोम सीडीएफ के नमूने के रूप में जाना जाता है : मान लीजिए कि आप एक संभाव्यता घनत्व f ( z ) के साथ एक यादृच्छिक चर उत्पन्न करना चाहते थे और आपके पास एक यादृच्छिक चर U ~ यूनिफ़ॉर्म (0, 1) है, जैसे बाहर आता है अधिकांश प्रोग्रामिंग भाषाओं में। आप यह कैसे करते हैं?random()
- सबसे पहले, अपने घनत्व को एक संचयी वितरण फ़ंक्शन या सीडीएफ में बदल दें, जिसे हम एफ ( जेड ) कहेंगे । सीडीएफ, याद रखें, व्युत्पन्न च के साथ 0 से 1 तक एकतरफा बढ़ता है ( जेड ) के ।
- फिर सीडीएफ के व्युत्क्रम फ़ंक्शन F -1 ( z) की गणना करें ) ।
- आप पाएंगे कि Z = F -1 ( U ) लक्ष्य घनत्व के अनुसार वितरित किया गया है। (नोट 3)।
अब सुनहरे अनुपात सर्पिल चाल रिक्त स्थान एक अच्छी तरह से भी पैटर्न में बाहर अंक के लिए θ तो चलो कि बाहर एकीकृत करते हैं; यूनिट डिस्क के लिए हमें F ( r ) = r 2 के साथ छोड़ दिया जाता है । तो उलटा फ़ंक्शन एफ -1 ( यू ) = यू 1/2 है , और इसलिए हम ध्रुवीय निर्देशांक में डिस्क पर यादृच्छिक अंक उत्पन्न करेंगे r = sqrt(random()); theta = 2 * pi * random()
।
अब इस व्युत्क्रम फ़ंक्शन को बेतरतीब ढंग से नमूना लेने के बजाय हम इसे समान रूप से नमूना कर रहे हैं , और वर्दी नमूने के बारे में अच्छी बात यह है कि बड़े एन की सीमा में अंक कैसे फैलते हैं, के बारे में हमारे परिणाम ऐसा व्यवहार करेंगे जैसे हमने यादृच्छिक रूप से नमूना लिया था। यह संयोजन चाल है। इसके बजाय random()
हम उपयोग करते हैं (arange(0, num_pts, dtype=float) + 0.5)/num_pts
, इसलिए, कहते हैं, अगर हम 10 अंक का नमूना चाहते हैं तो वे हैं r = 0.05, 0.15, 0.25, ... 0.95
। हम समान रूप से नमूना आर रिक्ति प्राप्त करने के लिए करते हैं, और हम आउटपुट में भयानक "बार" से बचने के लिए सूरजमुखी की वृद्धि का उपयोग करते हैं।
अब एक गोले पर सूरजमुखी कर रहे हैं
बिंदुओं के साथ गोले को बनाने के लिए हमें जो परिवर्तन करने की आवश्यकता है, उसमें केवल गोलाकार निर्देशांक के लिए ध्रुवीय निर्देशांक को स्विच करना शामिल है। बेशक रेडियल समन्वय इस में प्रवेश नहीं करता है क्योंकि हम एक इकाई क्षेत्र पर हैं। चीजें एक छोटे से अधिक सुसंगत यहाँ रखने के लिए, भले ही मैं एक भौतिक विज्ञानी मैं गणितज्ञों 'निर्देशांकों जहां 0 ≤ इस्तेमाल करेंगे के रूप में प्रशिक्षित किया गया था φ ≤ π है अक्षांश ध्रुव और 0 ≤ से नीचे आ रहा है θ ≤ 2π है देशांतर। तो ऊपर से अंतर यह है कि हम मूल रूप से चर स्थान ले रही हैं आर के साथ φ ।
हमारे क्षेत्र तत्व है, जो था आर डी आर डी θ , अब नहीं-बहुत अधिक जटिल पाप (हो जाता है φ ) घ φ घ θ । तो वर्दी रिक्ति के लिए हमारे संयुक्त घनत्व पाप (है φ ) / 4π। बाहर का घालमेल θ , हम पाते हैं च ( φ ) = पाप ( φ ) / 2, इस प्रकार एफ ( φ -) = (क्योंकि (1 φ / 2))। इस Inverting हम कर सकते हैं कि एक समान यादृच्छिक चर acos कैसा दिखेगा (1 - 2 यू ), लेकिन हम समान रूप से बेतरतीब ढंग से करने के बजाय नमूना है, तो हम बजाय का उपयोग φ कश्मीर = acos (1 - 2 ( k+ 0.5) / एन )। और बाकी एल्गोरिथ्म सिर्फ x, y और z निर्देशांक पर इसे पेश कर रहा है:
from numpy import pi, cos, sin, arccos, arange
import mpl_toolkits.mplot3d
import matplotlib.pyplot as pp
num_pts = 1000
indices = arange(0, num_pts, dtype=float) + 0.5
phi = arccos(1 - 2*indices/num_pts)
theta = pi * (1 + 5**0.5) * indices
x, y, z = cos(theta) * sin(phi), sin(theta) * sin(phi), cos(phi);
pp.figure().add_subplot(111, projection='3d').scatter(x, y, z);
pp.show()
फिर से n = 100 और n = 1000 के परिणाम जैसे दिखते हैं:
आगे का अन्वेषण
मैं मार्टिन रॉबर्ट्स के ब्लॉग पर एक चिल्लाहट देना चाहता था। ध्यान दें कि ऊपर मैंने प्रत्येक सूचकांक में 0.5 जोड़कर अपने सूचकांकों की भरपाई की। यह सिर्फ मुझे दृष्टिगत रूप से आकर्षित कर रहा था, लेकिन यह पता चला है कि ऑफसेट की पसंद बहुत मायने रखती है और अंतराल पर स्थिर नहीं है और इसका मतलब पैकिंग में 8% बेहतर सटीकता प्राप्त कर सकती है यदि इसे सही ढंग से चुना जाए। उसका R 2 अनुक्रम प्राप्त करने का एक तरीका भी होना चाहिएएक क्षेत्र को कवर और यह देखना दिलचस्प होगा कि क्या यह एक अच्छा कवर भी उत्पन्न करता है, शायद जैसा है, लेकिन शायद केवल आधे हिस्से से लिया गया इकाई वर्ग तिरछे या तो काट दिया और एक चक्र पाने के लिए चारों ओर फैला दिया।
टिप्पणियाँ
उन "बार" को एक संख्या के लिए परिमेय सन्निकटन द्वारा बनाया जाता है, और एक संख्या के लिए सर्वश्रेष्ठ परिमेय सन्निकटन इसके निरंतर अंश अभिव्यक्ति से आते हैं, z + 1/(n_1 + 1/(n_2 + 1/(n_3 + ...)))
जहां z
एक पूर्णांक है और n_1, n_2, n_3, ...
सकारात्मक पूर्णांकों का एक परिमित या अनंत अनुक्रम है:
def continued_fraction(r):
while r != 0:
n = floor(r)
yield n
r = 1/(r - n)
चूंकि अंश भाग 1/(...)
हमेशा शून्य और एक के बीच होता है, निरंतर अंश में एक बड़ा पूर्णांक एक विशेष रूप से अच्छे परिमेय सन्निकटन के लिए अनुमति देता है: "100 और 101 के बीच किसी चीज से विभाजित" "1 और 2. के बीच किसी चीज से विभाजित" से बेहतर है। सबसे तर्कहीन संख्या इसलिए एक है जो कि है 1 + 1/(1 + 1/(1 + ...))
और विशेष रूप से अच्छा तर्कसंगत अनुमान नहीं है; एक हल कर सकते हैं φ = 1 + 1 / φ द्वारा के माध्यम से गुणा करके φ सुनहरे अनुपात के लिए सूत्र मिलता है।
उन लोगों के लिए जो NumPy से परिचित नहीं हैं - सभी कार्य "सदिश" हैं, इसलिए यह sqrt(array)
वही है जो अन्य भाषाएं लिखती हैं map(sqrt, array)
। तो यह एक घटक-द्वारा-घटक sqrt
अनुप्रयोग है। एक स्केलर के साथ विभाजन के लिए भी समान है या स्केलर के साथ जोड़ - वे समानांतर में सभी घटकों पर लागू होते हैं।
एक बार जब आप जानते हैं कि यह परिणाम है तो प्रमाण सरल है। यदि आप पूछते हैं कि क्या संभावना है जो z < Z < z + d z है , तो यह वही है जो यह पूछ रहा है कि क्या संभावना है कि z < F -1 ( U ) < z + d z , सभी तीन अभिव्यक्तियों पर F को लागू करें, यह देखते हुए कि यह है एक नीरस रूप से बढ़ता हुआ कार्य, इसलिए F ( z ) < U < F ( z + d z ), F ( z ) + f खोजने के लिए दाहिने हाथ की ओर का विस्तार करें। (z ) d z , और चूंकि U एकसमान है, यह संभावना केवल f ( z ) d z है जैसा कि वादा किया गया है।