Phương pháp Euler rõ ràng quá chậm cho vấn đề khuếch tán phản ứng


10

Tôi đang giải quyết hệ thống khuếch tán phản ứng của Turing bằng mã C ++. Quá chậm: đối với kết cấu 128x128 pixel, số lần lặp có thể chấp nhận là 200 - kết quả là chậm 2,5 giây. Tôi cần 400 lần lặp để có được hình ảnh thú vị - nhưng 5 giây chờ đợi là quá nhiều. Ngoài ra, kích thước của kết cấu nên trên thực tế là 512x512 - nhưng điều này dẫn đến thời gian chờ đợi rất lớn. Các thiết bị là iPad, iPod.

Có bất kỳ cơ hội để làm điều này nhanh hơn? Phương pháp Euler hội tụ chậm (wikipedia) - có phương pháp nhanh hơn sẽ cho phép giảm số lần lặp?

EDIT: Như Thomas Klimpel đã chỉ ra, các dòng: "if (m_An [i] [j] <0.0) {...}", "if (m_Bn [i] [j] <0.0) {...}" đang trì hoãn hội tụ: sau khi xóa, hình ảnh có ý nghĩa xuất hiện sau 75 lần lặp . Tôi đã nhận xét ra các dòng trong mã dưới đây.

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();
    }
}

Ngoài ra, tôi muốn đề cập rằng bạn không nên đặt câu hỏi chéo, vì có vẻ như bạn đã hỏi những câu hỏi rất giống nhau ở đâyđây .
Godric Seer

Bạn đã từng thấy tác phẩm của Greg Turk về điều này chưa?
JM

@JM: Chưa. Tôi vừa thử chạy mã của mình: nó yêu cầu máy chủ X với PseudoColor, tức là độ sâu màu 8 bit. Tôi nghĩ rằng tôi không thể cung cấp điều này trên OSX. Tôi đã thử nhiều máy chủ VNC nhưng không gặp may.
AllCoder

Tôi nghĩ bạn vẫn có thể điều chỉnh cách tiếp cận của Turk đối với vấn đề hiện tại; mô hình khuếch tán phản ứng dường như được sử dụng một chút công bằng trong đồ họa máy tính ngày nay.
JM

1
Tôi có thể sai, nhưng phần có m_An [i] [j] = 0,0; thực sự có thể thêm một phần tử vào hệ thống này mà không thể mô hình hóa bằng phương trình vi phân với phía bên tay phải liên tục. Điều này làm cho một chút khó khăn để đưa ra một bộ giải nhanh hơn.
Thomas Klimpel

Câu trả lời:


9

Bạn dường như bị giới hạn bởi sự ổn định, điều này được dự kiến ​​vì sự khuếch tán bị cứng khi bạn tinh chỉnh lưới. Các phương pháp tốt cho các hệ thống cứng ít nhất là một phần ngầm định. Sẽ mất một số nỗ lực, nhưng bạn có thể thực hiện một thuật toán đa biến đơn giản (hoặc sử dụng thư viện) để giải quyết hệ thống này với chi phí ít hơn mười "đơn vị công việc" (về cơ bản là chi phí của một trong các bước thời gian của bạn). Khi bạn tinh chỉnh lưới, số lần lặp sẽ không tăng.


Nếu chỉ khuếch tán ở đây, anh ta có thể sử dụng phương pháp ADI như Douglas-Gunn và mọi thứ sẽ ổn. Tuy nhiên, theo kinh nghiệm của riêng tôi, phần phản ứng thường tồi tệ hơn nhiều so với độ cứng ngoài việc là phi tuyến xấu.
Thomas Klimpel

1
ADI không may có bộ nhớ địa phương khủng khiếp. Cũng lưu ý rằng phản ứng có thể được xử lý ngầm bất kể có khuếch tán hay không. Dưới sự sàng lọc lưới, sự khuếch tán cuối cùng sẽ trở thành ưu thế, nhưng chúng ta không thể biết ngưỡng đó ở đâu mà không biết các hằng số.
Jed Brown

