サーチアクセスに関する関数についてのソースファイルである。
#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; }