/* 内部記憶をもつ形の想起 */ /* 定数をランダムにしたり適当にいれて想起 */ #include <stdio.h> /* ヘッダ */ #include <stdlib.h> #include <string.h> #include <math.h> #define RECALL #include "grobal.h" /* 自作のヘッダ */ #include "protfunc.h" #include "funcdef.h" int main( int argc , char **argv ){ srand48( Seed ); /* 乱数の設定 */ options_recall( argc , argv ); /* オプション */ load_prm( fi_weight ); /* 結合荷重を読み込む */ set_teach( Data ); /* 教師信号を読み込む */ set_file(); /* 出力ファイルの設定 */ set_input(); /* 入力値の設定 */ recall(); /* 実際に想起を行なう */ sort(); /* 曲の順序を並べかえる */ output_file(); /* ファイルに出力する */ output_song(); /* 曲を出力する */ if( Flag_weightsearch != 0 ) weight_search(); /* 結合荷重の測定をする */ return 0; } /* オプションを決定する関数 */ void options_recall( int argc , char **argv ){ while( --argc ){ if( **++argv == '-' ){ switch( *++*argv ){ case 'r': /* 内部記憶部分をランダムにする */ Flag_random = 1; break; case 'z': /* 0にする */ if( --argc ){ Flag_zero = 1; Set_zero = atof( *++argv ); if( Set_zero < 0 ) Set_zero = 0; break; } case 's': if( --argc ){ Flag_inout = 1; /* 1にしてそれ以外を0にする */ Set_inout = atof( *++argv ); if( Set_inout < 0 ) Set_inout = 0; break; } case 'a': /* 教師信号を除去する */ Flag_teachcut = 1; break; case 'n': /* 入力にノイズをのせる */ if( --argc ){ Flag_inc = 1; Noize = atof( *++argv ); break; } default: usage: fprintf( stderr , "Usage: pout16 [-r] [-z Number] WeightFile.data\n" ); exit(-1); } } else { if( fi_weight == NULL ){ fi_weight = *argv; } else { goto usage; } } } } /* 結合荷重等の定数を読み込む関数 */ void load_prm( char *filename ){ FILE *fp; size_t wsize; int i; if( filename != NULL ){ if(( fp = fopen( filename , "r" )) == NULL ){ fprintf( stderr , "Can't Open %s\n" , filename ); exit(1); } } else { fp = stdin; } wsize = sizeof( double ); /* 各定数を読み込む */ fread( inout , wsize , Inunit * Time , fp ); fread( inkeep , wsize , Inunit * Time , fp ); fread( wim , wsize , Inunit * Midunit , fp ); fread( wmo , wsize , Midunit * Outunit , fp ); fread( sikiiim , wsize , Midunit ,fp ); fread( sikiimo , wsize , Outunit ,fp ); fclose( fp ); } /* 入力データを設定する */ void set_input(){ int i; if( Flag_random != 0 ){ /* 内部記憶部分をランダムにする */ for( i = TLC ; i < Inunit ; i++ ){ inout[i][0] = quantum( qrand() ); } } if( Flag_zero != 0 ){ /* 値を0にする */ for ( i = TLC + Set_zero ; i < Inunit ; i++ ){ inout[i][0] = 0.0; } } if( Flag_inout != 0 ){ /* 1にしてそれ以外を0にする */ for( i = TLC ; i < Inunit ; i++ ){ inout[i][0] = 0.0; } inout[Set_inout][0] = 1.0; } } /* 実際に想起を行なう関数 */ void recall(){ int i,j; int g,h; /* 想起部分 */ for( k = 0 ; k < Souki ; k++ ){ if( k == 0 ){ for( i = 0 ; i < TLC ; i++ ){ if( Flag_teachcut != 0 ){ /* 第1音を与えない */ inout[i][0] = 0; } else { inout[i][0] = inkeep[i][0]; } } if( Flag_inc != 0 ) inout[0][0] = inout[0][0] + Noize; /* ノイズを含める */ if( Flag_view != 0 ) input_view(); /* 状態を表示 */ } for( t = 0 ; t < tsmax ; t++ ){ g = t + 1; if( g >= tsmax ) g = 0; h = t - 1; if( h < 0 ) h = tsmax - 1; for( j = 0 ; j < Outunit ; j++ ){ outkeep[j] = outout[j]; } switch( Flag_caos ){ case 1 : caos_forward_propagation(); /* カオスNNを利用した想起 */ default : forward_propagation(); } if( k == Souki - 1 ) plot_func(); /* 重みと結合荷重の特性をとる */ output_correct(); /* 量子化を行なう */ if( k % 1000 == 0 && Flag_view != 0 ) printf( "%f %f %f %f\n",outout[0],outout[1],inkeep[0][t],inkeep[1][t] ); feedback(); /* フィードバックする */ for( j = 0 ; j < Tunit ; j++ ){ /* 出力値を保存しておく */ songkeep[j][t] = outout[j]; } } } } /* 環境状況を標準出力する */ void input_view(){ int i; printf( "Tunit\n" ); /* 教師信号の値を確認 */ printf( "%f %f\n" , inout[0][0] , inout[1][0] ); printf( "Lunit\n" ); /* 補助入力層の値を確認 */ for( i = Tunit ; i < TL ; i = i + 4 ){ printf( "%f %f %f %f\n" , inout[i][0] , inout[i + 1][0] , inout[i + 2][0] , inout[i + 3][0] ); } printf( "Cunit\n" ); for( i = TL ; i < TLC ; i = i + 4 ){ printf( "%f %f %f %f\n" , inout[i][0] , inout[i + 1][0] , inout[i + 2][0] , inout[i + 3][0] ); } printf( "Nunit\n" ); /* 内部記憶層の値を確認 */ for( i = TLC ; i < TLCN ; i = i + 4 ){ printf( "%f %f %f %f\n" , inout[i][0] , inout[i + 1][0] , inout[i + 2][0] , inout[i + 3][0] ); } printf( "Eunit\n" ); for( i = TLCN ; i < Inunit ; i = i + 4 ){ printf( "%f %f %f %f\n" , inout[i][0] , inout[i + 1][0] , inout[i + 2][0] , inout[i + 3][0] ); } printf( "\n" ); } /* 想起した曲をファイルに出力する */ void output_song(){ int i; for( t = 0 ; t < tsmax ; t++ ){ fprintf( fpsong , "%f %f\n",song[0][t] , song[1][t] ); } fclose( fpsong ); } /* カオスNNを用いたフォワードプロパゲーション */ void caos_forward_propagation(){ int i,j; double sum; for( i = 0 ; i < Midunit ; i++ ){ sum = 0; for( j = 0 ; j < Inunit ; j++ ){ sum += wim[i][j] * inout[j][t]; } old_em[i] = em[i]; em[i] = km * old_em[i] + sum; old_zm[i] = zm[i]; old_midout[i] = midout[i]; zm[i] = kr * zm[i] - al * old_midout[i]; midout[i] = fsig( em[i] + zm[i] + sikiiim[i] ); } for( i = 0 ; i < Outunit ; i++ ){ sum = 0; for( j = 0 ; j < Midunit ; j++ ){ sum += wmo[i][j] * midout[j]; } outout[i] = fsig( sum + sikiimo[i] ); } } /* 想起された曲をならびかえる */ void sort(){ int i,k; int set; int delay_s; int flag_minus = 0; /* 位相差の測定 */ for( i = 0 ; i < tsmax ; i++ ){ if( songkeep[0][i] == 1.0 ) delay_s = i + 1; /* 最終音1.0を基準に */ if( delay_s >= tsmax / 2 ){ /* この条件ちょっとおかしい */ delay_s = tsmax - i - 2; flag_minus = 1; } } if( flag_minus != 0 ){ printf( "delay = - %d\n" ,delay_s ); } else { printf( "delay = %d\n" ,delay_s ); } /* 並び替えを行なう */ set = 0; for( i = 0 ; i < tsmax ; i++ ){ if( songkeep[0][i] == 1.0 ){ /* 最終音1.0を基準に */ set = i; break; } else { set = 0; /* なければそのまま */ } } for( i = 0 , k = set + 1 ; i < tsmax ; i++ , k++ ){ if( k >= tsmax ) k = 0; song[0][i] = songkeep[0][k]; song[1][i] = songkeep[1][k]; } } /* ファイルに出力する */ void output_file(){ int i,j; for( i = TLC ; i < TLCN ; i++ ){ /* 内部記憶層の出力を保存 */ for( j = 0 ; j < tsmax ; j++ ){ fprintf( fpnaibu , "%f\n" , inout[i][j] ); } } fclose( fpnaibu ); if( Flag_timenaibu != 0 ){ /* 内部記憶層のt - t+1 特性の保存 */ for( i = TLC ; i < TLCN ; i++ ){ for( j = 0 ; j < tsmax ; j++ ){ if( j >= tsmax - 1 ){ fprintf( fpnaibu2 , "%f %f\n" , inout[i][j] , inout[i][0] ); } else { fprintf( fpnaibu2 , "%f %f\n" , inout[i][j] , inout[i][j + 1] ); } } } } fclose( fpnaibu2 ); if( Flag_weightplot != 0 ){ /* 各結合荷重の保存 */ for( j = 0 ; j < Midunit ; j++ ){ for( i = 0 ; i < TLC ; i++ ){ fprintf( fpweight_tm , "%f " , wim[j][i] ); } fprintf( fpweight_tm , "\n" ); for( i = TLC ; i < Inunit ; i++ ){ fprintf( fpweight_nm , "%f " , wim[j][i] ); } fprintf( fpweight_nm , "\n" ); for( i = 0 ; i < TLC ; i++ ){ fprintf( fpweight_mt , "%f " , wmo[i][j] ); } fprintf( fpweight_mt , "\n" ); for( i = TLC ; i < Outunit ; i++ ){ fprintf( fpweight_mn , "%f " , wmo[i][j] ); } fprintf( fpweight_mn , "\n" ); } fclose( fpweight_tm ); fclose( fpweight_nm ); fclose( fpweight_mt ); fclose( fpweight_mn ); } } /* 結合荷重の積(=入力に1を与えた時の影響)を測定する */ void weight_search(){ int i , j , k; double indata[Inunit][TLC]; double sum; char fi[Smax]; FILE *fp; sprintf( fi , "kekka19/song/wsearch_ver%d.dat" ,Filenumber ); fp = fopen( fi ,"w" ); if( fp == NULL ){ fprintf( stderr, "File not open!\n" ); exit(1); } for( k = 0 ; k < TLC ; k++ ){ for( i = 0 ; i < Inunit ; i++ ){ sum = 0; for( j = 0 ; j < Midunit ; j++ ){ sum += wim[j][i] * wmo[k][j]; } indata[i][k] = sum; } } for( j = 0 ; j < Inunit ; j++ ){ for( i = 0 ; i < TLC ; i++ ){ fprintf( fp , "%f " , indata[j][i] ); } fprintf( fp , "\n" ); } fclose( fp ); } void plot_func(){ int i,j; if( Flag_weightplot02 != 0 ){ /* 出力値-結合荷重特性 */ for( j = 0 ; j < TLC ; j++ ){ for( i = 0 ; i < Midunit ; i++ ){ fprintf( fpweight02_mt , "%f %f\n" , outout[j] , wmo[j][i] ); } } for( j = TLC ; j < Outunit ; j++ ){ for( i = 0 ; i < Midunit ; i++ ){ fprintf( fpweight02_mn , "%f %f\n" , outout[j] , wmo[j][i] ); } } for( j = 0 ; j < Midunit ; j++ ){ for( i = 0 ; i < TLC ; i++ ){ fprintf( fpweight02_tm , "%f %f\n" , midout[j] , wim[j][i] ); } for( i = TLC ; i < Inunit ; i++ ){ fprintf( fpweight02_nm , "%f %f\n" , midout[j] , wim[j][i] ); } } fclose( fpweight02_tm ); fclose( fpweight02_nm ); fclose( fpweight02_mt ); fclose( fpweight02_mn ); } }