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();
}
}
Jawaban:
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.
sumber
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.
sumber
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.
sumber