इस GLSL रैंड () वन-लाइनर की उत्पत्ति क्या है?


92

मैंने इस छद्म-यादृच्छिक संख्या जनरेटर को यहाँ और वहाँ वेब के आसपास संदर्भित शेड में उपयोग के लिए देखा है :

float rand(vec2 co){
  return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

इसे विभिन्न रूप से "कैनोनिकल", या "वन-लाइनर मैंने कहीं वेब पर पाया है" कहा जाता है।

इस समारोह का मूल क्या है? क्या निरंतर मूल्य उतने ही मनमाने हैं जितने कि वे लगते हैं या उनके चयन की कुछ कला है? क्या इस समारोह की खूबियों की कोई चर्चा है?

संपादित करें: इस फ़ंक्शन का सबसे पुराना संदर्भ जो मैं भर में आया हूं , वह है फुक '08 से यह संग्रह , जो मूल पृष्ठ अब वेब से चला जा रहा है। लेकिन इसकी कहीं और चर्चा नहीं है।


यह एक शोर समारोह है, जिसका उपयोग प्रक्रियात्मक रूप से उत्पन्न इलाके बनाने के लिए किया जाता है। कुछ इसी तरह की तरह en.wikipedia.org/wiki/Perlin_noise
foreyez

जवाबों:


42

बहुत दिलचस्प सवाल!

मैं उत्तर टाइप करते समय यह जानने की कोशिश कर रहा हूं :) इसके साथ खेलने का पहला आसान तरीका: http://www.wolframalpha.com/input/?i=plot%28+mod%28+sin%28x*12.9898 +% 2 बी + y * 78.233% 29 + * + 43758.5453% 2C1% 29x% 3D0..2% 2C + y% 3D0..2% 29

तो फिर चलो यह सोचते हैं कि हम यहां क्या करने की कोशिश कर रहे हैं: दो इनपुट निर्देशांक x के लिए, y हम एक "यादृच्छिक संख्या" लौटाते हैं। अब यह एक यादृच्छिक संख्या नहीं है। हर बार जब हम एक ही x, y इनपुट करते हैं, तो ऐसा ही होता है। यह एक हैश समारोह है!

पहला काम जो करता है वह है 2d से 1d तक जाना। यह अपने आप में दिलचस्प नहीं है, लेकिन संख्याएं चुनी जाती हैं, इसलिए वे आम तौर पर दोहराते नहीं हैं। इसके अलावा, हम वहाँ एक अस्थायी बिंदु इसके अलावा है। Y या x से कुछ अधिक बिट्स होंगे, लेकिन संख्याओं को सही चुना जा सकता है इसलिए यह एक मिश्रण करता है।

फिर हम एक ब्लैक बॉक्स पाप () फ़ंक्शन का नमूना लेते हैं। यह कार्यान्वयन पर बहुत कुछ निर्भर करेगा!

अंत में यह पाप में त्रुटि को बढ़ाता है (अंश को गुणा करके और लागू करके)।

मुझे नहीं लगता कि यह सामान्य मामले में एक अच्छा हैश फ़ंक्शन है। पापी () GPU पर, संख्यात्मक रूप से एक ब्लैक बॉक्स है। लगभग किसी भी हैश फ़ंक्शन को लेने और इसे परिवर्तित करके बहुत बेहतर निर्माण करना संभव होना चाहिए। हार्ड भाग cpu हैशिंग में प्रयुक्त विशिष्ट पूर्णांक ऑपरेशन को फ्लोट (आधा या 32 बिट) या फिक्स्ड पॉइंट ऑपरेशंस में बदलना है, लेकिन यह संभव होना चाहिए।

फिर, हैश फ़ंक्शन के रूप में इसके साथ वास्तविक समस्या यह है कि पाप () एक ब्लैक बॉक्स है।


1
यह मूल के बारे में सवाल का जवाब नहीं देता है, लेकिन मुझे नहीं लगता कि यह वास्तव में जवाबदेह है। मैं इस उत्तर को चित्रमय ग्राफ के कारण स्वीकार करूँगा।
ग्रुमड्रिग

