サーチアクセスに関する関数についてのソースファイルである。
#include <math.h>
#include "srh2_ms.h"
#include "srh2_sms.h"
/* パターンの要素 */
#define B 1 /* 黒 */
#define W 0 /* 白 */
#define PATTERN 4 /* 記憶するパターン数 */
#define fout(x) (1/(1+ exp(-(x/0.01)))) /* シグモイド関数 */
extern double drand48();/* 乱数関数 */
int fail;/* それぞれの検索パターンについて数えて
一番早く失敗したのが何回目の初期パターンかを表す */
int search;/* 何番目の検索パターンを検索しているかを示す */
int kai;/* 何番目の初期パターンで検索しているかを示す */
int kai_max;/* 離散的時間最大値
(この時間までに想起できなかったら失敗とみなす) */
int shoki_n;/* 検索回数 */
/* シナプス前抑制変数・定数 */
static double z;/* 入力 */
static double rsnp;/* 出力 */
static double rcha;/* 出力最小値(カオス状態) */
static double gs;/* しきい値 */
/* カオスニューロン定数 */
static double alp;/* 不応性に関する比例定数 */
static double km;/* 相互結合入力に関する記憶の減衰定数 */
static double kr;/* 不応性に関する減衰定数 */
static double gaib;/* しきい値定数 */
static double eps;/* シグモイド関数の温度の比例定数 */
double sei_hei;/* 想起成功率 */
double t_hei;/* 平均想起時間 */
search_main()
{
FILE *file_write(int *,int);
/* Result File または,Passage File の書き込み設定 */
int i,j;
int fw;/* Result File, Passage File 書き込み失敗判定フラグ */
int keika_ari;/* Passage File 出力判定フラグ */
FL_OBJECT *ob;/* 検索中に入力があったオブジェクトのポインタ */
int levo[U],levn[U];/* 量子化値 */
int times;/* 同パターン連続想起回数 */
int hi;/* 同パターン連続想起判定フラグ */
long shoki;/* 乱数初期化 */
/* カオスニューロン出力・内部状態 */
double x[U];/* 出力パターン */
double m[U];/* 相互結合に関する内部状態 */
double n[U];/* 不応性に関する内部状態 */
/* 自己相関学習変数・定数 */
double sok;/* 結合荷重比例定数 */
double w[U][U];/* シナプス結合荷重 */
int out_in[PATTERN][U];/* 学習パターン */
int nai_s_s[PATTERN][SRH_MAX];/* 検索パターンと初期パターンの相関内積 */
FILE *fp;/* Pattern File */
FILE *fd;/* Result File */
FILE *fk;/* Passage File */
const char *pfn;/* Pattern File のファイル名 */
/* 各定数設定 */
sok = fl_get_counter_value(sok_o);
alp = fl_get_counter_value(alp_o);
eps = 0.015;
gaib = 2.0;
rcha = 0.4;
km = fl_get_counter_value(km_o);
kr = fl_get_counter_value(kr_o);
gs = fl_get_counter_value(gs_o);
shoki_n = (int)fl_get_counter_value(sn);
shoki = (long)fl_get_counter_value(pn);
kai_max = (int)fl_get_counter_value(mt);
sei_hei=0.0;
t_hei=0.0;
fail=-1;
keika_ari = fl_get_button(po);
/* Pattern File 読み込み設定 */
pfn = fl_get_input(fl);
if((fp = fopen(pfn,"r")) == NULL){
/* 読み込みに失敗した場合
(ファイルがないか読み込み禁止になっている場合) */
fl_set_object_lcol(str,FL_BLACK);
fl_activate_object(str);
fl_show_alert("Sorry","Can't find or read Pattern File!!",pfn,0);
goto fail_p;
}
/* Passage Output ボタンが ON(黄)の場合 */
if(keika_ari){
/* Passage File 書き込み設定 */
fk=file_write(&fw,0);
if(fw)
/* 書き込み失敗の場合 */
goto fail_k;
}
/* Result File 書き込み設定 */
fd=file_write(&fw,1);
if(fw)
goto fail_d;
/* 各定数のファイル出力 */
fprintf(fd,"km\t%1.3lf\nkr\t%1.3lf\ng\t%1.3lf\n",km,kr,gs);
fprintf(fd,"so\t%1.3lf\nm\t%d\nalp\t%2.2lf\n\n",sok,kai_max,alp);
/* パターンの取り込み */
if(torikomi(shoki,out_in,fp,fd,pfn))
/* 失敗の場合 */
goto fail_d;
/* 自己相関学習 */
soukan(sok,w,out_in);
/* 各学習パターンごとに検索 */
for(search = 0; search < PATTERN; search++){
/* 何番目の学習パターンかをファイル出力 */
fprintf(fd,"\npt%d\n",search);
/* 初期値パターン設定 */
srand48(shoki);
/* 各パターンにつき shoki_n 回検索する */
for(j = 0; j < shoki_n ; j++){
/* 初期設定・内積計算 */
shoki_p(j,x,m,n,out_in,nai_s_s);
/* 想起されるまでニューロンの出力を計算を繰り返す
kai_max 回繰り返しても想起されなかった場合は計算を終了する */
for(kai = 0; kai < kai_max ; kai++){
/* ボタン等の入力を調べる */
if((ob=fl_check_forms())==ps){
pas:
/* PAUSE ボタンを押した場合 */
while((ob=fl_do_forms())!=ps)
if(ob==stp)
/* STOP ボタンを押した場合 */
goto stop;
}
else
/* STOP ボタンを押した場合 */
if(ob==stp)
stop:
/* 本当に検索を中止していいかどうかを選択 */
if(fl_show_question("Do you really want to STOP?","","")){
/* Yes を選択した場合 */
fl_set_object_lcol(str,FL_BLACK);
fl_activate_object(str);
goto fail_d;
}
else
if(fl_get_button(ps))
/* PAUSE ボタンが ON の状態の場合 */
goto pas;
/* 量子化(終了判定比較等に用いる) */
ryoushika(levo,x);
/* カオスニューロンの入力と出力の比較(検索終了判定) */
hi=hikaku(levo,levn);
if (hi == 0 && kai != 0)
times++;/* 同じ場合 */
else
times=0;/* 異なる場合 */
/* 出力を新たに入力とする */
for(i=0; i<U; i++)
levn[i] = levo[i];
/* 出力パターンと検索パターンとの距離計算と,
シナプス前抑制関数の出力計算 */
kyori(x,out_in);
/* Passage Output ボタンが ON の場合 Passage File へ出力 */
if(keika_ari)
keika(levo,times,hi,kai,fk);
/* 何らかのパターンが想起されたとみなし終了 */
if(times == SOUKITIME)
break;
/* カオスニューロンの出力計算 */
neuro(x,m,n,w);
}
/* 想起に成功したかどうかの判定・ファイル出力 */
jikosouki(j,levo,out_in,fd);
}
fprintf(fd,"\n");
}
/* 初期パターンと学習パターンとの相関内積の出力 */
for(i=0; i<PATTERN; i++){
/* 何番目の学習パターンとの相関内積かを出力 */
fprintf(fd,"\nnp%d\n",i);
for(j=0; j<shoki_n; j++){
fprintf(fd,"%5d",nai_s_s[i][j]);
if(j%10 == 9)
fprintf(fd,"\n");
}
fprintf(fd,"\n");
}
/* 失敗がなかった場合 Failure ランプに青を点灯 */
if(fail==-1) fl_set_object_color(f_sg,FL_BLUE,FL_COL1);
/* 想起平均時間の計算 */
if(sei_hei!=0)
t_hei/=sei_hei;
else t_hei=-1.0;/* 一度も成功しなかった場合 -1 とする */
/* 想起成功率の計算 */
sei_hei/=PATTERN*shoki_n;
/* 計算結果をファイル出力 */
fprintf(fd,"seikou\t%lf\n",sei_hei);
fprintf(fd,"time\t%lf\n",t_hei);
/* 各ファイルを閉じる */
fail_d:
fclose(fd);
fail_k:
if(keika_ari)
fclose(fk);
fail_p:
fclose(fp);
}
/* 自己相関学習 */
soukan(double sok, double w[][U], int out_in[][U])
{
int i,j,k;
double out_in_z_h;/* 全学習パターンの要素平均 */
/* 全学習パターンの要素平均の計算 */
out_in_z_h = 0.0;
for(j = 0; j < U; j++)
for(i = 0; i < PATTERN; i++)
out_in_z_h += (double)out_in[i][j];
out_in_z_h /= U*PATTERN;
/* 自己相関学習によりシナプス結合荷重を求める
(全学習パターンの要素平均を考慮) */
for(i = 0; i < PATTERN; i++)
for(j = 0; j < U; j++)
for(k = 0; k < U; k++){
if(i==0) w[j][k]=0.0;
w[j][k] += sok * 4 *((double)out_in[i][j] - out_in_z_h) *
((double)out_in[i][k] - out_in_z_h);
}
}
/* 初期設定・内積計算 */
shoki_p(int j, double x[], double m[], double n[], int out_in[][U],
int nai_s_s[][SRH_MAX])
{
register int i;
nai_s_s[search][j] = 0;
for(i = 0; i < U; i++){
/* 初期パターンの設定 */
if(drand48() < 0.5)
x[i] = W;
else
x[i] = B;
/* 初期パターンと検索パターンとの相関内積 */
if((double)out_in[search][i] == x[i])
nai_s_s[search][j]++;
else
nai_s_s[search][j]--;
/* 内部状態の初期設定 */
m[i] = n[i] = 0;
}
}
/* 量子化 */
ryoushika(int levo[], double x[])
{
register int i;
for(i = 0; i < U; i++)
if(x[i] < 0.1)
levo[i] = 0;
else
if(x[i] < 0.25)
levo[i] = 1;
else
if(x[i] < 0.5)
levo[i] = 2;
else
if(x[i] < 0.75)
levo[i] = 3;
else
if(x[i] < 0.90)
levo[i] = 4;
else
levo[i] = 5;
}
/* カオスニューロンの入力と出力が等しいかどうかを量子化値を用いて比較 */
int hikaku(int levo[], int levn[])
{
register int i;
for(i = 0; i < U; i++)
if(levo[i] != levn[i])
return 1;
return 0;
}
/* カオスニューロンの出力計算 */
neuro(double x[],double m[], double n[], double w[][U])
{
register int i,j;
register double kas;
for(i=0; i<U; i++){
kas = 0.0;
for(j = 0; j < U; j++)
kas += (w[i][j] * x[j]);
m[i] = rsnp * kas + km * m[i];
n[i] = -alp * x[i] + kr * n[i] + gaib;
x[i] = fout((m[i] + n[i]) / eps);
}
}
/* Pattern File からのデータの取り込み,Result File へデータ出力 */
int torikomi(long shoki, int out_in[][U], FILE *fp, FILE *fd,
const char *pfn)
{
int i,j,naiseki,nyuu;
for(i=0; i<PATTERN; i++){
/* 何番目のパターンかを表示 */
fprintf(fd,"p%d\n",i);
for(j=0; j<U; j++){
/* Pattern File からパターンの要素を順に入力 */
if((nyuu=fscanf(fp,"%d",&out_in[i][j]))==0 || nyuu==EOF){
/* Pattern File のデータ形式が正しくない場合 */
fl_set_object_lcol(str,FL_BLACK);
fl_activate_object(str);
fl_show_alert("Sorry","Bad Format File!",pfn,0);
return -1;
}
/* Result File へパターンの要素を順に出力 */
fprintf(fd,"%d ",out_in[i][j]);
if(j%10 == 9)
fprintf(fd,"\n");
}
fprintf(fd,"\n");
}
j = 1;
/* 相関内積のデータ数の計算 */
for(i=1; i<PATTERN; i++)
j *= i;
for(i=0; i<j; i++){
/* Pattern File から相関内積値を順に出力 */
if((nyuu=fscanf(fp,"%d",&naiseki)) == 0 || nyuu == EOF){
/* Pattern File のデータ形式が正しくない場合 */
fl_set_object_lcol(str,FL_BLACK);
fl_activate_object(str);
if(nyuu)
/* Pattern File に相関内積値がない場合 */
fl_show_alert("Sorry","No Inner Product!",pfn,0);
else
/* Pattern File に数字以外の文字が含まれている場合 */
fl_show_alert("Sorry","Bad Format File!",pfn,0);
return -1;
}
/* まだ内積値を Result File に出力していない場合,内積値を示す n を出力 */
if(i==0) fprintf(fd,"n");
/* Pattern File に内積値を出力 */
fprintf(fd,"\t%3d ",naiseki);
}
/* Result File に Pattern Number (s), Search Number (sn) を出力 */
fprintf(fd,"\n\ns\t%lu\nsn\t%3d\n\n",shoki,shoki_n);
return 0;
}
/* 出力パターンと検索パターンとの距離計算と,シナプス前抑制関数の出力計算 */
kyori(double x[],int out_in[][U])
{
register int i;
z=0;
for(i=0; i<U; i++)
/* パターンの要素ごとの距離の絶対値を加算 */
z += fabs(x[i] - (double)out_in[search][i]);
/* 距離計算 */
z /= U;
/* 距離からシナプス前抑制関数の出力計算 */
if(z < gs)
rsnp = 1;
else
rsnp = rcha;
}
/* Passage File への出力 */
keika(int levo[], int times, int hi, FILE *fk)
{
register int i;
/* 各変数の出力 */
fprintf(fk,"t=%d time=%d hi=%d rsnp=%1.3lf z=%1.3lf\n",kai,times,hi,rsnp,z);
/* 出力パターンの出力 */
for(i=0; i<U; i++){
fprintf(fk,"%d ",levo[i]);
if(i%10 == 9)
fprintf(fk,"\n");
}
fprintf(fk,"\n");
}
/* Result File, Passage File に指定されているファイルを開く時に
呼び出される関数 */
FILE *file_write(int *fw, int fs)
{
const char *fname;
FILE *f;
char q1[200],q2[200],sys[150],dir[100];
int i,dirf;
/* Result File, Passage File のどちらを開くか判定し,fname へ入力 */
if(fs)
fname=fl_get_input(rfl);
else
fname=fl_get_input(pfl);
if((f=fopen(fname,"w"))==NULL){
/* fname のファイルが開けない場合 */
if(fs)
sprintf(q1,"I don't write in this Result File!");
else
sprintf(q1,"I don't write in this Passage File!");
sprintf(q2,"Do you want to do 'chmod u+w %s'?",fname);
/* fname のファイルに書き込み許可を与えるかどうかを選択 */
if(fl_show_question(q1,fname,q2)){
fclose(f);
/* fname のファイルに書き込み許可を与える */
sprintf(sys,"chmod u+w %s",fname);
system(sys);
}
else
/* No を選択した場合,検索を終了 */
goto w_fail;
if((f=fopen(fname,"w"))==NULL){
/* まだファイルが開けない場合 */
/* 指定したファイルがあるディレクトリを調べ,dir へ入力 */
dirf=0;
for(i=0; *(fname+i)!='\0'; i++){
if((dir[i]=*(fname+i))=='/') dirf=i;
}
dir[dirf]='\0';
/* dir に入力されているディレクトリを作るかどうかを選択 */
sprintf(q1,"Do you want to do 'mkdir %s'?",dir);
if(fl_show_question("I failed to do 'chmod'!",q1,"")){
fclose(f);
/* dir に入力されているディレクトリを作成 */
sprintf(sys,"mkdir %s",dir);
system(sys);
}
else
/* No を選択した場合,検索を終了 */
goto w_fail;
if((f=fopen(fname,"w"))==NULL){
/* まだファイルが開けない場合 */
/* dir に入力されているディレクトリに書き込み・実行許可を
与えるかどうかを選択 */
sprintf(q1,"Do you want to do 'chmod u+wx %s'?",dir);
if(fl_show_question("I failed to do 'mkdir'!",q1,"")){
fclose(f);
sprintf(sys,"chmod u+wx %s",dir);
system(sys);
}
else
/* No を選択した場合,検索を終了 */
goto w_fail;
if((f=fopen(fname,"w"))==NULL){
/* なお,まだファイルが開けない場合,警告を出して終了 */
fl_show_alert("Sorry","I failed to do 'chmod'!!","",0);
w_fail:
/* START ボタンを動作可能にする */
fl_set_object_lcol(str,FL_BLACK);
fl_activate_object(str);
/* ファイルを開けなかったことを示す */
*fw=1;
return f;
}
}
}
}
/* 正常にファイルを開けたことを示す */
*fw=0;
/* 得られたファイルポインタを
fd (Result File) または fk (Passage File) へ入力 */
return f;
}