/* PC9801でコンパイルする場合は下の1行のコメントを外す */
/* #define __PC9801__ */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(__TURBOC__) && defined(__MSDOS__)
#include <alloc.h>
#include <graphics.h>
#else
#include <local/bgi.h>
#endif
#define U 100
#define PATTERN 6
#define M 3
#define SOUKITIME 15
#define No_IUnits 100
#define No_HUnits 10
#define No_OUnits 2
#define r_No_IUnits 4
#define r_No_HUnits 4
#define r_No_OUnits 1
#define CTRL(x) ((x) - '@')
#define fout(x) (1 / (1 + exp(-(x))))
static int levo[U], levn[U],
kai, ko, ka, ki, kka, kki, ku, ke, jik, time, hi, jyoutai,
page, retsu, outend, until;
static char par[256], tim[256], fname[256], size[256];
static double alp, eps, sok, km, kr, rcha, xold[U], xnew[U], m[U], n[U],
#if defined(__TURBOC__) && defined(__MSDOS__)
far *w[U],
#else
w[U][U],
#endif
gaib;
double out_hid[No_HUnits], out_out[No_OUnits];
double witoh[No_HUnits][No_IUnits], dwitoh[No_HUnits][No_IUnits];
double witoo[No_OUnits][No_HUnits], dwitoo[No_OUnits][No_HUnits];
double hbias[No_HUnits], dhbias[No_HUnits];
double obias[No_OUnits], dobias[No_OUnits];
double r_out_in[16][4], r_out_hid[r_No_HUnits], r_out_out[r_No_OUnits];
double r_witoh[r_No_HUnits][r_No_IUnits], r_dwitoh[r_No_HUnits][r_No_IUnits];
double r_witoo[r_No_OUnits][r_No_HUnits], r_dwitoo[r_No_OUnits][r_No_HUnits];
double r_hbias[r_No_HUnits], r_dhbias[r_No_HUnits];
double r_obias[r_No_OUnits], r_dobias[r_No_OUnits];
double out_in[6][U] = {
{1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
0, 1, 1, 1, 0, 0, 1, 1, 1, 0,
0, 0, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 0, 0,
0, 1, 1, 1, 0, 0, 1, 1, 1, 0,
1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
0, 0, 1, 1, 1, 0, 1, 1, 1, 0,
0, 0, 1, 1, 0, 0, 0, 1, 1, 0,
0, 1, 1, 1, 0, 0, 0, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 1, 1, 1, 0, 0, 0, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 1, 0, 0,
1, 1, 0, 0, 0, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0, 0, 1, 1,
0, 0, 1, 1, 1, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 0, 0, 0, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
0, 0, 1, 1, 0, 0, 1, 1, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 0, 1, 1,
0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 1, 0, 1, 1, 0, 0, 0,
0, 0, 1, 1, 0, 1, 1, 0, 0, 0,
1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
1, 0, 0 ,1, 0, 0, 1, 0, 0, 1,
1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 1, 1, 1, 1,
1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
1, 1, 1, 1, 0, 0, 1, 1, 1, 1},
};
int next(int);
void soukan(void);
void shoki(void);
void ryoushika(void);
int hikaku(void);
void output(unsigned int);
void tokuchou_output(void);
void neuro(int);
void kentou(void);
void beep(void);
#if defined(__TURBOC__) && defined(__MSDOS__)
void clean_up(void);
void graph2xbm(char *s);
void clean_up(void)
{
int i;
for(i = 0; i < U; i++)
farfree(w[i]);
}
#pragma warn -par
void graph2xbm(char *s)
{
/* dummy */
}
#pragma warn +par
#endif
int next(p)
int p;
{
if(((p + 1) % M) == 0)
return (p + 1 - M);
else return (p + 1);
}
void soukan()
{
int i, j, k;
for(j = 0; j < U; j++) {
for(k = 0; k < U; k++) {
w[j][k] = 0.0;
}
}
for(i = 0; i < PATTERN; i++) {
for(j = 0; j < U ; j++) {
for(k = 0; k < U ; k++) {
w[j][k] += sok * (2 * out_in[next(i)][j] - 1)
* (2 * out_in[i][k] - 1);
}
}
}
}
void shoki()
{
int i;
for(i = 0; i < U; i++){
xold[i] = 0.8 * 0.8 * out_in[jyoutai][i];
m[i] = n[i] = 0.0;
}
}
void ryoushika()
{
int i;
for(i = 0; i < U; i++){
if(xold[i] < 0.1) {
levo[i] = 0;
} else if(xold[i] < 0.25) {
levo[i] = 1;
} else if(xold[i] < 0.5) {
levo[i] = 2;
} else if(xold[i] < 0.75) {
levo[i] = 3;
} else if(xold[i] < 0.9) {
levo[i] = 4;
} else {
levo[i] = 5;
}
}
}
/*
int hikaku()
{
int i;
for(i = 0; i < U; i++) {
if(levo[i] != levn[i])
return(1);
}
return(0);
}
*/
void output(kai)
unsigned int kai;
{
int i, j, cc;
if(ko == 0) {
if(kai != 0) {
cc = getchar();
if(cc == 'p'){
graph2xbm(fname);
page++;
sprintf(fname, "bitmap/cy%d%d_%d.xbm",
jyoutai, page,until);
} else if(cc == 'q') {
closegraph();
exit(0);
}
}
cleardevice();
if(kai == 0)
outtextxy(10, 23, par);
}
sprintf(tim, "t=%u", kai);
ka = 10 + (ko % retsu) * 150;
ki = 50 + ((int)(ko / retsu)) * 152;
outtextxy(ka, ki, tim);
for(i = 0; i < 10; i++){
for(j = 0; j < 10; j++){
if(i == 0 && j == 0) {
kka = ka;
kki = ki;
}
if(levo[10 * i + j] == 0) {
ka = j * 11 - levo[10 * i + j]
+ 15 + (ko % retsu) * 150;
ki = i * 11 + 60 + (int)(ko / retsu) * 152;
putpixel(ka, ki, WHITE);
} else {
ka = j * 11 - levo[10 * i + j]
+ 15 + (ko % retsu) * 150;
ki = i * 11 - levo[10 * i + j]
+ 60 + ((int)(ko / retsu)) * 152;
ku = j * 11 + levo[10 * i + j]
+ 15 + (ko % retsu) * 150;
ke = i * 11 + levo[10 * i + j]
+ 60 + ((int)(ko / retsu)) * 152;
bar(ka, ki, ku, ke);
}
}
}
ko++;
for(i = 0; i < U; i++)
levn[i] = levo[i];
if(ko % outend == 0)
ko = 0;
}
/*
void tokuchou_output()
{
int i, j;
i = 0;
for (j = 0; j < U; j++)
out_in[i][j] = xold[j];
if(time == SOUKITIME){
kentou();
}
}
*/
void neuro(i)
int i;
{
int j;
double kas = 0.0;
for(j = 0; j < U; j++)
kas += (rcha * w[i][j] * xold[j]);
m[i] = kas + km * m[i];
n[i] = -alp * xold[i] + kr * n[i] + gaib;
#if 0
printf("%f\n", (m[i] + n[i]) / eps);
printf("exp: %f\n", exp(-(m[i] + n[i]) / eps));
#endif
xnew[i] = fout((m[i] + n[i]) / eps);
}
void kentou()
{
int cc;
printf("Search!!\n");
printf("access_time = %d\n\n", kai - SOUKITIME);
outtextxy(kka + 70, kki, "?");
cc = getchar();
if(cc == 'p')
graph2xbm(fname);
closegraph();
exit(0);
}
void beep()
{
putchar(CTRL('G'));
}
void main(argc, argv)
int argc;
char *argv[];
{
int i, fin;
#if defined(__TURBOC__) && defined(__MSDOS__)
int gd, gm;
#else
int *gd, *gm;
#endif
/* 条件コンパイル --1にすると、cycle.cfg から以下の定数を読み込む */
#if 0
FILE *fp;
if((fp = fopen("CHAOS.CFG", "RT")) == NULL)
exit(1);
fscanf(fp, "%f", &sok);
fscanf(fp, "%f", &alp);
fscanf(fp, "%f", &eps);
fscanf(fp, "%f", &km);
fscanf(fp, "%f", &kr);
fscanf(fp, "%f", &ko);
fscanf(fp, "%f", &gaib);
fscanf(fp, "%f", &rcha);
fclose(fp);
#else
sok = 1.0/6;
alp = 10.0;
eps = 0.015;
km = 0.2;
kr = 0.9;
ko = 0;
gaib = 2.0;
rcha = 1.0;
#endif
if(argc != 6) {
fprintf(stderr, "\n\n使用法 :cycle?? <km> <kr> <初期値> <列> <割り込み回数>\n");
fprintf(stderr, " <初期値パターン> 0-バツ, 1-三角, 2-波, 3-星.4-鎖.5-花.\n");
exit(-1);
}
#if defined(__TURBOC__) && defined(__MSDOS__)
for(i = 0; i < U; i++) {
if((w[i] = (double far *)farmalloc(sizeof(double) * U))
== NULL) {
fprintf(stderr, "%s: Out of memory.\n", argv[0]);
exit(-1);
}
}
atexit(clean_up);
#endif
km = atof(argv[1]);
kr = atof(argv[2]);
jyoutai = atoi(argv[3]);
retsu = atof(argv[4]);
outend = (5 * retsu);
until = atoi(argv[5]);
sprintf(par, "km%3.2f kr=%3.2f alp=%3.1f a=%3.2f eps=%4.3f",
km, kr, alp, gaib, eps);
sprintf(fname, "bitmap/cy%d%d_%d.xbm",
jyoutai, page,until);
sprintf(size, "%dx785", retsu * 150);
#if defined(__TURBOC__) && defined(__MSDOS__)
#if defined(__PC9801__)
gd = PC98;
gm = PC98C16;
#else
gd = VGA;
gm = VGAHI;
#endif
initgraph(&gd, &gm, "");
#else
initgraph(gd, gm, size);
settextfont("12x24");
#endif
soukan();
/* 初期値パターン設定 */
shoki();
for(kai = 0; kai < 3000; kai++){
if (kai == until)
km = kr = alp = 0.0;
/* 量子化 */
ryoushika();
/* 直前の出力と比較 */
/*
hi = hikaku();
if (hi == 0)
time++;
else
time = 0;
*/
/* 画面出力 */
output(kai);
/*特徴抽出 */
/*
tokuchou_output();
*/
if(jik == 1)
break;
for(i = 0; i < U; i++)
neuro(i);
for(i = 0; i < U; i++)
xold[i] = xnew[i];
}
fin = getchar();
if(fin == 'p')
graph2xbm(fname);
closegraph();
beep();
}