19

मूल शायद कागज है: "यादृच्छिक संख्या उत्पन्न करने पर, y की मदद से [= (ए + एक्स) पाप (बीएक्स)] मॉड 1", डब्ल्यूजेजे रे, सांख्यिकीविदों की 22 वीं यूरोपीय बैठक और संभाव्यता सिद्धांत और 7 वें विनियस सम्मेलन। गणितीय सांख्यिकी, अगस्त 1998

EDIT: चूँकि मुझे इस पेपर की एक प्रति नहीं मिल रही है और "TestU01" संदर्भ स्पष्ट नहीं हो सकता है, यहाँ इस योजना को छद्म-सी में TestU01 में वर्णित किया गया है:

#define A1 ???
#define A2 ???
#define B1 pi*(sqrt(5.0)-1)/2
#define B2 ???

uint32_t n;   // position in the stream

double next() {
  double t = fract(A1     * sin(B1*n));
  double u = fract((A2+t) * sin(B2*t));
  n++;
  return u;
} 

जहाँ केवल अनुशंसित निरंतर मान B1 है।

ध्यान दें कि यह एक धारा के लिए है। 1D हैश 'एन' में बदलना पूर्णांक ग्रिड बन जाता है। तो मेरा अनुमान है कि किसी ने इसे देखा और 't' को एक साधारण फ़ंक्शन f (x, y) में बदल दिया। उपज के ऊपर मूल स्थिरांक का उपयोग करना:

float hash(vec2 co){
  float t = 12.9898*co.x + 78.233*co.y; 
  return fract((A2+t) * sin(t));  // any B2 is folded into 't' computation
}

3
बहुत दिलचस्प है! मुझे एक ऐसा पेपर मिला, जो Google पुस्तकें पर स्वयं जर्नल के रूप में संदर्भित करता है , लेकिन ऐसा प्रतीत होता है कि टॉक या पेपर स्वयं जर्नल में शामिल नहीं था।
ग्रुमड्रिग

1
इसके अलावा, यह शीर्षक से दिखाई देगा कि मैं जिस फ़ंक्शन के बारे में पूछ रहा हूं वह उस फ़ंक्शन fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * (co.xy + vec2(43758.5453, SOMENUMBER))के अनुरूप होना चाहिए जो पेपर के बारे में है।
ग्रुमड्रिग

एक बात और, अगर यह वास्तव में समारोह के उपयोग का मूल है, जादू संख्या की उत्पत्ति का प्रश्न (की पसंद aऔर b) पर इस्तेमाल किया और अवशेष से अधिक है, लेकिन कागज आप का हवाला देते में इस्तेमाल किया गया हो सकता है।
ग्रुमड्रिग

मुझे अब पेपर भी नहीं मिल रहा है। (संपादित करें: ऊपर बताए अनुसार एक ही पेपर)
एमबी रेनॉल्ड्स

अधिक जानकारी के साथ उत्तर को अपडेट करें।
एमबी रेनॉल्ड्स

8

स्थिर मान मनमाने ढंग से होते हैं, विशेष रूप से यह कि वे बहुत बड़े होते हैं, और कुछ संख्या में दशमलव संख्याएँ अभाज्य संख्याओं से दूर होती हैं।

एक उच्च आयाम साइनस के 4000 से गुणा एक मापांक एक आवधिक कार्य है। यह एक विंडो ब्लाइंड या एक नालीदार धातु की तरह बहुत छोटा है क्योंकि इसे 4000 से गुणा किया जाता है, और डॉट उत्पाद द्वारा एक कोण पर बदल दिया जाता है।