Mã ví dụ triển khai Euler lạc hậu cho điều này (bằng Python) có ở đây: scicomp.stackexchange.com/a/2247/123
David Ketcheson

@DavidKetcheson: Sử dụng các phương thức ngầm đòi hỏi phải giải phương trình? Đây là lý do tại sao có mã linalg.spsolve ()?
AllCoder

1
@ ALLCoder Có, nó yêu cầu giải quyết, nhưng việc giải quyết có thể được thực hiện nhanh hơn nhiều so với tất cả các bước thời gian cần thiết để một phương thức rõ ràng được ổn định.
Jed Brown

2

Từ quan điểm thực tế: bộ xử lý A5 không mạnh lắm, vì vậy bạn có thể đợi một vài lần lặp CTNH hoặc nếu ipod / ipad của bạn sẽ được kết nối với internet, giải quyết vấn đề của bạn từ xa hoặc trên đám mây.


Tôi ngạc nhiên khi A5 cung cấp năng lượng nhỏ như thế nào. Làm thế nào để Pages, Safari và các ứng dụng lớn khác hoạt động tốt như vậy? Tôi cần tạo ra những hình ảnh ngẫu nhiên, trừu tượng, nghĩ rằng hình thái học sẽ đủ đơn giản ..
AllCoder

Vâng, A5 là một bộ xử lý tiết kiệm năng lượng được tối ưu hóa cho web và video (Pages, Safari, v.v.). Ngược lại, hầu hết các khối lượng công việc số thực hiện hàng tấn hoạt động của dấu phẩy động và chuyển động dữ liệu, các tính năng này không phải là trọng tâm của bộ xử lý di động công suất thấp.
fcruz

0

Euler không hội tụ chậm liên quan đến các phương pháp khác, tuy nhiên tôi không nghĩ đó là điều bạn quan tâm. Nếu bạn chỉ tìm kiếm những hình ảnh "thú vị", hãy tăng kích thước của bước thời gian của bạn và thực hiện ít lần lặp hơn. Vấn đề, như Jed chỉ ra, là phương pháp euler rõ ràng có vấn đề ổn định với các bước thời gian lớn liên quan đến kích thước lưới. lưới của bạn càng nhỏ (tức là hình ảnh của bạn có độ phân giải càng cao), bước thời gian của bạn càng nhỏ để tính đến nó.

Chẳng hạn, bằng cách sử dụng euler ẩn thay vì rõ ràng, bạn không đạt được bất kỳ mệnh lệnh hội tụ nào, nhưng giải pháp sẽ có sự ổn định vô điều kiện, cho phép các bước thời gian lớn hơn nhiều. Các phương thức tiềm ẩn phức tạp hơn để thực hiện và tính toán nhiều hơn theo từng bước, nhưng bạn sẽ thấy lợi nhuận vượt xa hơn bằng cách thực hiện tổng số bước ít hơn.


Vấn đề này bị giới hạn bởi sự ổn định nên chỉ cần tăng kích thước bước thời gian sẽ không hoạt động.
Jed Brown

Nếu tôi thay đổi 0,01 thành 0,015, thì tôi nhận được "nồng độ hóa học gần bằng 0" tại tất cả các điểm - tức là một hình vuông màu xám. Đây là nguồn gốc của mã của tôi: drdobbs.com/article/print?articleId=184410024
AllCoder

Vâng, đó sẽ là kết quả của các vấn đề ổn định mà Jed đã đề cập. Như anh ấy đề cập trong câu trả lời của mình, sử dụng một phương pháp ngầm được đặc trưng bởi hiệu suất ổn định tốt hơn sẽ giải quyết vấn đề này cho bạn. Tôi sẽ cập nhật câu trả lời của tôi để loại bỏ các thông tin không liên quan.
Godric Seer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.