/* 内部記憶をもつ形の想起 */
/* 定数をランダムにしたり適当にいれて想起 */
#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 );
}
}