स्पष्ट यूलर विधि प्रतिक्रिया-प्रसार की समस्या के लिए बहुत धीमी है


10

मैं C ++ कोड के साथ ट्यूरिंग की प्रतिक्रिया-प्रसार प्रणाली को हल कर रहा हूं। यह बहुत धीमा है: 128x128 पिक्सेल बनावट के लिए, पुनरावृत्तियों की स्वीकार्य संख्या 200 है - जिसके परिणामस्वरूप 2.5 सेकंड की देरी होती है। मुझे दिलचस्प छवि प्राप्त करने के लिए 400 पुनरावृत्तियों की आवश्यकता है - लेकिन प्रतीक्षा के 5 सेकंड बहुत अधिक हैं। इसके अलावा, बनावट का आकार वास्तव में 512x512 होना चाहिए - लेकिन इसके परिणामस्वरूप बहुत इंतजार करना पड़ता है। उपकरण iPad, iPod हैं।

क्या इसे तेजी से करने का कोई मौका है? यूलर विधि धीरे-धीरे (विकिपीडिया) में परिवर्तित हो जाती है - जल्दी विधि होने से पुनरावृत्तियों की संख्या को छोड़ने की अनुमति होगी?

EDIT: जैसा कि थॉमस क्लिंपेल ने बताया, "अगर (m_An [i] [j] <0.0) {...}", "if (m_Bn [i] [j] <0.0) {...}" अभिसरण में देरी कर रहे हैं: हटाने के बाद, 75 पुनरावृत्तियों के बाद सार्थक छवि दिखाई देती है । मैंने नीचे कोड में लाइनें लिखी हैं।

void TuringSystem::solve( int iterations, double CA, double CB ) {
    m_iterations = iterations;
    m_CA = CA;
    m_CB = CB;

    solveProcess();
}

void set_torus( int & x_plus1, int & x_minus1, int x, int size ) {
    // Wrap "edges"
    x_plus1 = x+1;
    x_minus1 = x-1;
    if( x == size - 1 ) { x_plus1 = 0; }
    if( x == 0 ) { x_minus1 = size - 1; }
}

void TuringSystem::solveProcess() {
    int n, i, j, i_add1, i_sub1, j_add1, j_sub1;
    double DiA, ReA, DiB, ReB;

    // uses Euler's method to solve the diff eqns
    for( n=0; n < m_iterations; ++n ) {
        for( i=0; i < m_height; ++i ) {
            set_torus(i_add1, i_sub1, i, m_height);

            for( j=0; j < m_width; ++j ) {
                set_torus(j_add1, j_sub1, j, m_width);

                // Component A
                DiA = m_CA * ( m_Ao[i_add1][j] - 2.0 * m_Ao[i][j] + m_Ao[i_sub1][j]   +   m_Ao[i][j_add1] - 2.0 * m_Ao[i][j] + m_Ao[i][j_sub1] );
                ReA = m_Ao[i][j] * m_Bo[i][j] - m_Ao[i][j] - 12.0;
                m_An[i][j] = m_Ao[i][j] + 0.01 * (ReA + DiA);
                // if( m_An[i][j] < 0.0 ) { m_An[i][j] = 0.0; }

                // Component B
                DiB = m_CB * ( m_Bo[i_add1][j] - 2.0 * m_Bo[i][j] + m_Bo[i_sub1][j]   +   m_Bo[i][j_add1] - 2.0 * m_Bo[i][j] + m_Bo[i][j_sub1] );
                ReB = 16.0 - m_Ao[i][j] * m_Bo[i][j];
                m_Bn[i][j] = m_Bo[i][j] + 0.01 * (ReB + DiB);
                // if( m_Bn[i][j] < 0.0 ) { m_Bn[i][j]=0.0; }
            }
        }

        // Swap Ao for An, Bo for Bn
        swapBuffers();
    }
}

इसके अलावा, मैं यह उल्लेख करना चाहता हूं कि यह पसंद किया जाता है कि आप प्रश्नों को क्रॉस-पोस्ट न करें, क्योंकि ऐसा प्रतीत होता है कि आपने यहां और यहां दोनों ही समान प्रश्न पूछे हैं
गोड्रिक सीर

क्या आपने पहले से ही इस पर ग्रेग तुर्क का काम देखा है , किसी भी मौके से?
जेएम

@ जेएम: अभी तक नहीं। मैंने सिर्फ उसका कोड चलाने की कोशिश की: इसमें PseudoColor के साथ X सर्वर की आवश्यकता होती है, अर्थात 8 बिट रंग की गहराई। मुझे लगता है कि मैं इसे OSX पर प्रदान नहीं कर सकता। मैंने विभिन्न वीएनसी सर्वरों की कोशिश की लेकिन कोई भाग्य नहीं।
AllCoder

मुझे लगता है कि आपको अभी भी मामले में तुर्क के दृष्टिकोण को अनुकूलित करने में सक्षम होना चाहिए; प्रतिक्रिया-प्रसार पैटर्न आजकल कंप्यूटर ग्राफिक्स में काफी हद तक उपयोग किए जा रहे हैं।
JM