जैसा कि फ़ंक्शन 2-डी है, डॉट उत्पाद में एक्स और वाई अक्ष के सापेक्ष आवधिक फ़ंक्शन को आवधिक मोड़ने का प्रभाव होता है। लगभग 13/79 अनुपात तक। यह अक्षम है, आप वास्तव में (13x + 79y) के साइनस कर के ही इसे प्राप्त कर सकते हैं यह भी वही चीज हासिल करेगा जो मुझे कम गणित के साथ लगता है ।।

यदि आपको एक्स और वाई दोनों में फ़ंक्शन की अवधि मिलती है, तो आप इसे नमूना कर सकते हैं ताकि यह फिर से एक साधारण साइन लहर की तरह दिखाई देगा।

यहाँ यह की एक तस्वीर से ज़ूम इन ग्राफ

मुझे मूल पता नहीं है, लेकिन यह कई अन्य लोगों के समान है, यदि आप इसे नियमित अंतराल पर ग्राफिक्स में इस्तेमाल करते हैं, तो यह मौआ पैटर्न का उत्पादन करेगा और आप देख सकते हैं कि यह अंततः फिर से घूम रहा है।


लेकिन GPUs X और Y की सीमा 0..1 से है और यदि आप अपना ग्राफ बदलते हैं तो यह अधिक यादृच्छिक लगता है। मुझे पता है कि यह एक बयान की तरह लगता है लेकिन यह वास्तव में एक सवाल है, क्योंकि मेरी गणित की शिक्षा 18 साल की उम्र में समाप्त हो गई थी।
स्ट्रिंग्स

मुझे पता है, मैं बस इतना है कि आप देख सकते हैं कि यादृच्छिक कार्य उस रूप का है, सिवाय इसके कि लकीरें बहुत तेजी से बदल रही हैं, सिवाय इसके कि आपको परिवर्तनों को देखने के लिए छोटे से ज़ूम करना होगा ... आप कल्पना कर सकते हैं कि अंक लेना लकीरें पर 1 से 1 x और y मानों के लिए 0 से 1 की ऊँचाई तक बहुत यादृच्छिक संख्याएँ देगा।
एलियनियल

ओह, मैं समझता हूं, और यह किसी भी यादृच्छिक संख्या पीढ़ी के लिए बहुत तर्कसंगत लगता है, जो इसके मूल में एक पाप कार्य का उपयोग करता है
स्ट्रिंग्स

2
यह अनिवार्य रूप से एक रैखिक ज़िगज़ैग है, और पाप को थोड़ा सा बदलाव करना चाहिए, यह वैसा ही है जैसे कि कोई आपके सामने एक कार्ड को 10 से बहुत तेजी से गोल और गोल घुमा रहा हो और आप कोशिश करने वाले हों अंत में कार्डों से संख्याओं का एक पैटर्न चुनें, वे यादृच्छिक संख्याएँ होंगी क्योंकि यह बहुत तेज़ी से फ़्लर्ट कर रहा होगा कि वह केवल कार्ड को गोल-गोल घुमाते हुए एक सटीक तुल्यकालन में कार्ड चुनकर एक पैटर्न प्राप्त कर सकता है।
क्षणिक

बस एक ध्यान दें, यह करने के लिए तेजी से नहीं होगा (13x + 79y), क्योंकि dot(XY, AB)वास्तव में क्या आप अपने डॉट उत्पाद, के रूप में वर्णन है, क्या करेंगे जोx,y dot 13, 79 = (13x + 79y)
whn

1

हो सकता है कि यह कुछ गैर-आवर्तक अराजक मानचित्रण हो, फिर यह कई चीजों की व्याख्या कर सकता है, लेकिन बड़ी संख्या के साथ सिर्फ कुछ मनमाना हेरफेर भी हो सकता है।

