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,594 @@
1
+ #include <stdio.h>
2
+ #ifdef ibmpc
3
+ #include "strings.h"
4
+ #else
5
+ #include <strings.h>
6
+ #endif
7
+ #include <math.h>
8
+ #define MAX_PARSE_BUF 4096
9
+
10
+
11
+ char pbuf[MAX_PARSE_BUF]; /* retains all strings parsed so far */
12
+ char nbuf[80]; /* shows string in get_nums */
13
+ int nbp;
14
+
15
+ double atof();
16
+
17
+ #ifdef ibmpc
18
+ extern char far *malloc();
19
+ #else
20
+ #ifndef aix3
21
+ extern char *malloc();
22
+ #endif
23
+ #endif
24
+ extern int nn; /* number of nodes */
25
+ extern int ni; /* number of inputs */
26
+ extern int no; /* number of outputs */
27
+ extern int nt; /* nn + ni + 1 */
28
+ extern int np; /* ni + 1 */
29
+
30
+ extern struct cf {
31
+ int con; /* connection flag */
32
+ int fix; /* fixed-weight flag */
33
+ int num; /* group number */
34
+ int lim; /* weight limits */
35
+ float min; /* weight minimum */
36
+ float max; /* weight maximum */
37
+ };
38
+
39
+ extern struct nf {
40
+ int func; /* activation function type */
41
+ int dela; /* delay flag */
42
+ int targ; /* target flag */
43
+ };
44
+
45
+ extern struct cf **cinfo; /* (nn x nt) connection info */
46
+
47
+ extern struct nf *ninfo; /* (nn) node info */
48
+
49
+ extern FILE *cfp;
50
+
51
+ extern int *outputs; /* (no) indices of output nodes */
52
+ extern int *selects; /* (nn+1) nodes selected for probe printout */
53
+
54
+ extern int ngroups; /* number of groups */
55
+ extern int limits; /* flag for limited weights */
56
+
57
+ extern float weight_limit; /* bound for random weight init */
58
+
59
+ get_nodes()
60
+ {
61
+ int i;
62
+
63
+ char buf[80];
64
+ char tmp[80];
65
+
66
+ /* read nn, ni, no */
67
+ nn = ni = no = -1;
68
+ get_str(cfp,buf,"\n");
69
+ /* first line must be "NODES:" */
70
+ if (strcmp(buf, "NODES:") != 0){
71
+ fprintf(stderr,".cf file must begin with NODES:\n");
72
+ exit(1);
73
+ }
74
+ /* next three lines must specify nn, ni, and no in any order */
75
+ for (i = 0; i < 3; i++){
76
+ get_str(cfp,buf," ");
77
+ get_str(cfp,tmp," ");
78
+ if (tmp[0] != '=')
79
+ parse_err();
80
+ get_str(cfp,tmp,"\n");
81
+ if (strcmp(buf, "nodes") == 0)
82
+ nn = atoi(tmp);
83
+ if (strcmp(buf, "inputs") == 0)
84
+ ni = atoi(tmp);
85
+ if (strcmp(buf, "outputs") == 0)
86
+ no = atoi(tmp);
87
+ }
88
+ if ((nn < 1) || (ni < 0) || (no < 0) || (nn < no)){
89
+ fprintf(stderr,"ERROR: Invalid specification\n\n");
90
+ parse_err();
91
+ }
92
+ nt = 1 + ni + nn;
93
+ np = 1 + ni;
94
+ }
95
+
96
+ get_outputs()
97
+ {
98
+ int i;
99
+ int j;
100
+
101
+ struct nf *n;
102
+
103
+ char buf[80];
104
+
105
+ get_str(cfp,buf," ");
106
+ /* next line must specify outputs */
107
+ if (strcmp(buf, "output") != 0)
108
+ parse_err();
109
+ get_str(cfp,buf," ");
110
+ if (strcmp(buf, "node") != 0){
111
+ if (strcmp(buf, "nodes") != 0)
112
+ parse_err();
113
+ }
114
+ get_str(cfp,buf," ");
115
+ if (strcmp(buf, "are") != 0){
116
+ if (strcmp(buf, "is") != 0)
117
+ parse_err();
118
+ }
119
+ get_str(cfp,buf,"\n");
120
+ get_nums(buf,nn+ni,ni,selects);
121
+ if (selects[0] == 1){
122
+ fprintf(stderr,"Node 0 cannot be an output\n");
123
+ exit(1);
124
+ }
125
+ for (i = 1; i <= ni; i++){
126
+ if (selects[i] == 1){
127
+ fprintf(stderr,"An input cannot be an output\n");
128
+ exit(1);
129
+ }
130
+ }
131
+ n = ninfo;
132
+ for (i = ni+1, j = -1; i <= nn+ni; i++, n++){
133
+ if (selects[i] > 0){
134
+ if (++j < no){
135
+ outputs[j] = i-ni;
136
+ n->targ = 1;
137
+ }
138
+ }
139
+ }
140
+ if (++j != no){
141
+ fprintf(stderr,"Expecting %d outputs, found %d\n",no,j);
142
+ exit(1);
143
+ }
144
+
145
+ }
146
+
147
+ get_connections()
148
+ {
149
+ int i;
150
+ int j;
151
+ int k;
152
+
153
+ struct cf *ci;
154
+
155
+ int gn;
156
+
157
+ float min;
158
+ float max;
159
+
160
+ char buf[80];
161
+
162
+ int *tmp;
163
+ int *iselects;
164
+
165
+ /* malloc space for iselects */
166
+ iselects = (int *) malloc(nt * sizeof(int));
167
+ if (iselects == NULL){
168
+ perror("iselects malloc failed");
169
+ exit(1);
170
+ }
171
+
172
+ get_str(cfp,buf,"\n");
173
+ /* next line must be "CONNECTIONS:" */
174
+ if (strcmp(buf, "CONNECTIONS:") != 0)
175
+ parse_err();
176
+
177
+ get_str(cfp,buf," ");
178
+
179
+ /* next line must be "groups = #" */
180
+ if (strcmp(buf, "groups") != 0)
181
+ parse_err();
182
+ get_str(cfp,buf," ");
183
+ if (buf[0] != '=')
184
+ parse_err();
185
+ get_str(cfp,buf,"\n");
186
+ ngroups = atoi(buf);
187
+
188
+ /* malloc space for tmp */
189
+ tmp = (int *) malloc((ngroups+1) * sizeof(int));
190
+ if (tmp == NULL){
191
+ perror("tmp malloc failed");
192
+ exit(1);
193
+ }
194
+
195
+ get_str(cfp,buf," ");
196
+ while (strcmp(buf, "SPECIAL:") != 0){
197
+ /* a group is identified */
198
+ if (strcmp(buf,"group") == 0){
199
+ get_str(cfp,buf," ");
200
+ get_nums(buf,ngroups,0,tmp);
201
+ get_str(cfp,buf," ");
202
+ if (buf[0] != '=')
203
+ parse_err();
204
+ get_str(cfp,buf," ");
205
+ /* group * = fixed */
206
+ if (strcmp(buf,"fixed") == 0){
207
+ for (i = 0; i < nn; i++){
208
+ ci = *(cinfo + i);
209
+ for (j = 0; j < nt; j++, ci++){
210
+ if (tmp[ci->num])
211
+ ci->fix = 1;
212
+ }
213
+ }
214
+ }
215
+ /* group * = wmin & wmax */
216
+ else {
217
+ min = (float) atof(buf);
218
+ get_str(cfp,buf," ");
219
+ if (buf[0] != '&')
220
+ parse_err();
221
+ get_str(cfp,buf," ");
222
+ max = (float) atof(buf);
223
+ if (max < min){
224
+ fprintf(stderr,"ERROR: %g < %g\n\n",max,min);
225
+ parse_err();
226
+ }
227
+ for (i = 0; i < nn; i++){
228
+ ci = *(cinfo + i);
229
+ for (j = 0; j < nt; j++, ci++){
230
+ if (tmp[ci->num]){
231
+ limits = 1;
232
+ ci->lim = 1;
233
+ ci->min = min;
234
+ ci->max = max;
235
+ }
236
+ }
237
+ }
238
+ }
239
+ strcat(pbuf,"\n");
240
+ get_str(cfp,buf," ");
241
+ }
242
+ /* a connection is specified */
243
+ else {
244
+ get_nums(buf,nn+ni,ni,selects);
245
+ if (selects[0]){
246
+ fprintf(stderr,"Connecting TO a bias\n\n");
247
+ parse_err();
248
+ }
249
+ for (i = 1; i <= ni; i++){
250
+ if (selects[i]){
251
+ fprintf(stderr,"Connecting TO an input\n\n");
252
+ parse_err();
253
+ }
254
+ }
255
+ get_str(cfp,buf," ");
256
+ if (strcmp(buf,"from") != 0)
257
+ parse_err();
258
+ get_str(cfp,buf," ");
259
+ get_nums(buf,nn+ni,ni,iselects);
260
+ for (i = 0; i < nn; i++){
261
+ ci = *(cinfo + i);
262
+ for (j = 0; j < nt; j++, ci++){
263
+ if ((selects[i+ni+1]) && (iselects[j]))
264
+ ci->con += 1;
265
+ }
266
+ }
267
+ strcat(pbuf,"\t");
268
+ get_str(cfp,buf," ");
269
+ if (buf[0] == '='){
270
+ get_str(cfp,buf," ");
271
+ /* connection = fixed */
272
+ if (strcmp(buf,"fixed") == 0){
273
+ for (i = 0; i < nn; i++){
274
+ ci = *(cinfo + i);
275
+ for (j = 0; j < nt; j++, ci++){
276
+ if ((selects[i+ni+1]) &&
277
+ (iselects[j]))
278
+ ci->fix = 1;
279
+ }
280
+ }
281
+ }
282
+ else {
283
+ /* connection = group # */
284
+ if (strcmp(buf,"group") == 0){
285
+ get_str(cfp,buf," ");
286
+ gn = atoi(buf);
287
+ for (i = 0; i < nn; i++){
288
+ ci = *(cinfo + i);
289
+ for (j = 0; j < nt; j++, ci++){
290
+ if ((selects[i+ni+1]) &&
291
+ (iselects[j]))
292
+ ci->num = gn;
293
+ }
294
+ }
295
+ }
296
+ /* connection = min & max */
297
+ else {
298
+ min = (float) atof(buf);
299
+ get_str(cfp,buf," ");
300
+ if (buf[0] != '&')
301
+ parse_err();
302
+ get_str(cfp,buf," ");
303
+ max = (float) atof(buf);
304
+ if (max < min){
305
+ fprintf(stderr,"ERROR: %g < %g\n\n",max,min);
306
+ parse_err();
307
+ }
308
+ for (i = 0; i < nn; i++){
309
+ ci = *(cinfo + i);
310
+ for (j = 0; j < nt; j++, ci++){
311
+ if ((selects[i+ni+1]) &&
312
+ (iselects[j])){
313
+ limits = 1;
314
+ ci->lim = 1;
315
+ ci->min = min;
316
+ ci->max = max;
317
+ }
318
+ }
319
+ }
320
+ }
321
+ }
322
+ get_str(cfp,buf,"\t");
323
+ if (strcmp(buf,"fixed") == 0){
324
+ for (i = 0; i < nn; i++){
325
+ ci = *(cinfo + i);
326
+ for (j = 0; j < nt; j++, ci++){
327
+ if ((selects[i+ni+1]) &&
328
+ (iselects[j]))
329
+ ci->fix = 1;
330
+ }
331
+ }
332
+ get_str(cfp,buf,"\t");
333
+ }
334
+ if (strcmp(buf,"one-to-one") == 0){
335
+ for (k = 0; k < nt; k++){
336
+ if (iselects[k])
337
+ break;
338
+ }
339
+ for (i = 0; i < nn; i++){
340
+ ci = *(cinfo + i);
341
+ for (j = 0; j < nt; j++, ci++){
342
+ if ((selects[i+ni+1]) &&
343
+ (iselects[j])){
344
+ if (ci->con == 1){
345
+ ci->con = 0;
346
+ ci->fix = 0;
347
+ ci->lim = 0;
348
+ }
349
+ else
350
+ ci->con -= 1;
351
+ }
352
+ }
353
+ if (selects[i+np]){
354
+ ci = *(cinfo + i) + k++;
355
+ ci->con = 1;
356
+ ci->fix = 1;
357
+ ci->lim = 1;
358
+ }
359
+ }
360
+ get_str(cfp,buf,"\n");
361
+ }
362
+ }
363
+ }
364
+ }
365
+ /*
366
+ for (i = 0; i < nn; i++){
367
+ ci = *(cinfo + i);
368
+ for (j = 0; j < nt; j++, ci++){
369
+ fprintf(stderr,"i: %d j: %d c: %d f: %d g: %d\n",
370
+ i,j,ci->con,ci->fix,ci->num);
371
+ }
372
+ }
373
+ */
374
+
375
+ }
376
+
377
+ get_special()
378
+ {
379
+ char buf[80];
380
+ char tmp[80];
381
+
382
+ int i;
383
+
384
+ int *iselects;
385
+
386
+ struct nf *n;
387
+
388
+ /* malloc space for iselects */
389
+ iselects = (int *) malloc(nt * sizeof(int));
390
+ if (iselects == NULL){
391
+ perror("iselects malloc failed");
392
+ exit(1);
393
+ }
394
+
395
+
396
+ while (fscanf(cfp,"%s",buf) != EOF){
397
+ if (strlen(pbuf) > MAX_PARSE_BUF -512) strcpy(pbuf, pbuf +512);
398
+ strcat(pbuf,buf);
399
+ strcat(pbuf," ");
400
+ get_str(cfp,tmp," ");
401
+ if (tmp[0] != '=')
402
+ parse_err();
403
+ get_str(cfp,tmp,"\n");
404
+ if (strcmp(buf,"weight_limit") == 0)
405
+ weight_limit = (float) atof(tmp);
406
+ if (strcmp(buf,"selected") == 0){
407
+ get_nums(tmp,nn,0,selects);
408
+ }
409
+ if (strcmp(buf,"linear") == 0){
410
+ get_nums(tmp,nn,0,iselects);
411
+ n = ninfo;
412
+ for (i = 1; i <= nn; i++, n++){
413
+ if (iselects[i])
414
+ n->func = 2;
415
+ }
416
+ }
417
+ if (strcmp(buf,"bipolar") == 0){
418
+ get_nums(tmp,nn,0,iselects);
419
+ n = ninfo;
420
+ for (i = 1; i <= nn; i++, n++){
421
+ if (iselects[i])
422
+ n->func = 1;
423
+ }
424
+ }
425
+ if (strcmp(buf,"binary") == 0){
426
+ get_nums(tmp,nn,0,iselects);
427
+ n = ninfo;
428
+ for (i = 1; i <= nn; i++, n++){
429
+ if (iselects[i])
430
+ n->func = 3;
431
+ }
432
+ }
433
+ if (strcmp(buf,"delayed") == 0){
434
+ get_nums(tmp,nn,0,iselects);
435
+ n = ninfo;
436
+ for (i = 1; i <= nn; i++, n++){
437
+ if (iselects[i])
438
+ n->dela = 1;
439
+ }
440
+ }
441
+ }
442
+
443
+ }
444
+
445
+ get_str(fp,buf,str)
446
+ FILE *fp;
447
+ char *buf;
448
+ char *str;
449
+ {
450
+ if (fscanf(fp,"%s",buf) == EOF){
451
+ fprintf(stderr,"Premature EOF detected.\n\n");
452
+ parse_err();
453
+ }
454
+ if (strlen(pbuf) > MAX_PARSE_BUF -512) strcpy(pbuf, pbuf +512);
455
+ strcat(pbuf,buf);
456
+ strcat(pbuf,str);
457
+ }
458
+
459
+ get_nums(str,nv,offset,vec)
460
+ char *str;
461
+ int nv;
462
+ int offset;
463
+ int *vec;
464
+ {
465
+ int c, i, j, l, k, m, n;
466
+ int dash;
467
+ int input;
468
+
469
+ char tmp[80];
470
+
471
+ dash = 0;
472
+ input = 0;
473
+ l = strlen(str);
474
+ nbp = 0;
475
+ for (i = 0; i <= nv; i++)
476
+ vec[i] = 0;
477
+ for (i = 0, j = 0; i < l; j++, i++){
478
+ c = str[i];
479
+ switch (c) {
480
+ case '0':
481
+ case '1':
482
+ case '2':
483
+ case '3':
484
+ case '4':
485
+ case '5':
486
+ case '6':
487
+ case '7':
488
+ case '8':
489
+ case '9': nbuf[nbp++] = tmp[j] = str[i];
490
+ break;
491
+ case 'i': input++;
492
+ j--;
493
+ nbuf[nbp++] = str[i];
494
+ break;
495
+ case '-': if (j == 0)
496
+ parse_err();
497
+ tmp[j] = '\0';
498
+ j = -1;
499
+ nbuf[nbp++] = str[i];
500
+ m = atoi(tmp);
501
+ dash = 1;
502
+ break;
503
+ case ',': if (j == 0)
504
+ parse_err();
505
+ tmp[j] = '\0';
506
+ j = -1;
507
+ nbuf[nbp++] = str[i];
508
+ if (dash){
509
+ n = atoi(tmp);
510
+ if (input == 1)
511
+ parse_err();
512
+ if (n < m)
513
+ parse_err();
514
+ }
515
+ else{
516
+ m = atoi(tmp);
517
+ n = m;
518
+ }
519
+ if (input == 0){
520
+ m += offset;
521
+ n += offset;
522
+ }
523
+ if (n > nv){
524
+ fprintf(stderr,"ERROR %d > %d\n",n,nv);
525
+ parse_err();
526
+ }
527
+ if ((input) && (n > offset)){
528
+ fprintf(stderr,"ERROR %d > %d\n",n,offset);
529
+ parse_err();
530
+ }
531
+ for (k = m; k <= n; k++){
532
+ if ((input == 0) && (k == offset))
533
+ vec[0] = 1;
534
+ else
535
+ vec[k] = 1;
536
+ }
537
+ input = 0;
538
+ dash = 0;
539
+ break;
540
+
541
+ default: parse_err();
542
+ }
543
+ }
544
+ if (j == 0)
545
+ parse_err();
546
+ tmp[j] = '\0';
547
+ nbuf[nbp++] = tmp[j];
548
+ if (dash){
549
+ n = atoi(tmp);
550
+ if (input == 1){
551
+ fprintf(stderr,"Cannot use dash to connect input and noninput\n\n");
552
+ parse_err();
553
+ }
554
+ if (n < m){
555
+ fprintf(stderr,"Upper bound must exceed lower\n\n");
556
+ parse_err();
557
+ }
558
+ }
559
+ else{
560
+ m = atoi(tmp);
561
+ n = m;
562
+ }
563
+ if (input == 0){
564
+ m += offset;
565
+ n += offset;
566
+ }
567
+ if (n > nv){
568
+ fprintf(stderr,"ERROR %d > %d\n",n,nv);
569
+ parse_err();
570
+ }
571
+ if ((input) && (n > offset)){
572
+ fprintf(stderr,"ERROR %d > %d\n",n,offset);
573
+ parse_err();
574
+ }
575
+ for (k = m; k <= n; k++){
576
+ if ((input == 0) && (k == offset))
577
+ vec[0] = 1;
578
+ else
579
+ vec[k] = 1;
580
+ }
581
+
582
+ nbp = 0;
583
+
584
+ }
585
+
586
+ parse_err()
587
+ {
588
+ fprintf(stderr,"\nError in .cf file:\n\n");
589
+ fprintf(stderr,"%s\n\n",pbuf);
590
+ fprintf(stderr,"(%s)\n\n",nbuf);
591
+ exit(1);
592
+
593
+ }
594
+