1
मैं गलत हो सकता हूं, लेकिन m_An [i] [j] = 0.0 वाला हिस्सा; वास्तव में इस प्रणाली में एक तत्व जोड़ सकते हैं जिसे एक निरंतर दाहिने हाथ की ओर के अंतर समीकरण द्वारा मॉडलिंग नहीं किया जा सकता है। इससे तेज सॉल्वर के साथ आना थोड़ा मुश्किल होता है।
थॉमस क्लिम्पेल

जवाबों:


9

आप स्थिरता से सीमित प्रतीत होते हैं, जो कि उम्मीद है कि जब आप ग्रिड को परिष्कृत करते हैं तो विसरण कठोर होता है। कठोर प्रणालियों के लिए अच्छे तरीके कम से कम आंशिक रूप से निहित हैं। यह कुछ प्रयास करेगा, लेकिन आप इस प्रणाली को हल करने के लिए एक सरल मल्टीग्रिड एल्गोरिथ्म (या एक पुस्तकालय का उपयोग कर सकते हैं) को कम से कम दस "कार्य इकाइयों" (आवश्यक रूप से आपके एक समय के कदम की लागत) के साथ हल कर सकते हैं। जब आप ग्रिड को परिष्कृत करते हैं, तो पुनरावृत्तियों की संख्या में वृद्धि नहीं होगी।


यदि केवल प्रसार यहां कठोर होगा, तो वह डगलस-गन की तरह एडीआई पद्धति का उपयोग कर सकता है और सबकुछ ठीक हो जाएगा। हालांकि, मेरे अपने अनुभव में, बुरी तरह से अशुभ होने के अलावा कठोरता के संबंध में प्रतिक्रिया भाग अक्सर बहुत खराब होता है।
थॉमस क्लिम्पेल

1
ADI दुर्भाग्य से भयानक स्मृति क्षेत्र है। यह भी ध्यान दें कि प्रसार चाहे जो भी हो, प्रतिक्रिया को स्पष्ट रूप से माना जा सकता है। ग्रिड शोधन के तहत, अंत में प्रसार प्रभावी हो जाएगा, लेकिन हम यह नहीं बता सकते हैं कि स्थिरांक कहाँ स्थिरांक को जाने बिना है।
जेड ब्राउन

इसके लिए पिछड़े यूलर को लागू करने वाला उदाहरण कोड (पायथन में) यहाँ है: scicomp.stackexchange.com/a/2247/123
डेविड केचेसन

@DavidKetcheson: निहित विधियों का उपयोग करके समीकरण को हल करने की आवश्यकता है? यही कारण है कि कोड में linalg.spsolve () है?
ऑलकोडर

1
@AllCoder हाँ, इसके लिए एक समाधान की आवश्यकता है, लेकिन एक स्पष्ट विधि के स्थिर होने के लिए आवश्यक सभी चरणों की तुलना में यह समाधान बहुत तेज़ी से किया जा सकता है।
जेड ब्राउन

2

व्यावहारिक दृष्टिकोण से: A5 प्रोसेसर इतना शक्तिशाली नहीं है, इसलिए आप कुछ HW पुनरावृत्तियों की प्रतीक्षा कर सकते हैं, या यदि आपका ipod / ipad इंटरनेट से कनेक्ट होने जा रहा है, तो अपनी समस्या को दूर से या क्लाउड में हल करें।


मुझे आश्चर्य है कि ए 5 कितनी छोटी शक्ति प्रदान करता है। पेज, सफारी और अन्य बड़े एप्लिकेशन इतने अच्छे से कैसे काम कर सकते हैं? मुझे यादृच्छिक, अमूर्त छवियां उत्पन्न करने की आवश्यकता है, सोचा कि
रूपजनन

खैर, ए 5 वेब और वीडियो (पेज, सफारी, आदि) के लिए अनुकूलित एक ऊर्जा-कुशल प्रोसेसर है। इसके विपरीत, अधिकांश संख्यात्मक कार्यभार फ्लोटिंग-पॉइंट संचालन और डेटा-आंदोलनों के टन करते हैं, ये विशेषताएं कम-शक्ति वाले मोबाइल प्रोसेसर का ध्यान नहीं हैं।
fcruz

0

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

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


यह समस्या स्थिरता से सीमित है इसलिए केवल समय कदम आकार बढ़ाने से काम नहीं चलेगा।
जेड ब्राउन

यदि मैं 0.01 से उदा। 0.015 में बदल जाता हूं, तो मुझे सभी बिंदुओं पर "केम। एसपी। शून्य के पास" मिलता है - यानी एक ग्रे वर्ग। यहाँ मेरे कोड की उत्पत्ति है: drdobbs.com/article/print?articleId=184410024
AllCoder

हां, यह जेड द्वारा उल्लिखित स्थिरता के मुद्दों का परिणाम होगा। जैसा कि वह अपने जवाब में उल्लेख करता है, बेहतर स्थिरता प्रदर्शन द्वारा विशेषता एक निहित विधि का उपयोग करके आपके लिए इस मुद्दे को हल करेगा। अप्रासंगिक सूचना को हटाने के लिए मैं अपने उत्तर को अपडेट करूंगा।
गोड्रिक सीर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.