tlearn 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,577 @@
1
+ #include <stdio.h>
2
+
3
+ #ifdef ibmpc
4
+ #define random() rand()
5
+ #define srandom(x) srand(x)
6
+ #endif
7
+ #ifdef THINK_C
8
+ #define random() rand()
9
+ #define srandom(x) srand(x)
10
+ #endif /* THINK_C */
11
+
12
+ double atof();
13
+
14
+ #ifdef ibmpc
15
+ extern char far *malloc();
16
+ #else
17
+ extern void *malloc();
18
+ #endif
19
+ extern int nn; /* number of nodes */
20
+ extern int ni; /* number of inputs */
21
+ extern int no; /* number of outputs */
22
+ extern int nt; /* nn + ni + 1 */
23
+ extern int np; /* ni + 1 */
24
+
25
+ extern struct cf {
26
+ int con; /* connection flag */
27
+ int fix; /* fixed-weight flag */
28
+ int num; /* group number */
29
+ int lim; /* weight limits */
30
+ float min; /* weight minimum */
31
+ float max; /* weight maximum */
32
+ };
33
+
34
+ extern struct nf {
35
+ int func; /* activation function type */
36
+ int dela; /* delay flag */
37
+ int targ; /* target flag */
38
+ };
39
+
40
+ extern struct cf **cinfo; /* (nn x nt) connection info */
41
+
42
+ extern int ngroups; /* number of groups */
43
+
44
+ extern char root[128]; /* root filename for .data, .teach, etc. files */
45
+
46
+ extern float rate; /* learning rate */
47
+ extern float momentum; /* momentum */
48
+
49
+ extern int randomly; /* flag for presenting inputs in random order */
50
+ extern int localist; /* flag for localist inputs */
51
+ extern int limits; /* flag for limited weights */
52
+
53
+ long dc = 0;
54
+ int *ldata = 0;
55
+
56
+ float *data = 0;
57
+
58
+ update_inputs(aold,tick,flag,maxtime,local)
59
+ float *aold;
60
+ int tick;
61
+ int flag;
62
+ long *maxtime;
63
+ int **local;
64
+ {
65
+ /* extern long random(); */
66
+
67
+ register int i;
68
+
69
+ int j;
70
+
71
+ long ii;
72
+
73
+ static long dn;
74
+ static long ds;
75
+
76
+ int *idata;
77
+ int *id;
78
+ int *lld;
79
+
80
+ static FILE *fp;
81
+
82
+ char buf[512];
83
+ char file[512];
84
+
85
+ static float *dm;
86
+ static int *ld;
87
+
88
+ register float *d;
89
+ register float *zo;
90
+
91
+
92
+ if ((data == 0) && (ldata == 0)){
93
+ /* get .data file */
94
+ sprintf(file, "%s.data", root);
95
+ fp = fopen(file, "r");
96
+ if (fp == NULL) {
97
+ perror("ERROR: Empty data file");
98
+ exit(1);
99
+ }
100
+ /* determine format of .data file */
101
+ fscanf(fp,"%s",buf);
102
+ if (strcmp(buf, "localist") == 0){
103
+ localist = 1;
104
+ }
105
+ else if (strcmp(buf, "distributed") != 0){
106
+ perror("ERROR: .data file must be localist or distributed\n");
107
+ exit(1);
108
+ }
109
+ /* determine size of .data file */
110
+ if (fscanf(fp,"%ld",maxtime) != 1){
111
+ perror("ERROR: how many items in .data file?");
112
+ exit(1);
113
+ }
114
+ /* malloc space for data */
115
+ if (localist){
116
+ dn = *maxtime;
117
+ ds = *maxtime * ni;
118
+ ldata = (int *) malloc(ds * sizeof(int));
119
+ if (ldata == NULL){
120
+ perror("ldata malloc failed");
121
+ exit(1);
122
+ }
123
+ idata = (int *) malloc((ni+1) * sizeof(int));
124
+ if (idata == NULL){
125
+ perror("idata malloc failed");
126
+ exit(1);
127
+ }
128
+ /* read data */
129
+ ld = ldata;
130
+ for (ii = 0; ii < dn; ii++){
131
+ fscanf(fp,"%s",buf);
132
+ get_nums(buf,ni,0,idata);
133
+ id = idata + 1;
134
+ lld = ld;
135
+ for (j = 1; j <= ni; j++, id++){
136
+ if (*id)
137
+ *lld++ = j;
138
+ }
139
+ *lld = 0;
140
+ ld += ni;
141
+ }
142
+ }
143
+ else {
144
+ dn = *maxtime;
145
+ ds = *maxtime * ni;
146
+ data = (float *) malloc(ds * sizeof(float));
147
+ if (data == NULL){
148
+ perror("data malloc failed");
149
+ exit(1);
150
+ }
151
+ /* read data */
152
+ d = dm = data;
153
+ for (ii = 0; ii < ds; ii++, d++){
154
+ fscanf(fp,"%s",buf);
155
+ *d = atof(buf);
156
+ if ((*d == 0.) && (buf[0] != '0') && (buf[1] != '0')){
157
+ fprintf(stderr,"error reading .data file on or around line %ld of input\n",ii+1);
158
+ exit(1);
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+
165
+ /* update input (only at major time increments) */
166
+ if (tick == 0){
167
+ /* read next ni inputs from .data file */
168
+ if (localist){
169
+ if (randomly){
170
+ dc = (random() >> 8) % dn;
171
+ if (dc < 0)
172
+ dc = -dc;
173
+ *local = (int *) (ldata + dc * ni);
174
+ }
175
+ else {
176
+ *local = (int *) (ldata + dc * ni);
177
+ if (++dc >= dn)
178
+ dc = 0;
179
+ }
180
+ }
181
+ else {
182
+ if (randomly){
183
+ dc = (random() >> 8) % dn;
184
+ if (dc < 0)
185
+ dc = -dc;
186
+ d = (float *) (data + dc * ni);
187
+ zo = aold + 1;
188
+ for (i = 0; i < ni; i++, zo++, d++){
189
+ *zo = *d;
190
+ }
191
+ }
192
+ else {
193
+ d = dm;
194
+ zo = aold + 1;
195
+ for (i = 0; i < ni; i++, zo++, d++, dc++){
196
+ if (dc >= ds){
197
+ dc = 0;
198
+ d = data;
199
+ }
200
+ *zo = *d;
201
+ }
202
+ dm = d;
203
+ }
204
+ }
205
+ }
206
+ else {
207
+ /* turn off input during extra ticks with -I */
208
+ if (flag){
209
+ zo = aold + 1;
210
+ for (i = 0; i < ni; i++, zo++)
211
+ *zo = 0.;
212
+ }
213
+ }
214
+
215
+ }
216
+
217
+ update_targets(atarget,time,tick,flag,maxtime)
218
+ float *atarget;
219
+ long time;
220
+ int tick;
221
+ int flag;
222
+ long *maxtime;
223
+ {
224
+ long i;
225
+
226
+ int k;
227
+
228
+ register int j;
229
+
230
+ register float *ta;
231
+ register float *t;
232
+ register long *n;
233
+ register float *to;
234
+
235
+ static long *ntimes;
236
+ static float *teach;
237
+
238
+ static int local = 0; /* flag for localist output */
239
+
240
+ static long *nm;
241
+ static float *tm;
242
+ static long nc = 0;
243
+
244
+ static long len;
245
+ static long ts;
246
+
247
+ static long next; /* next time tag in .teach file */
248
+
249
+ static float *otarget = 0; /* (no) back-up copy of target values */
250
+
251
+ static FILE *fp;
252
+
253
+ char buf[128];
254
+
255
+ if (otarget == 0){
256
+ /* get .teach file */
257
+ sprintf(buf, "%s.teach", root);
258
+ fp = fopen(buf, "r");
259
+ if (fp == NULL) {
260
+ perror("ERROR: Empty target file");
261
+ exit(1);
262
+ }
263
+ /* malloc space for back-up copy of targets */
264
+ otarget = (float *) malloc(no * sizeof(float));
265
+ if (otarget == NULL){
266
+ perror("otarget malloc failed");
267
+ exit(1);
268
+ }
269
+ /* determine format of .teach file */
270
+ fscanf(fp,"%s",buf);
271
+ if (strcmp(buf, "localist") == 0){
272
+ local = 1;
273
+ }
274
+ else if (strcmp(buf, "distributed") != 0){
275
+ perror("ERROR: .teach file must be localist or distributed\n");
276
+ exit(1);
277
+ }
278
+ /* determine size of teach array */
279
+ if (fscanf(fp,"%ld",&len) != 1){
280
+ perror("ERROR: how many items in .teach file?");
281
+ exit(1);
282
+ }
283
+ /* malloc space for teach and ntimes buffers */
284
+ ts = len * no;
285
+ teach = (float *) malloc(ts * sizeof(float));
286
+ if (teach == NULL){
287
+ perror("teach malloc failed");
288
+ exit(1);
289
+ }
290
+ ntimes = (long *) malloc(len * sizeof(long));
291
+ if (ntimes == NULL){
292
+ perror("ntimes malloc failed");
293
+ exit(1);
294
+ }
295
+ /* read teach info */
296
+ t = tm = teach;
297
+ n = nm = ntimes;
298
+ for (i = 0; i < len; i++, n++){
299
+ fscanf(fp,"%ld",n);
300
+ if (local){
301
+ fscanf(fp,"%s",buf);
302
+ k = atoi(buf) - 1;
303
+ if (k < 0){
304
+ fprintf(stderr,"error reading .teach file on or around line %ld of input\n",i+1);
305
+ exit(1);
306
+ }
307
+ for (j = 0; j < no; j++, t++){
308
+ if (j == k)
309
+ *t = 1.;
310
+ else
311
+ *t = 0.;
312
+ }
313
+ }
314
+ else {
315
+ for (j = 0; j < no; j++, t++){
316
+ fscanf(fp,"%s",buf);
317
+ /* asterick is don't care sign */
318
+ if (buf[0] == '*')
319
+ *t = -9999.0;
320
+ else {
321
+ *t = atof(buf);
322
+ if ((*t == 0.) && (buf[0] != '0') && (buf[1] != '0')){
323
+ fprintf(stderr,"error reading .teach file on or around line %ld of input\n",i+1);
324
+ exit(1);
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+
332
+ /* check for new target values (only at major time increments) */
333
+ if (tick == 0){
334
+ t = tm;
335
+ n = nm;
336
+ /* restore previous values if destroyed by -T */
337
+ if (flag){
338
+ ta = atarget;
339
+ to = otarget;
340
+ for (j = 0; j < no; j++, ta++, to++)
341
+ *ta = *to;
342
+ }
343
+
344
+ /* if inputs are selected randomly, time-tags are
345
+ assumed to run sequentially, and targets are
346
+ selected to match input */
347
+
348
+ if (randomly){
349
+ if (dc >= len){
350
+ perror("ERROR: a target line is required for every input line with -R");
351
+ exit(1);
352
+ }
353
+ ta = atarget;
354
+ t = (float *) (teach + no * dc);
355
+ for (j = 0; j < no; j++, ta++, t++){
356
+ *ta = *t;
357
+ }
358
+ return;
359
+ }
360
+
361
+ /* rewind whenever .data begins again at time 0 */
362
+ if (time == 0){
363
+ nc = 0;
364
+ t = teach;
365
+ n = ntimes;
366
+ next = *n;
367
+ ta = atarget;
368
+ for (j = 0; j < no; j++, ta++)
369
+ *ta = -9999.0;
370
+ }
371
+ /* get new target values when time matches next */
372
+ if (time >= next){
373
+ /* read next no targets */
374
+ ta = atarget;
375
+ for (j = 0; j < no; j++, t++, ta++){
376
+ *ta = *t;
377
+ }
378
+ /* final target persists till end of input */
379
+ n++;
380
+ if (++nc >= len)
381
+ next = *maxtime;
382
+ else
383
+ next = *n;
384
+ }
385
+ tm = t;
386
+ nm = n;
387
+ /* remember target values if -T will destroy them */
388
+ if (flag){
389
+ ta = atarget;
390
+ to = otarget;
391
+ for (j = 0; j < no; j++, ta++, to++)
392
+ *to = *ta;
393
+ }
394
+ }
395
+ else {
396
+ /* turn off target during extra ticks with -T */
397
+ if (flag){
398
+ ta = atarget;
399
+ for (j = 0; j < no; j++, ta++)
400
+ *ta = -9999.0;
401
+ }
402
+ }
403
+
404
+ }
405
+
406
+ update_reset(time,tick,flag,maxtime,now)
407
+ long time;
408
+ int tick;
409
+ int flag;
410
+ long *maxtime;
411
+ int *now;
412
+ {
413
+ long i;
414
+
415
+ static int start = 1; /* flag for initialization */
416
+ static long next; /* next time tag in .teach file */
417
+
418
+ static long *rtimes;
419
+
420
+ static long *nm;
421
+ static long nc = 0;
422
+
423
+ static long l;
424
+
425
+ static FILE *fp;
426
+
427
+ char buf[128];
428
+
429
+ *now = 0;
430
+
431
+ if (flag == 0)
432
+ return;
433
+
434
+ if (start){
435
+ start = 0;
436
+ /* get .reset file */
437
+ sprintf(buf, "%s.reset", root);
438
+ fp = fopen(buf, "r");
439
+ if (fp == NULL) {
440
+ perror("ERROR: Empty reset file");
441
+ exit(1);
442
+ }
443
+ /* determine size of .reset file */
444
+ if (fscanf(fp,"%ld",&l) != 1){
445
+ perror("error reading .reset file");
446
+ exit(1);
447
+ }
448
+ /* malloc space for rtimes buffer */
449
+ rtimes = (long *) malloc(l * sizeof(long));
450
+ if (rtimes == NULL){
451
+ perror("rtimes malloc failed");
452
+ exit(1);
453
+ }
454
+ /* read reset info */
455
+ nm = rtimes;
456
+ for (i = 0; i < l; i++, nm++)
457
+ fscanf(fp,"%ld",nm);
458
+ nm = rtimes;
459
+ }
460
+
461
+ /* check for new resets (only at major time increments) */
462
+ if (tick == 0){
463
+ /* rewind whenever .data begins again at time 0 */
464
+ if (time == 0){
465
+ nc = 0;
466
+ nm = rtimes;
467
+ next = *nm;
468
+ }
469
+ if (time >= next){
470
+ *now = 1;
471
+ nm++;
472
+ if (++nc >= l)
473
+ next = *maxtime;
474
+ else
475
+ next = *nm;
476
+ }
477
+ }
478
+
479
+ }
480
+
481
+ update_weights(awt,adwt,awinc)
482
+ float **awt;
483
+ float **adwt;
484
+ float **awinc;
485
+ {
486
+ register int i;
487
+ register int j;
488
+
489
+ register struct cf *ci;
490
+
491
+ register float *w;
492
+ register float *dw;
493
+ register float *wi;
494
+ register float **wip;
495
+ register float **wp;
496
+ register float **dwp;
497
+
498
+ register struct cf **cp;
499
+
500
+ register int k;
501
+ register int n;
502
+ register float *sum;
503
+
504
+ float asum;
505
+
506
+ /* update weights if they are not fixed */
507
+ sum = &asum;
508
+ cp = cinfo;
509
+ wp = awt;
510
+ dwp = adwt;
511
+ wip = awinc;
512
+ for (i = 0; i < nn; i++, cp++, wp++, dwp++, wip++){
513
+ ci = *cp;
514
+ w = *wp;
515
+ dw = *dwp;
516
+ wi = *wip;
517
+ for (j = 0; j < nt; j++, dw++, wi++, w++, ci++){
518
+ if ((ci->con) && !(ci->fix)){
519
+ *wi = rate * *dw + momentum * *wi;
520
+ *w += *wi;
521
+ *dw = 0.;
522
+ }
523
+ }
524
+ }
525
+ /* look for weights in the same group and average them together */
526
+ for (k = 1; k <= ngroups; k++){
527
+ *sum = 0.;
528
+ n = 0;
529
+ cp = cinfo;
530
+ wp = awt;
531
+ /* calculate average */
532
+ for (i = 0; i < nn; i++, cp++, wp++){
533
+ ci = *cp;
534
+ w = *wp;
535
+ for (j = 0; j < nt; j++, w++, ci++){
536
+ if (ci->num == k){
537
+ *sum += *w;
538
+ n++;
539
+ }
540
+ }
541
+ }
542
+ if (n > 0)
543
+ *sum /= n;
544
+ /* replace weight with average */
545
+ cp = cinfo;
546
+ wp = awt;
547
+ for (i = 0; i < nn; i++, cp++, wp++){
548
+ ci = *cp;
549
+ w = *wp;
550
+ for (j = 0; j < nt; j++, w++, ci++){
551
+ if (ci->num == k)
552
+ *w = *sum;
553
+ }
554
+ }
555
+ }
556
+ /* look for limited weights and enforce limits */
557
+ if (limits == 0)
558
+ return;
559
+ cp = cinfo;
560
+ wp = awt;
561
+ for (i = 0; i < nn; i++, cp++, wp++){
562
+ ci = *cp;
563
+ w = *wp;
564
+ for (j = 0; j < nt; j++, w++, ci++){
565
+ if (ci->lim){
566
+ if (*w < ci->min)
567
+ *w = ci->min;
568
+ if (*w > ci->max)
569
+ *w = ci->max;
570
+ }
571
+ }
572
+ }
573
+
574
+ return;
575
+ }
576
+
577
+