#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <local/bgi.h>
#define S 3 /*始めに覚えるパターンの数*/
#define Z 49 /*ニューロンの総数*/
#define Kr 0.95 /*外部入力の係数*/
#define Ks 0.99 /*相互結合の係数*/
#define Km 0.1 /*不応性の係数*/
#define a 2.0 /*不応性の係数*/
#define v 2.0 /*外部入力の係数*/
#define Q 0.0 /*閾値*/
#define A 7 /*ニューロンの縦の数*/
#define ll 7 /*ニューロンの横の数*/
#define kkk 6
#define Vth 50 /*変化量の閾値*/
#define ZZ 50 /*離散時間の総数*/
#define E 0.015 /*シグモイド関数の係数*/
#define AA 50
#define BB 100
#define CC 150
#define DD 175 /*各外部入力の離散時間の数*/
#define EE 200
#define FF 225
#define GG 250
#define HH 275
static char tim[ZZ];
FILE *e;
FILE *f1;
FILE *ff;
FILE *ee;
FILE *f2;
char c[10];
char ccc[10];
char mm[Z];
char gg[Z];
void kazyu1(); /*始めに覚えるパターンを読み込む*/
void kazyu2(); /*結合荷重を計算する*/
void kazyu3(); /*新しいパターンを読み込む*/
void gaibu(); /*外部入力の計算*/
void sougo(); /*相互結合の計算*/
void fuou(); /*不応性の計算*/
void keisan(); /*ニュウロンの出力の計算*/
void hanbetu1(); /*外部入力と相互結合、不応性の影響力*/
void hanbetu2(); /*変化量の計算*/
void hanbetu3(); /*入力パターンの変化の判別*/
void kakikomi(); /*ファイルに書き込む*/
void syuturyoku(); /*グラフィクで表す*/
void graf(); /*グラフを書く*/
double drand48();
int t,oo,ooo,r,tt,ttt,yy,ss,rr,onazi,onazi1;
int w[Z][Z],m[ZZ][Z],mnoi[ZZ][Z],mnoi1[ZZ][Z],mnoi2[Z],g[10][Z],xx[ZZ][Z];
double V,yyy;
double xdata[ZZ],xnoi[ZZ],xnoi2[ZZ];
double n[ZZ][Z],nn[ZZ][Z],nnn[ZZ][Z],x[ZZ][Z];
/*メインプログラム*/
main()
{
ff=fopen("AS1.DAT","w");
ee=fopen("MITI.DAT","w");
t=0;
ooo=0;
tt=0;
ttt=0;
r=S;
kazyu1();
kazyu2();
printf("ノイズなら 1 欠落させるなら0 ");
scanf("%d",&ss);
if(ss==1)
printf("何個 ノイズをいれる ");
else
printf("何個 欠落させる ");
scanf("%d",&yy);
while(ttt<ZZ)
{
gaibu();
hanbetu3();
sougo();
fuou();
keisan();
hanbetu1();
kakikomi();
t=t+1;
ttt=ttt+1;
if(oo==Z)
hanbetu2();
if(ooo==1)
{
kazyu3();
kazyu2();
ooo=0;
}
}
syuturyoku();
graf();
fclose(ff);
fclose(ee);
}
/*結合荷重割り当て*/
void kazyu3()
{
int i,j;
if(ooo==1)
{
for(rr=0;rr<r;rr++)
{
onazi=0;
for(i=0;i<Z;i++)
if(g[rr][i]==xx[tt][i])
onazi=onazi+1;
if(onazi==Z)
onazi1=1;
}
if(onazi1!=1)
{
for(i=0;i<Z;i++)
g[r][i]=xx[tt][i];
fprintf(ee,"\n");
for(i=0;i<Z;i++)
if(g[r][i]==1)
gg[i]='#';
else
gg[i]=':';
j=0;
for(i=0;i<Z;i++)
if(j==kkk)
{
fprintf(ee,"%c\n",gg[i]);
j=0;
}
else
{
fprintf(ee,"%c",gg[i]);
j=j+1;
}
r=r+1;
}
}
}
void kazyu1()
{
int b,i,j,o,l,y,aa,d,h,hh,k,xx;
i=0;j=0;b=0;o=0;
e=fopen("HAM.DAT","r");
for(h=0;h<r;h++)
{
b=0;
for(j=0;j<A;j++)
{
fscanf(e,"%s",ccc);
for(l=0;l<ll;l++)
{
if (ccc[l]=='#')
xx=1;
else
xx=-1;
g[h][l+b]=xx;
}
b=b+ll;
}
}
fclose(e);
}
void kazyu2()
{
int i,j,y,aa,d,h;
for(i=0;i<Z;i++)
for(j=0;j<Z;j++)
{
d=0;
if(i!=j)
for(h=0;h<r;h++)
{
y=g[h][i];
aa=g[h][j];
d=d+aa*y;
}
else
d=0;
w[i][j]=d;
}
}
/*外部入力*/
void gaibu()
{
int bb,b,l,i,j,cc,aa,kaz,kazu1,dame,noi3;
double noi,noi1,noi2[Z];
if(ttt<AA)
f1=fopen("DATA66.DAT","r");
if(AA-1<ttt && ttt<BB)
f1=fopen("DATA888.DAT","r");
if(BB-1<ttt && ttt<CC)
f1=fopen("DATA999.DAT","r");
if(CC-1<ttt && ttt<DD)
f1=fopen("DATA66.DAT","r");
if(DD-1<ttt && ttt<EE)
f1=fopen("DATA77.DAT","r");
if(EE-1<ttt && ttt<FF)
f1=fopen("DATA44.DAT","r");
if(FF-1<ttt && ttt<GG)
f1=fopen("DATA55.DAT","r");
if(GG-1<ttt && ttt<HH)
f1=fopen("DATA888.DAT","r");
if(HH-1<ttt && ttt<ZZ)
f1=fopen("DATA999.DAT","r");
b=0;
for(j=0;j<A;j++)
{
fscanf(f1,"%s",c);
for(l=0;l<ll;l++)
{
if(c[l]=='#')
cc=1;
else
cc=-1;
m[ttt][l+b]=cc;
}
b=b+ll;
}
kaz=1;
i=1;
noi=drand48();
noi1=noi*48;
noi2[0]=(int)noi1;
while(kaz<yy)
{
kazu1=0;
while(kazu1<1)
{
noi=drand48(); /*ノイズを入れる*/
noi1=noi*49;
noi3=(int)noi1;
if(noi3==49)
noi3=48;
dame=0;
for(j=0;j<i;j++)
if(noi2[j]==noi3)
dame=dame+1;
if(dame==0)
{
kazu1=1;
noi2[i]=noi3;
}
else
kazu1=0;
}
kaz=kaz+1;
i=i+1;
}
for(i=0;i<Z;i++)
mnoi[ttt][i]=m[ttt][i];
for(i=0;i<yy;i++)
{
aa=noi2[i];
if(ss==1)
if(mnoi[ttt][aa]==1)
mnoi[ttt][aa]=-1;
else
mnoi[ttt][aa]=1;
else
mnoi[ttt][aa]=0;
}
for(i=0;i<Z;i++)
if(mnoi[ttt][i]>0)
mnoi1[ttt][i]=1;
else
mnoi1[ttt][i]=-1;
for(i=0;i<Z;i++)
{
if(t==0)
n[t][i]=v*mnoi[ttt][i];
else
n[t][i]=Ks*n[t-1][i]+v*mnoi[ttt-1][i];
}
fclose(f1);
}
/*ニューロン間の相互結合*/
void sougo()
{
int i,j;
double p,pp;
for(i=0;i<Z;i++)
{
if(t==0)
{
p=0;
for(j=0;j<Z;j++)
p=w[i][j]*mnoi[ttt][j]+p;
nn[t][i]=p;
}
else
{
pp=0;
for(j=0;j<Z;j++)
pp=w[i][j]*x[ttt-1][j]+pp;
nn[t][i]=Km*nn[t-1][i]+pp;
}
}
}
/*ニューロン自身の不応性*/
void fuou()
{
int i,j;
for(i=0;i<Z;i++)
if(t==0)
nnn[t][i]=-a*mnoi[ttt][i]-Q;
else
nnn[t][i]=Kr*nnn[t-1][i]-a*x[ttt-1][i]-Q;
}
/*ニューロンの計算*/
void keisan()
{
int i,j;
double uu;
uu=0.0;
for(i=0;i<Z;i++)
{
if(t==0)
x[ttt][i]=mnoi[ttt][i];
else
{
uu=n[t][i]+nn[t][i]+nnn[t][i];
x[ttt][i]=2/(1+exp(-uu/E))-1;
}
if(x[ttt][i]>0)
xx[ttt][i]=1;
else
xx[ttt][i]=-1;
}
}
/*書き込み*/
void kakikomi()
{
int q[Z],i,j;
for(i=0;i<Z;i++)
if(x[ttt][i]>0)
q[i]=1;
else
q[i]=-1;
for(i=0;i<Z;i++)
if(q[i]==1)
mm[i]='#';
else
mm[i]=':';
j=0;
for(i=0;i<Z;i++)
{
if(j==kkk)
{
fprintf(ff,"%c\n",mm[i]);
j=0;
}
else
{
fprintf(ff,"%c",mm[i]);
j=j+1;
}
}
fprintf(ff,"\n");
}
/*未知パターン、既知パターンの判別*/
void hanbetu1()
{
int i,j;
double u,z;
oo=0;
for(i=0;i<Z;i++)
{
u=fabs(n[t][i]);
z=fabs(nn[t][i]+nnn[t][i]);
if(u>z)
oo=oo+1;
}
}
void hanbetu2()
{
int h,i,j;
V=0;
for(h=tt+2;h<ttt;h++)
for(i=0;i<Z;i++)
V=fabs(x[h][i]-x[h-1][i])+V;
if(V>Vth)
{
ooo=1;
tt=ttt-1;
}
else
ooo=0;
}
void hanbetu3()
{
int i,j,zz;
zz=0;
if(ttt!=0)
for(i=0;i<Z;i++)
if(m[ttt][i]!=m[ttt-1][i])
zz=zz+1;
if(zz>9)
{
t=0;
tt=ttt;
gaibu();
}
}
/*グラフィックを描く */
void syuturyoku()
{
int Gd,Gm,i,ii,jj,kai,ka,kka,kki,ki,ku,ke;
int dd,ddd,tttt,v1,v2,v3,v4;
ka=100;
ki=100;
kka=150;
kki=150;
ku=300;
ke=300;
initgraph(Gd,Gm,"1140x960");
settextfont("7x14");
for(tttt=0;tttt<ZZ;tttt++)
{
sprintf(tim,"t=%u",tttt);
ddd=tttt%25;
if(ddd==0)
dd=tttt/25*80;
ka=ddd*45+2+10;
ki=76+dd+2;
outtextxy(ka,ki,tim);
v1=ddd*45+1+10;
v2=dd+1;
v3=ddd*45+37+10;
v4=dd+1;
line(v1,v2,v3,v4);
v1=ddd*45+1+10;
v2=dd+1;
v3=ddd*45+1+10;
v4=dd+65;
line(v1,v2,v3,v4);
v1=ddd*45+37+10;
v2=dd+1;
v3=ddd*45+37+10;
v4=dd+65;
line(v1,v2,v3,v4);
v1=ddd*45+1+10;
v2=dd+65;
v3=ddd*45+37+10;
v4=dd+65;
line(v1,v2,v3,v4);
for(ii=0;ii<7;ii++)
for(jj=0;jj<7;jj++)
if(xx[tttt][ii*7+jj]==-1)
{
ka=jj*5+2+ddd*45+2+10;
ki=ii*9+3+dd+2;
putpixel(ka,ki,WHITE);
ka=jj*5+2+ddd*45+2+10;
ki=ii*9+4+dd+2;
putpixel(ka,ki,WHITE);
}
else
{
kka=jj*5+ddd*45+2+10;
kki=ii*9+dd+2;
ku=jj*5+4+ddd*45+2+10;
ke=ii*9+8+dd+2;
bar(kka,kki,ku,ke);
}
}
graph2xbm("output2.xbm");
while(!kbhit());
closegraph();
}
/*グラフを描く*/
void graf()
{
char moji = '"';
static char str[] = "TitleText:";
int i,danoi,daanoi;
double da,daa,daa2,daa1;
for(ttt=0;ttt<ZZ;ttt++)
{
da=0;
daa=0;
danoi=0;
daanoi=0;
for(i=0;i<Z;i++)
{
da=(double)m[ttt][i]*x[ttt][i]+da;
daa1=(double)abs(m[ttt][i]);
daa2=fabs(x[ttt][i]);
daa=daa1*daa2+daa;
danoi=m[ttt][i]*mnoi[ttt][i]+danoi;
daanoi=abs(m[ttt][i])*abs(mnoi[ttt][i])+daanoi;
}
xdata[ttt]=da/daa;
xnoi[ttt]=(double)danoi/(double)daanoi;
}
f2=fopen("data2.dat","w");
if(ss==1)
fprintf(f2,"%s Noizu Data\n",str);
else
fprintf(f2,"%s Keturaku Data\n",str);
fprintf(f2,"%c |A| \n",moji);
for(ttt=0;ttt<ZZ;ttt++)
{
fprintf(f2,"%d",ttt);
fprintf(f2,"%c",' ' );
fprintf(f2,"%f\n",xdata[ttt]);
}
fprintf(f2,"\n");
fprintf(f2,"%c |A|+|B+C|\n",moji);
for(ttt=0;ttt<ZZ;ttt++)
{
fprintf(f2,"%d",ttt);
fprintf(f2,"%c",' ' );
fprintf(f2,"%f\n",xnoi[ttt]);
}
fprintf(f2,"\n");
fprintf(f2,"%c |A+B+C| \n",moji);
for(ttt=0;ttt<ZZ;ttt++)
{
fprintf(f2,"%d",ttt);
fprintf(f2,"%c",' ' );
fprintf(f2,"%f\n",xnoi2[ttt]);
}
fclose(f2);
}