संपादित करें: मूल रूप से, फंक्शन फ्रैक्चर (पाप (x) * 43758.5453) एक साधारण हैश जैसा कार्य है, पाप (x) -1 से 1 के बीच सहज पाप प्रक्षेप प्रदान करता है, इसलिए पाप (x) * 43758.5453 से प्रक्षेप होगा - 43758.5453 से 43758.5453। यह एक बहुत बड़ी रेंज है, इसलिए एक्स में छोटा कदम भी परिणाम में बड़ा कदम प्रदान करेगा और आंशिक भाग में वास्तव में बड़ी भिन्नता होगी। "फ्रैक्च" को मान -0.99 ... से 0.999 ... तक प्राप्त करने की आवश्यकता है। अब, जब हमारे पास हैश फ़ंक्शन जैसा कुछ है, तो हमें वेक्टर से उत्पादन हैश के लिए फ़ंक्शन बनाना चाहिए। सबसे सरल तरीका है इनपुट वेक्टर के किसी भी वाई घटक के लिए "हैश" को अलग से कॉल करें। लेकिन फिर, हमारे पास कुछ सममित मूल्य होंगे। तो, हमें वेक्टर से कुछ मूल्य प्राप्त करना चाहिए, दृष्टिकोण कुछ यादृच्छिक वेक्टर ढूंढ रहा है और उस वेक्टर को "डॉट" उत्पाद ढूंढता है, यहां हम जाते हैं: फ्रैक्चर (पाप (डॉट) (co.xy), vec2 (12.9898,78.233))) * 43758.5453); इसके अलावा, चयनित वेक्टर के अनुसार, "डॉट" उत्पाद गणना के बाद "पाप" फ़ंक्शन के कई परिवृत्त होने के लिए इसकी लम्बाई लंबी होनी चाहिए।


लेकिन फिर 4e5 के रूप में अच्छी तरह से काम करना चाहिए, मुझे समझ में नहीं आता कि क्यों जादू नंबर 43758.5453। (इसके अलावा, मैं रैंड (0) = 0 से बचने के लिए कुछ भिन्नात्मक संख्या से x को ऑफ़सेट
करूँगा

1
मुझे लगता है कि 4e5 के साथ आपको भिन्नात्मक बिट्स की इतनी भिन्नता नहीं मिलेगी, यह आपको हमेशा एक ही मूल्य देगा। इसलिए, दो शर्तों को पूरा करना होगा, बड़े पर्याप्त और आंशिक भागों की पर्याप्त अच्छी विविधता होनी चाहिए।
रोमन

आपका क्या मतलब है, "हमेशा आपको एक ही मूल्य देगा"? (यदि आपका मतलब है कि यह हमेशा एक ही अंक लेगा, पहला, वे अभी भी अव्यवस्थित हैं, दूसरा, फ्लोट को m * 2 ^ p के रूप में संग्रहीत किया जाता है, 10 ^ p नहीं, इसलिए * 4e5 अभी भी बिट्स स्क्रैम्बल करता है)।
फेब्रिस NEYRET

मैंने सोचा था कि आपने संख्या का एक घातांक प्रतिनिधित्व लिखा है, 4 * 10 ^ 5, इसलिए पाप (x) * 4e5 आपको इतनी अराजक संख्या नहीं देगा। मैं मानता हूं कि पाप तरंग से भिन्नात्मक बिट्स आपको अच्छी शैतानी देंगे।
रोमन

लेकिन, फिर यह एक्स की सीमा पर निर्भर करता है, मेरा मतलब है कि यदि फ़ंक्शन छोटे (-0.001, 0.001) और बड़े मूल्यों (-1, 1) के लिए मजबूत होना चाहिए। आप फ्रैक्चर (पाप / x / 1000.0) * 43758.5453 के साथ अंतर देखने की कोशिश कर सकते हैं; और फ्रैक्चर (पाप (x / 1000.0) * 4e5) ;, जहां x रेंज में [-1, 1.]। दूसरे संस्करण में छवि अधिक मोनोटोनिक होगी (कम से कम मुझे शेडर में अंतर दिखाई देता है)। लेकिन, सामान्य तौर पर, मैं इस बात से सहमत हूं कि आप अभी भी 4e5 का उपयोग कर सकते हैं और काफी अच्छा परिणाम दे सकते हैं।
रोमन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.