Explicit Euler method ช้าเกินไปสำหรับปัญหาการเกิดปฏิกิริยา


10

ฉันกำลังแก้ไขระบบตอบโต้การแพร่ของทัวริงด้วยรหัส C ++ ต่อไปนี้ ช้าเกินไป: สำหรับพื้นผิวพิกเซล 128x128 จำนวนการวนซ้ำที่ยอมรับได้คือ 200 - ซึ่งส่งผลให้เกิดความล่าช้า 2.5 วินาที ฉันต้องการ 400 ซ้ำเพื่อให้ได้ภาพที่น่าสนใจ - แต่ 5 วินาทีของการรอนั้นมากเกินไป นอกจากนี้ขนาดของพื้นผิวควรเป็นจริง 512x512 - แต่มันส่งผลในเวลาที่รอคอยมาก อุปกรณ์คือ iPad, iPod

มีโอกาสที่จะทำสิ่งนี้ได้เร็วขึ้นไหม? วิธีออยเลอร์ลู่เข้าช้า (วิกิพีเดีย) - การมีวิธีที่เร็วกว่าจะทำให้จำนวนการทำซ้ำลดลงหรือไม่

แก้ไข:ตามที่โธมัสคลิมเพลชี้ให้เห็นบรรทัด: "ถ้า (m_An [i] [j] <0.0) {... }", "ถ้า (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();
    }
}

นอกจากนี้ผมอยากจะพูดถึงว่าเป็นที่ต้องการที่คุณทำคำถามไม่ได้ข้ามโพสต์เพราะมันดูเหมือนว่าคุณได้ถามคำถามที่คล้ายกันมากทั้งที่นี่และที่นี่
Godric Seer

คุณเคยเห็นงานของGreg Turkในเรื่องนี้โดยบังเอิญไหม?
JM

@JM: ยังไม่ ฉันเพิ่งลองเรียกใช้รหัสของเขา: มันต้อง X server ด้วย PseudoColor นั่นคือความลึกของสี 8 บิต ฉันคิดว่าฉันไม่สามารถให้สิ่งนี้ใน OSX ฉันลองใช้เซิร์ฟเวอร์ VNC หลายแห่ง แต่ก็ไม่มีโชค
AllCoder

ฉันคิดว่าคุณควรจะสามารถปรับแนวทางของชาวเติร์กให้เข้ากับเรื่องนั้นได้ รูปแบบการแพร่กระจายของปฏิกิริยาดูเหมือนว่าจะใช้งานได้ดีในคอมพิวเตอร์กราฟิกในปัจจุบัน
JM

1
ฉันอาจจะผิด แต่ส่วนที่มีm_An [i] [j] = 0.0; อาจเพิ่มองค์ประกอบให้กับระบบนี้ซึ่งไม่สามารถสร้างแบบจำลองโดยสมการเชิงอนุพันธ์ด้วยด้านขวาอย่างต่อเนื่อง สิ่งนี้ทำให้ยากต่อการแก้ปัญหาที่เร็วขึ้น
โทมัสคลิมเพล

คำตอบ:


9

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


หากการแพร่กระจายเพียงอย่างเดียวจะแข็งทื่อที่นี่เขาสามารถใช้วิธี ADI เช่น Douglas-Gunn และทุกอย่างจะดี อย่างไรก็ตามจากประสบการณ์ของฉันเองส่วนของปฏิกิริยามักจะแย่ลงมากเมื่อเทียบกับความฝืดนอกเหนือจากการไม่เชิงเส้น
Thomas Klimpel

1
ADI น่าเสียดายที่มีพื้นที่หน่วยความจำแย่มาก โปรดทราบด้วยว่าปฏิกิริยาสามารถรักษาได้โดยปริยายไม่ว่าการแพร่กระจายนั้น ภายใต้การปรับแต่งกริดการแพร่กระจายในที่สุดก็จะกลายเป็นที่โดดเด่น แต่เราไม่สามารถบอกได้ว่าเกณฑ์อยู่ที่ไหนโดยไม่ทราบค่าคงที่
Jed Brown

ตัวอย่างโค้ดที่ใช้ออยเลอร์ย้อนหลังสำหรับเรื่องนี้ (ใน Python) อยู่ที่นี่: scicomp.stackexchange.com/a/2247/123
David Ketcheson

@DavidKetcheson: การใช้วิธีการทางอ้อมต้องแก้สมการหรือไม่ นี่คือเหตุผลที่มี linalg.spsolve () ในรหัสหรือไม่
AllCoder

1
@ AllCoder ใช่ต้องแก้ปัญหา แต่การแก้ปัญหาสามารถทำได้เร็วกว่าทุกขั้นตอนที่จำเป็นสำหรับวิธีการที่ชัดเจนเพื่อให้มีเสถียรภาพ
Jed Brown

2

จากมุมมองที่ใช้งานได้จริง: โปรเซสเซอร์ A5 ไม่ได้มีประสิทธิภาพมากนักดังนั้นคุณสามารถรอการทำซ้ำ HW สองสามครั้งหรือหาก iPod / iPad ของคุณกำลังเชื่อมต่อกับอินเทอร์เน็ตแก้ปัญหาของคุณจากระยะไกลหรือในระบบคลาวด์


ฉันประหลาดใจที่ A5 มีพลังงานเพียงเล็กน้อย Pages, Safari และแอปพลิเคชันขนาดใหญ่อื่น ๆ ทำงานได้ดีอย่างไร ฉันต้องการสร้างภาพนามธรรมแบบสุ่มคิดว่า morphogenesis จะง่ายพอ ..
AllCoder

A5 เป็นโปรเซสเซอร์ที่ประหยัดพลังงานเหมาะสำหรับเว็บและวิดีโอ (Pages, Safari, ฯลฯ ) ในทางตรงกันข้ามปริมาณงานที่เป็นตัวเลขส่วนใหญ่จะมีการดำเนินการเกี่ยวกับจำนวนจุดลอยตัวและการเคลื่อนย้ายข้อมูลจำนวนมากคุณสมบัติเหล่านี้ไม่ได้เป็นจุดสนใจของโปรเซสเซอร์มือถือที่ใช้พลังงานต่ำ
fcruz

0

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

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


ปัญหานี้ถูก จำกัด ด้วยความเสถียรดังนั้นการเพิ่มขนาดขั้นตอนเวลาจะไม่ทำงาน
Jed Brown

ถ้าฉันเปลี่ยน 0.01 เป็นเช่น 0.015 ฉันจะได้รับ "ความเข้มข้นของเคมี sp. ใกล้ศูนย์" ทุกจุด - เช่นสี่เหลี่ยมสีเทา นี่คือที่มาของรหัสของฉัน: drdobbs.com/article/print?articleId=184410024
AllCoder

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