Metode Euler eksplisit terlalu lambat untuk masalah difusi reaksi

10

Saya memecahkan sistem reaksi-difusi Turing dengan mengikuti kode C ++. Terlalu lambat: untuk tekstur 128x128 piksel, jumlah iterasi yang dapat diterima adalah 200 - yang menghasilkan penundaan 2,5 detik. Saya perlu 400 iterasi untuk mendapatkan gambar yang menarik - tetapi menunggu 5 detik terlalu banyak. Selain itu, ukuran teksturnya seharusnya 512x512 - tetapi ini menghasilkan waktu tunggu yang sangat lama. Perangkatnya adalah iPad, iPod.

Apakah ada peluang untuk melakukan ini lebih cepat? Metode Euler konvergen perlahan (wikipedia) - memiliki metode yang lebih cepat akan memungkinkan untuk menjatuhkan jumlah iterasi?

EDIT: Seperti yang ditunjukkan Thomas Klimpel, baris: "if (m_An [i] [j] <0,0) {...}", "if (m_Bn [i] [j] <0,0) {...}" menunda konvergensi: setelah menghapus, gambar yang berarti muncul setelah 75 iterasi . Saya telah mengomentari baris dalam kode di bawah ini.

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();
    }
}
AllCoder
sumber
Juga, saya ingin menyebutkan bahwa itu adalah pilihan yang Anda lakukan tidak pertanyaan cross-posting, karena tampaknya Anda telah meminta pertanyaan yang sangat mirip baik di sini dan di sini .
Godric Seer
Apakah Anda sudah melihat pekerjaan Greg Turk dalam hal ini?
JM
@ JK: Belum. Saya baru saja mencoba menjalankan kodenya: membutuhkan server X dengan PseudoColor, yaitu kedalaman warna 8 bit. Saya rasa saya tidak bisa menyediakan ini di OSX. Saya mencoba berbagai server VNC tetapi tidak berhasil.
AllCoder
Saya pikir Anda masih harus bisa mengadaptasi pendekatan Turk terhadap masalah yang ada; pola reaksi-difusi tampaknya digunakan cukup adil dalam grafik komputer saat ini.
JM
1
Saya mungkin salah, tetapi bagian dengan m_An [i] [j] = 0,0; mungkin sebenarnya menambahkan elemen ke sistem ini yang tidak dapat dimodelkan oleh persamaan diferensial dengan sisi kanan kontinu. Ini membuatnya agak sulit untuk menghasilkan pemecah yang lebih cepat.
Thomas Klimpel

Jawaban:

9

Anda tampaknya dibatasi oleh stabilitas, yang diharapkan karena difusi kaku saat Anda memperbaiki grid. Metode yang baik untuk sistem kaku setidaknya sebagian implisit. Ini akan membutuhkan upaya, tetapi Anda dapat menerapkan algoritma multigrid sederhana (atau menggunakan perpustakaan) untuk menyelesaikan sistem ini dengan biaya kurang dari sepuluh "unit kerja" (pada dasarnya biaya salah satu langkah waktu Anda). Saat Anda memperbaiki grid, jumlah iterasi tidak akan meningkat.

Jed Brown
sumber
Jika hanya difusi yang kaku di sini, dia bisa menggunakan metode ADI seperti Douglas-Gunn dan semuanya akan baik-baik saja. Namun, dalam pengalaman saya sendiri, bagian reaksi sering jauh lebih buruk sehubungan dengan kekakuan selain menjadi sangat tidak linier.
Thomas Klimpel
1
Sayangnya ADI memiliki memori lokalitas yang buruk. Perhatikan juga bahwa reaksi dapat diperlakukan secara implisit terlepas dari apakah difusi. Di bawah penyempurnaan grid, difusi pada akhirnya akan menjadi dominan, tetapi kami tidak dapat menentukan di mana ambangnya tanpa mengetahui konstanta.
Jed Brown
Contoh kode yang menerapkan Euler mundur untuk ini (dengan Python) ada di sini: scicomp.stackexchange.com/a/2247/123
David Ketcheson
@DavidKetcheson: Menggunakan metode implisit membutuhkan penyelesaian persamaan? Inilah sebabnya mengapa ada linalg.spsolve () dalam kode?
AllCoder
1
@ AllCoder Ya, ini membutuhkan penyelesaian, tetapi penyelesaiannya dapat dilakukan jauh lebih cepat daripada semua langkah waktu yang diperlukan untuk metode eksplisit menjadi stabil.
Jed Brown
2

Dari sudut pandang praktis: prosesor A5 tidak terlalu kuat, sehingga Anda bisa menunggu beberapa iterasi HW, atau jika ipod / ipad Anda akan terhubung ke internet, selesaikan masalah Anda dari jarak jauh atau di awan.

fcruz
sumber
Saya terkejut betapa kecilnya kekuatan yang ditawarkan A5. Bagaimana cara Halaman, Safari, dan aplikasi besar lainnya bekerja dengan baik? Saya perlu menghasilkan acak, gambar abstrak, berpikir bahwa morfogenesis akan cukup sederhana ..
AllCoder
Yah, A5 adalah prosesor hemat energi yang dioptimalkan untuk web dan video (Halaman, Safari, dll). Sebaliknya, sebagian besar beban kerja numerik melakukan banyak operasi floating-point dan pergerakan data, fitur-fitur ini bukan fokus dari prosesor seluler berdaya rendah.
fcruz
0

Euler memang bertemu perlahan-lahan dalam kaitannya dengan metode lain, namun saya tidak berpikir itu yang Anda minati. Jika Anda hanya mencari gambar "menarik", tambah ukuran langkah waktu Anda dan kurangi iterasi. Masalahnya, seperti yang ditunjukkan Jed, adalah bahwa metode euler eksplisit memiliki masalah stabilitas dengan langkah waktu yang besar dalam kaitannya dengan ukuran kisi. semakin kecil kisi Anda (yaitu, semakin tinggi resolusi gambar Anda), semakin kecil langkah waktu Anda untuk memperhitungkannya.

Misalnya, dengan menggunakan euler implisit alih-alih eksplisit, Anda tidak mendapatkan perintah konvergensi, tetapi solusinya akan memiliki stabilitas tanpa syarat, memungkinkan langkah waktu yang jauh lebih besar. Metode implisit lebih rumit untuk diterapkan dan mengambil lebih banyak perhitungan per langkah waktu, tetapi Anda harus melihat keuntungan lebih dari itu dengan mengambil langkah lebih sedikit secara total.

Pelihat Godric
sumber
Masalah ini dibatasi oleh stabilitas sehingga hanya meningkatkan ukuran langkah waktu tidak akan berhasil.
Jed Brown
Jika saya mengubah 0,01 menjadi misalnya 0,015, maka saya mendapatkan "konsentrasi kimia. Mendekati nol" di semua titik - yaitu kotak abu-abu. Ini adalah asal kode saya: drdobbs.com/article/print?articleId=184410024
AllCoder
Ya, itu akan menjadi hasil dari masalah stabilitas yang disebutkan Jed. Ketika ia menyebutkan dalam jawabannya, menggunakan metode implisit yang ditandai dengan kinerja stabilitas yang lebih baik akan menyelesaikan masalah ini untuk Anda. Saya akan memperbarui jawaban saya untuk menghapus informasi yang tidak relevan.
Godric Seer