モジュール

			
/**************************************************
  gasdiffusion.cc
  セルオートマトンによるガス拡散シミュレーション
***************************************************/

#define TIMES 20

vs_module
gasdiffusion(iImage cell, iImage gas, iImage rand)
{
    fprintf(stderr,"process start.\n");
    // テンポラリ変数
    iImage neighbors(cell);
    iImage shadow(gas);

    int times = 0;
    do {
	ImgCopy(neighbors, rand);

	// 径1の外周(全領域中での)は処理からはずす
	vsSetBoundary2D(1);    

	parallel_ie(x,y) {
	    if(times % 2) {
		switch(cell[][]) {
		  case 0:
		    neighbors[][] += rand[+1][];
		    neighbors[][] += rand[][-1];
		    neighbors[][] += rand[+1][-1];
		    break;
		  case 1:
		    neighbors[][] += rand[][-1];
		    neighbors[][] += rand[-1][];
		    neighbors[][] += rand[-1][-1];
		    break;
		  case 3:
		    neighbors[][] += rand[-1][];
		    neighbors[][] += rand[][+1];
		    neighbors[][] += rand[-1][+1];
		    break;
		  default:
		    neighbors[][] += rand[][+1];
		    neighbors[][] += rand[+1][];
		    neighbors[][] += rand[+1][+1];
		}
	    } else {
		switch(cell[][]) {
		  case 3:
		    neighbors[][] += rand[+1][];
		    neighbors[][] += rand[][-1];
		    neighbors[][] += rand[+1][-1];
		    break;
		  case 2:
		    neighbors[][] += rand[][-1];
		    neighbors[][] += rand[-1][];
		    neighbors[][] += rand[-1][-1];
		    break;
		  case 0:
		    neighbors[][] += rand[-1][];
		    neighbors[][] += rand[][+1];
		    neighbors[][] += rand[-1][+1];
		    break;
		  default:
		    neighbors[][] += rand[][+1];
		    neighbors[][] += rand[+1][];
		    neighbors[][] += rand[+1][+1];
		}
	    }
	}

	vsSetBoundary2D(0);
    
	parallel_ie(x,y) {
	    if((x > 1) && (x < (width -1)) && (y > 1) && (y < (heigh -1))) {
		if(neighbors[][] % 2) {
		    // 偶数の場合 - - - - - - - - - - - - - - - - - 
		    if(times % 2) {
			switch(cell[][]) {
			  case 0:
			    shadow[][] = gas[][-1]; break;
			  case 1:
			    shadow[][] = gas[-1][]; break;
			  case 3:
			    shadow[][] = gas[][+1]; break;
			  default:
			    shadow[][] = gas[+1][];
			}
		    } else {
			switch(cell[][]) {
			  case 3:
			    shadow[][] = gas[][-1]; break;
			  case 2:
			    shadow[][] = gas[-1][]; break;
			  case 0:
			    shadow[][] = gas[][+1]; break;
			  default:
			    shadow[][] = gas[+1][];
			}
		    }	
		} else {
		    // 奇数の場合 - - - - - - - - - - - - - - - - - 
		    if(times % 2) {
			switch(cell[][]) {
			  case 0:
			    shadow[][] = gas[+1][]; break;
			  case 1:
			    shadow[][] = gas[][-1]; break;
			  case 3:		    
			    shadow[][] = gas[-1][]; break;
			  default:
			    shadow[][] = gas[][+1];
			}
		    } else {
			switch(cell[][]) {
			  case 3:
			    shadow[][] = gas[+1][]; break;
			  case 2:
			    shadow[][] = gas[][-1]; break;
			  case 0:
			    shadow[][] = gas[-1][]; break;
			  default:
			    shadow[][] = gas[][+1];
			}
		    }	
		}
	    } else {
		shadow[][] = gas[][];
	    }
	}
	// 大域変数にコピー
	ImgCopy(gas,shadow);

	parallel_ie(x,y) {
	    if((x > 1) && (x < (width -1)) && (y > 1) && (y < (heigh -1))) {
		neighbors[][] = \
		    (rand[+1][] + rand[][+1] + rand[-1][] + rand[][-1]) % 2;
	    } else {
		neighbors[][] = rand[][];
	    }
	}

    } while(++times < TIMES);
}




実行フロープログラム

/****************************************
 *   実装実験用プログラムgasdiffusion.vpe   *
 ****************************************/
// 通信処理初期化 -------------

#pragma host_name	host1
#pragma host_name	host2
#pragma host_name	host3
#pragma host_name	host4

#pragma use_intercomm

// データの初期化 -------------

int w,h;
w   = 512;
h   = w;

iImage cell(w,h);
iImage  gas(w,h);
iImage rand(w,h);

int i, j;

// cellの初期値を入れる
for(j=0; j<h; j=j+2)
    for(i=0; i<w; i=i+2) cell(i,j) = 3;
for(j=1; j<h; j=j+2)
    for(i=0; i<w; i=i+2) cell(i,j) = 1;
for(j=0; j<h; j=j+2)
    for(i=1; i<w; i=i+2) cell(i,j) = 2;

// gas の初期値を入れる
for(j=h/3; j<h/3*2; j=j+1)
    for(i=w/3; i<w/3*2; i=i+1) gas(i,j) = 1;

// randの初期値を入れる
for(j=0; j<h; j=j+1)
    for(i=0; i<w; i=i+1)
	rand(i,j) = random() / (RAND_MAX / 5);


module("gasdiffusion", cell, gas, rand);

gather(gas);
imgSave("result.pgm", gas);


実行方法

  1. 全体画像、テンプレートの用意
  2. モジュールのコンパイル
    % vs_makemodule gasdiffusion.cc
  3. プログラムの実行
    % vios_run < gasdiffusion.vpe


実行フロー設定項目


モジュールプログラム説明

実行結果

テンプレートと全体画像がもっともマッチした時のテンプレートの中心がある座標を出力します。