반응-확산 문제에 대한 명백한 오일러 방법이 너무 느림


10

다음 C ++ 코드로 Turing의 반응 확산 시스템을 해결하고 있습니다. 너무 느립니다 : 128x128 픽셀 텍스처의 경우 허용되는 반복 횟수는 200 – 2.5 초 지연됩니다. 흥미로운 이미지를 얻으려면 400 회 반복해야하지만 5 초의 대기 시간이 너무 깁니다. 또한 텍스처의 크기는 실제로 512x512 여야합니다. 그러나 이로 인해 대기 시간이 길어집니다. 장치는 iPad, iPod입니다.

더 빨리 할 수있는 기회가 있습니까? 오일러 방법은 느리게 수렴합니다 (wikipedia). 더 빠른 방법을 사용하면 반복 횟수를 줄일 수 있습니까?

편집 : Thomas Klimpel이 지적한대로 "if (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();
    }
}

또한 질문을 교차 게시하지 않는 것이 좋습니다 . 여기여기 모두 에서 매우 유사한 질문을 한 것으로 보입니다 .
Godric Seer

이미 그렉 터크의 작업 을 본 적이 있습니까?
JM

@JM : 아직은 아닙니다. 방금 코드를 실행하려고했습니다 .PseudoColor가있는 X 서버, 즉 8 비트 색 농도가 필요합니다. OSX에서 이것을 제공 할 수 없다고 생각합니다. 다양한 VNC 서버를 사용해 보았지만 운이 없습니다.
AllCoder

본인은 여전히 ​​현재의 문제에 터크의 접근 방식을 적용 할 수 있어야한다고 생각합니다. 반응 확산 패턴은 오늘날 컴퓨터 그래픽에서 상당히 사용되는 것 같습니다.
JM

1
틀릴 수도 있지만 m_An [i] [j] = 0.0; 실제로 연속적인 우변을 가진 미분 방정식으로 모델링 할 수없는 요소를이 시스템에 추가 할 수 있습니다. 이로 인해 더 빠른 솔버를 찾기가 다소 어려워집니다.
Thomas Klimpel

답변:


9

그리드를 다듬을 때 확산이 뻣뻣하기 때문에 안정성이 제한되는 것 같습니다. 딱딱한 시스템을위한 좋은 방법은 적어도 부분적으로 암시 적입니다. 약간의 노력이 필요하지만 간단한 멀티 그리드 알고리즘을 구현하거나 라이브러리를 사용하여 10 개 미만의 "작업 단위"(본질적으로 시간 단계 중 하나의 비용)로이 시스템을 해결할 수 있습니다. 그리드를 세분화하면 반복 횟수가 증가하지 않습니다.


확산이 뻣뻣 할 경우 Douglas-Gunn과 같은 ADI 방법을 사용할 수 있으며 모든 것이 정상입니다. 그러나 내 자신의 경험에서, 반응 부분은 종종 비선형이 아닌 강성에 비해 훨씬 나쁩니다.
Thomas Klimpel

1
불행히도 ADI는 끔찍한 메모리 지역을 가지고 있습니다. 또한 확산 여부에 관계없이 반응을 암시 적으로 처리 할 수 ​​있습니다. 그리드 세분화에서는 확산이 지배적이지만 상수를 알지 못하면 임계 값이 어디에 있는지 알 수 없습니다.
제드 브라운

이것을 위해 (파이썬에서) 뒤로 오일러를 구현하는 예제 코드는 다음과 같습니다. scicomp.stackexchange.com/a/2247/123
David Ketcheson

@DavidKetcheson : 암시 적 방법을 사용하려면 방정식을 풀어야합니까? 이것이 코드에 linalg.spsolve ()가있는 이유입니다.
AllCoder

1
@AllCoder 그렇습니다. 해결이 필요하지만, 명시 적 방법이 안정되기 위해 필요한 모든 시간 단계보다 훨씬 빠르게 해결이 가능합니다.
제드 브라운

2

실용적인 관점에서 : A5 프로세서는 그다지 강력하지 않으므로 몇 번의 HW 반복을 기다리거나 ipod / ipad가 인터넷에 연결되어 있으면 원격으로 또는 클라우드에서 문제를 해결하십시오.


A5가 얼마나 작은 힘을 제공하는지 놀랍습니다. Pages, Safari 및 기타 대형 응용 프로그램이 어떻게 잘 작동합니까? 난 임의의 추상 이미지를 생성해야 morphogenesis 충분히 간단 할 것이라고 생각했다.
AllCoder

A5는 웹 및 비디오 (페이지, Safari 등)에 최적화 된 에너지 효율적인 프로세서입니다. 반면, 대부분의 수치 워크로드는 수많은 부동 소수점 연산 및 데이터 이동을 수행하지만 이러한 기능은 저전력 모바일 프로세서의 초점이 아닙니다.
fcruz

0

오일러는 다른 방법과 관련하여 천천히 수렴하지만, 이것이 당신이 관심있는 것 같지는 않습니다. "흥미로운"이미지를 찾고 있다면 시간 단계의 크기를 늘리고 반복 횟수를 줄이십시오. Jed가 지적했듯이 문제는 명시 적 오일러 방법이 그리드 크기와 관련하여 큰 시간 간격으로 안정성 문제를 가지고 있다는 것입니다. 격자가 작을수록 (즉, 이미지의 해상도가 높을수록) 시간 단계가 작아야합니다.

예를 들어 명시 적 대신 암시 적 오일러를 사용하면 수렴 순서는 얻지 못하지만 솔루션에는 무조건적인 안정성이있어 훨씬 더 큰 시간 단계를 허용합니다. 암시 적 메소드는 구현하기가 더 복잡하고 시간 단계마다 더 많은 계산을 수행하지만 총 단계를 줄이면 그 이상의 이점을 볼 수 있습니다.


이 문제는 안정성에 의해 제한되므로 시간 단계 크기를 늘리는 것만으로는 효과가 없습니다.
제드 브라운

0.01을 예를 들어 0.015로 변경하면 모든 지점에서 "화학 농도가 0에 가까워집니다"즉 회색 사각형이 나타납니다. 내 코드의 출처는 다음과 같습니다. drdobbs.com/article/print?articleId=184410024
AllCoder

예, 제드가 언급 한 안정성 문제의 결과 일 것입니다. 그가 답변에서 언급했듯이 더 나은 안정성 성능을 특징으로하는 암시 적 방법을 사용하면이 문제를 해결할 수 있습니다. 관련없는 정보를 제거하기 위해 답변을 업데이트하겠습니다.
Godric Seer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.