tlearn 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+