1 /*****************************************************************************
2 FILE : $Source: /projects/higgs1/SNNS/CVS/SNNS/tools/sources/ff_bignet.c,v $
3 SHORTNAME : ff_bignet
4 SNNS VERSION : 4.2
5
6 PURPOSE : Creates feedforward network
7 NOTES :
8
9 AUTHOR : Michael Vogt (xgui Version by Michael Schmalzl)
10 DATE : 4.7.1997
11
12 CHANGED BY : Guenter Mamier
13 RCS VERSION : $Revision: 1.11 $
14 LAST CHANGE : $Date: 1998/04/22 16:48:06 $
15
16 Copyright (c) 1990-1995 SNNS Group, IPVR, Univ. Stuttgart, FRG
17 Copyright (c) 1996-1998 SNNS Group, WSI, Univ. Tuebingen, FRG
18
19 ******************************************************************************/
20 #include <config.h>
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <ctype.h>
26
27 #include "kr_typ.h"
28 #include "kernel.h"
29 #include "glob_typ.h"
30 #include "kr_ui.h"
31
32 #include "ff_bignet.ph"
33
34
35
36 /*****************************************************************************
37 FUNCTION : create_net_PROC
38
39 PURPOSE : creates a SNNS-net in two steps:
40 1. calls up a function, which creates SNNS-units
41 2. calls up a function, which connections the SNNS-units.
42 NOTES : There are nine different ways (PLANE_TO_PLANE,
43 PLANE_TO_CLUSTER ...) two different planes can be connected.
44 RETURNS :
45
46 UPDATE : 20.12.1991
47 ******************************************************************************/
48
create_net_PROC(void)49 static void create_net_PROC(void)
50
51 {
52 LINK *LINK_element = LINK_first_element;
53 PLANE *source_plane, *target_plane;
54 int move,type_of_connection=1;
55
56 if(PLANE_length == 0)
57 return;
58
59 calculate_first_snns_unit_no_of_plane();
60 create_snns_unit();
61
62 while(LINK_element != NULL) {
63
64 move = (*LINK_element).move;
65 type_of_connection = (*LINK_element).type_of_connection;
66 source_plane = get_plane((*LINK_element).SOURCE.plane);
67 target_plane = get_plane((*LINK_element).TARGET.plane);
68
69 switch(type_of_connection) {
70 case PLANE_TO_PLANE:
71 make_link(source_plane, 0, 0, (*source_plane).width,
72 (*source_plane).height, target_plane, 0, 0,
73 (*target_plane).width,(*target_plane).height);
74 break;
75 case PLANE_TO_CLUSTER:
76 make_link(source_plane, 0, 0, (*source_plane).width,
77 (*source_plane).height, target_plane,
78 (*LINK_element).TARGET.CLUSTER.x-1,
79 (*LINK_element).TARGET.CLUSTER.y-1,
80 (*LINK_element).TARGET.CLUSTER.width,
81 (*LINK_element).TARGET.CLUSTER.height);
82 break;
83 case PLANE_TO_UNIT:
84 make_link(source_plane, 0, 0, (*source_plane).width,
85 (*source_plane).height, target_plane,
86 (*LINK_element).TARGET.UNIT.x-1,
87 (*LINK_element).TARGET.UNIT.y-1, 1, 1);
88 break;
89 case CLUSTER_TO_PLANE:
90 make_link(source_plane, (*LINK_element).SOURCE.CLUSTER.x-1,
91 (*LINK_element).SOURCE.CLUSTER.y-1,
92 (*LINK_element).SOURCE.CLUSTER.width,
93 (*LINK_element).SOURCE.CLUSTER.height,
94 target_plane, 0, 0, (*target_plane).width,
95 (*target_plane).height);
96 break;
97 case CLUSTER_TO_CLUSTER:
98 if(move) {
99 make_move_link(source_plane,
100 (*LINK_element).SOURCE.CLUSTER.x-1,
101 (*LINK_element).SOURCE.CLUSTER.y-1,
102 (*LINK_element).SOURCE.CLUSTER.width,
103 (*LINK_element).SOURCE.CLUSTER.height,
104 target_plane,
105 (*LINK_element).TARGET.CLUSTER.x-1,
106 (*LINK_element).TARGET.CLUSTER.y-1,
107 (*LINK_element).TARGET.CLUSTER.width,
108 (*LINK_element).TARGET.CLUSTER.height,
109 (*LINK_element).SOURCE.MOVE.delta_x,
110 (*LINK_element).SOURCE.MOVE.delta_y,
111 (*LINK_element).TARGET.MOVE.delta_x,
112 (*LINK_element).TARGET.MOVE.delta_y);
113 } else {
114 make_link(source_plane, (*LINK_element).SOURCE.CLUSTER.x-1,
115 (*LINK_element).SOURCE.CLUSTER.y-1,
116 (*LINK_element).SOURCE.CLUSTER.width,
117 (*LINK_element).SOURCE.CLUSTER.height,
118 target_plane, (*LINK_element).TARGET.CLUSTER.x-1,
119 (*LINK_element).TARGET.CLUSTER.y-1,
120 (*LINK_element).TARGET.CLUSTER.width,
121 (*LINK_element).TARGET.CLUSTER.height);
122 }
123 break;
124 case CLUSTER_TO_UNIT:
125 if(move) {
126 make_move_link(source_plane,
127 (*LINK_element).SOURCE.CLUSTER.x-1,
128 (*LINK_element).SOURCE.CLUSTER.y-1,
129 (*LINK_element).SOURCE.CLUSTER.width,
130 (*LINK_element).SOURCE.CLUSTER.height,
131 target_plane,
132 (*LINK_element).TARGET.UNIT.x-1,
133 (*LINK_element).TARGET.UNIT.y-1, 1, 1,
134 (*LINK_element).SOURCE.MOVE.delta_x,
135 (*LINK_element).SOURCE.MOVE.delta_y,
136 (*LINK_element).TARGET.MOVE.delta_x,
137 (*LINK_element).TARGET.MOVE.delta_y);
138 } else {
139 make_link(source_plane, (*LINK_element).SOURCE.CLUSTER.x-1,
140 (*LINK_element).SOURCE.CLUSTER.y-1,
141 (*LINK_element).SOURCE.CLUSTER.width,
142 (*LINK_element).SOURCE.CLUSTER.height,
143 target_plane,(*LINK_element).TARGET.UNIT.x-1,
144 (*LINK_element).TARGET.UNIT.y-1, 1, 1);
145 }
146 break;
147 case UNIT_TO_PLANE:
148 make_link(source_plane, (*LINK_element).SOURCE.UNIT.x-1,
149 (*LINK_element).SOURCE.UNIT.y-1, 1, 1, target_plane,
150 0, 0, (*target_plane).width, (*target_plane).height);
151 break;
152 case UNIT_TO_CLUSTER:
153 if(move) {
154 make_move_link(source_plane,
155 (*LINK_element).SOURCE.UNIT.x-1,
156 (*LINK_element).SOURCE.UNIT.y-1, 1, 1,
157 target_plane,
158 (*LINK_element).TARGET.CLUSTER.x-1,
159 (*LINK_element).TARGET.CLUSTER.y-1,
160 (*LINK_element).TARGET.CLUSTER.width,
161 (*LINK_element).TARGET.CLUSTER.height,
162 (*LINK_element).SOURCE.MOVE.delta_x,
163 (*LINK_element).SOURCE.MOVE.delta_y,
164 (*LINK_element).TARGET.MOVE.delta_x,
165 (*LINK_element).TARGET.MOVE.delta_y);
166 } else {
167 make_link(source_plane, (*LINK_element).SOURCE.UNIT.x-1,
168 (*LINK_element).SOURCE.UNIT.y-1, 1, 1,
169 target_plane, (*LINK_element).TARGET.CLUSTER.x-1,
170 (*LINK_element).TARGET.CLUSTER.y-1,
171 (*LINK_element).TARGET.CLUSTER.width,
172 (*LINK_element).TARGET.CLUSTER.height);
173 }
174 break;
175 case UNIT_TO_UNIT:
176 if(move) {
177 make_move_link(source_plane,
178 (*LINK_element).SOURCE.UNIT.x-1,
179 (*LINK_element).SOURCE.UNIT.y-1, 1, 1,
180 target_plane,
181 (*LINK_element).TARGET.UNIT.x-1,
182 (*LINK_element).TARGET.UNIT.y-1, 1, 1,
183 (*LINK_element).SOURCE.MOVE.delta_x,
184 (*LINK_element).SOURCE.MOVE.delta_y,
185 (*LINK_element).TARGET.MOVE.delta_x,
186 (*LINK_element).TARGET.MOVE.delta_y);
187 } else {
188 make_link(source_plane, (*LINK_element).SOURCE.UNIT.x-1,
189 (*LINK_element).SOURCE.UNIT.y-1, 1, 1,
190 target_plane,(*LINK_element).TARGET.UNIT.x-1,
191 (*LINK_element).TARGET.UNIT.y-1, 1, 1);
192 }
193 break;
194 } /* switch */
195 LINK_element = (*LINK_element).next;
196
197 } /* while */
198 }
199
200
201 /*****************************************************************************
202 FUNCTION : calculate_first_snns_unit_no_of_plane
203
204 PURPOSE : calculates the SNNS unit no of the left upper corner of every
205 plane.
206
207 NOTES : relative to this unit no, knowing the width and the height of the
208 planes, all other SNNS unit numbers of every plane can be
209 calculated. That's important for the function create_snns_unit.
210 RETURNS :
211
212 UPDATE : 20.12.1991
213 ******************************************************************************/
214
calculate_first_snns_unit_no_of_plane(void)215 static void calculate_first_snns_unit_no_of_plane(void)
216
217 {
218 PLANE *PLANE_element = PLANE_first_element;
219
220 (*PLANE_element).begin = 1;
221 PLANE_element = (*PLANE_element).next;
222
223 while(PLANE_element != NULL) {
224 (*PLANE_element).begin = (*(*PLANE_element).before).width *
225 (*(*PLANE_element).before).height +
226 (*(*PLANE_element).before).begin;
227 PLANE_element = (*PLANE_element).next;
228 }
229 }
230
231
232
233 /*****************************************************************************
234 FUNCTION : calculate_x_begin
235
236 PURPOSE : calculates the x-coordinate of a plane, where the plane is
237 positioned in the display window.
238 plane.
239 NOTES :
240 RETURNS : The X-Position
241
242 UPDATE : 20.12.1991
243 ******************************************************************************/
244
calculate_x_begin(int * new_x_begin,int * old_x_begin,int * x_max,int width,int pos)245 static int calculate_x_begin(int *new_x_begin, int *old_x_begin, int *x_max,
246 int width, int pos)
247
248 {
249 if(pos == BN_RIGHT) {
250 *new_x_begin = *x_max + 2;
251 *x_max = *new_x_begin + width;
252 *old_x_begin = *new_x_begin;
253 return *new_x_begin;
254 } else if(pos == BN_BELOW) {
255 if(*x_max < (*old_x_begin + width)) {
256 *x_max = *old_x_begin + width;
257 }
258 return *old_x_begin;
259 } else if(pos == BN_LEFT) {
260 *x_max = 0;
261 *old_x_begin = 2;
262
263 *new_x_begin = *x_max + 2;
264 *x_max = *new_x_begin + width;
265 return *new_x_begin;
266 }
267 return 0;
268 }
269
270
271 /*****************************************************************************
272 FUNCTION : calculate_y_begin
273
274 PURPOSE : calculates the y-coordinate of a plane, where the plane is
275 positioned in the display window.
276 plane.
277
278 NOTES :
279 RETURNS : The Y-Position
280
281 UPDATE : 20.12.1991
282 ******************************************************************************/
283
calculate_y_begin(int * absolute_y_max,int * relative_y_max,int * y_offset,int height,int pos)284 static int calculate_y_begin(int *absolute_y_max, int *relative_y_max,
285 int *y_offset, int height, int pos)
286 {
287 int y_begin;
288
289 if(pos == BN_RIGHT) {
290 y_begin = *y_offset + 2;
291 *relative_y_max = y_begin + height;
292 if(*absolute_y_max < *relative_y_max) {
293 *absolute_y_max = *relative_y_max;
294 }
295 } else if(pos == BN_BELOW) {
296 y_begin = *relative_y_max + 2;
297 *relative_y_max = y_begin + height;
298 if(*absolute_y_max < *relative_y_max) {
299 *absolute_y_max = *relative_y_max;
300 }
301 } else if(pos == BN_LEFT) {
302 *y_offset = *absolute_y_max;
303 y_begin = *y_offset + 2;
304 *absolute_y_max = y_begin + height;
305 *relative_y_max = y_begin + height;
306 }
307 return y_begin;
308 }
309
310
311 /*****************************************************************************
312 FUNCTION : create_snns_unit
313
314 PURPOSE : creates for every unit of a plane a SNNS default unit.
315
316 NOTES :
317 RETURNS :
318
319 UPDATE : 20.12.1991
320 ******************************************************************************/
321
create_snns_unit(void)322 static void create_snns_unit(void)
323 {
324 struct PosType unit_pos;
325
326 PLANE *PLANE_element = PLANE_first_element;
327 int x,y,width,height,unit_no,pos,ret;
328 int y_offset=0,relative_y_max=0,absolute_y_max=0,y_begin;
329 int x_max=0,old_x_begin=2,new_x_begin,x_begin;
330
331 ret = krui_allocateUnits((*PLANE_last_element).width *
332 (*PLANE_last_element).height +
333 (*PLANE_last_element).begin-1);
334 if(ret != 0){
335 fprintf(stderr, "%s\n", krui_error(ret));
336 exit(1);
337 }
338
339 while(PLANE_element != NULL) {
340
341 height = (*PLANE_element).height;
342 width = (*PLANE_element).width;
343 pos = (*PLANE_element).pos;
344
345 y_begin = calculate_y_begin(&absolute_y_max, &relative_y_max,
346 &y_offset, height, pos);
347 x_begin = calculate_x_begin(&new_x_begin, &old_x_begin,
348 &x_max, width, pos);
349
350 for(y=0;y<height;y++){
351 for(x=0;x<width;x++){
352 unit_no = krui_createUnit("unit", (*PLANE_element).out_func,
353 (*PLANE_element).act_func, 0.0, 0.0);
354 if(unit_no<0){
355 fprintf(stderr, "%s\n", krui_error(unit_no));
356 exit(1);
357 }
358
359 ret = krui_setUnitTType(unit_no,(*PLANE_element).type+1);
360 if(ret != 0){
361 fprintf(stderr, "%s\n", krui_error(ret));
362 exit(1);
363 }
364
365 unit_pos.x = x_begin + x;
366 unit_pos.y = y_begin + y;
367
368 krui_setUnitPosition(unit_no,&unit_pos);
369 }/*for*/
370 }/*for*/
371
372 PLANE_element = (*PLANE_element).next;
373 }/*while*/
374 }
375
376
377 /*****************************************************************************
378 FUNCTION : make_link
379
380 PURPOSE : creates the links between two planes.
381
382 NOTES :
383 RETURNS :
384
385 UPDATE : 20.12.1991
386 ******************************************************************************/
387
make_link(PLANE * LINK_source_plane,int LINK_source_cluster_x,int LINK_source_cluster_y,int LINK_source_cluster_width,int LINK_source_cluster_height,PLANE * LINK_target_plane,int LINK_target_cluster_x,int LINK_target_cluster_y,int LINK_target_cluster_width,int LINK_target_cluster_height)388 static void make_link(PLANE *LINK_source_plane, int LINK_source_cluster_x,
389 int LINK_source_cluster_y,int LINK_source_cluster_width,
390 int LINK_source_cluster_height, PLANE *LINK_target_plane,
391 int LINK_target_cluster_x, int LINK_target_cluster_y,
392 int LINK_target_cluster_width,
393 int LINK_target_cluster_height)
394
395 {
396 int i,j,k,l,ret,target_unit,source_unit;
397
398 for(i = LINK_target_cluster_y;
399 i < LINK_target_cluster_height+LINK_target_cluster_y; i++)
400 for(j = LINK_target_cluster_x;
401 j < LINK_target_cluster_width+LINK_target_cluster_x; j++)
402 {
403 target_unit = (*LINK_target_plane).begin +
404 (*LINK_target_plane).width * i + j;
405 ret = krui_setCurrentUnit(target_unit);
406 if(ret != 0){
407 fprintf(stderr, "%s\n", krui_error(ret));
408 exit(1);
409 }
410 for(k = LINK_source_cluster_y;
411 k < LINK_source_cluster_height+LINK_source_cluster_y; k++)
412 for(l = LINK_source_cluster_x;
413 l < LINK_source_cluster_width+LINK_source_cluster_x; l++)
414 {
415 source_unit = (*LINK_source_plane).begin +
416 (*LINK_source_plane).width * k + l;
417 if((ret = krui_createLink(source_unit,0.0)) != 0){
418 fprintf(stderr, "%s\n", krui_error(ret));
419 exit(1);
420 }
421 }
422 }
423 }
424
425
426 /*****************************************************************************
427 FUNCTION : make_move_link
428
429 PURPOSE : while "moving" (see docu) is possible the function make_link
430 is called up.
431 NOTES :
432 RETURNS :
433
434 UPDATE : 20.12.1991
435 ******************************************************************************/
436
make_move_link(PLANE * LINK_source_plane,int LINK_source_cluster_x,int LINK_source_cluster_y,int LINK_source_cluster_width,int LINK_source_cluster_height,PLANE * LINK_target_plane,int LINK_target_cluster_x,int LINK_target_cluster_y,int LINK_target_cluster_width,int LINK_target_cluster_height,int LINK_source_move_delta_x,int LINK_source_move_delta_y,int LINK_target_move_delta_x,int LINK_target_move_delta_y)437 static void make_move_link(PLANE *LINK_source_plane, int LINK_source_cluster_x,
438 int LINK_source_cluster_y,
439 int LINK_source_cluster_width,
440 int LINK_source_cluster_height,
441 PLANE * LINK_target_plane, int LINK_target_cluster_x,
442 int LINK_target_cluster_y,
443 int LINK_target_cluster_width,
444 int LINK_target_cluster_height,
445 int LINK_source_move_delta_x,
446 int LINK_source_move_delta_y,
447 int LINK_target_move_delta_x,
448 int LINK_target_move_delta_y)
449
450 {
451 int xs_pivot=LINK_source_cluster_x;
452 int xt_pivot=LINK_target_cluster_x;
453
454 do {
455 make_link(LINK_source_plane,LINK_source_cluster_x,LINK_source_cluster_y,
456 LINK_source_cluster_width,LINK_source_cluster_height,
457 LINK_target_plane,LINK_target_cluster_x,LINK_target_cluster_y,
458 LINK_target_cluster_width,LINK_target_cluster_height);
459 } while(move_p(LINK_source_plane, &LINK_source_cluster_y,
460 &LINK_source_cluster_x, LINK_source_cluster_width,
461 LINK_source_cluster_height, xs_pivot,
462 LINK_source_move_delta_x, LINK_source_move_delta_y) &&
463 move_p(LINK_target_plane, &LINK_target_cluster_y,
464 &LINK_target_cluster_x, LINK_target_cluster_width,
465 LINK_target_cluster_height, xt_pivot,
466 LINK_target_move_delta_x, LINK_target_move_delta_y));
467 }
468
469
470 /*****************************************************************************
471 FUNCTION : move_p
472
473 PURPOSE : tests whether the boundaries of a plane are crossed while
474 "moving" (see docu)
475
476 NOTES :
477 RETURNS :
478
479 UPDATE : 20.12.1991
480 ******************************************************************************/
481
move_p(PLANE * plane_no,int * y,int * x,int width,int height,int x_pivot,int x_step,int y_step)482 static int move_p(PLANE *plane_no, int *y, int *x, int width, int height,
483 int x_pivot, int x_step, int y_step)
484
485 {
486 if(x_step > 0 && ((*x)+width+x_step<=(*plane_no).width))
487 (*x)+= x_step;
488 else
489 if(y_step > 0 && ((*y)+height+y_step<=(*plane_no).height)){
490 (*y) += y_step;
491 (*x) = x_pivot;
492 }else
493 return 0;
494
495 return 1;
496 }
497
498
499 /*****************************************************************************
500 FUNCTION : more_data
501
502 PURPOSE : read command line integer value or "+"
503
504 NOTES :
505 RETURNS :
506
507 UPDATE :
508 ******************************************************************************/
509
more_data(char ** rest,char ** argv[],int * argc)510 static int more_data(char **rest, char **argv[], int *argc)
511 {
512 int retval = 0;
513
514 if (*argc > 0 && strcmp(**argv, "+") != 0)
515 {
516 retval = atoi(**argv);
517 *rest = **argv;
518 while (**rest != '\0' && isspace((int) **rest))
519 (*rest)++;
520 while (**rest != '\0' && isdigit((int) **rest))
521 (*rest)++;
522 (*argc)--;
523 (*argv)++;
524 }
525
526 return retval;
527 }
528
529 /*****************************************************************************
530 FUNCTION : read_link_elements
531
532 PURPOSE : reads the input datas of the link editor (Edit Link).
533
534 NOTES :
535 RETURNS : @@@
536
537 UPDATE : 20.12.1991
538 ******************************************************************************/
539
540 #define RETURN_IF_FAULT(x) { if ((x) != NULL && *(x) != '\0') return 0; }
541
read_link_elements(int * argc,char ** argv[])542 static int read_link_elements(int *argc, char **argv[])
543
544 {
545 /* the + character may be used to fill the remaining parameters
546 of one link definition column (compare bignet for xgui).
547 e.g. argv values like '1 + 2 +' result in a full connection
548 between plane 1 and plane 2 */
549 char *rest = NULL;
550
551 if (*argc <= 0)
552 return 0;
553 LINK_source_plane = more_data(&rest, argv, argc);
554 RETURN_IF_FAULT(rest);
555
556 LINK_source_cluster_x = more_data(&rest, argv, argc);
557 RETURN_IF_FAULT(rest);
558
559 LINK_source_cluster_y = more_data(&rest, argv, argc);
560 RETURN_IF_FAULT(rest);
561
562 LINK_source_cluster_width = more_data(&rest, argv, argc);
563 RETURN_IF_FAULT(rest);
564
565 LINK_source_cluster_height = more_data(&rest, argv, argc);
566 RETURN_IF_FAULT(rest);
567
568 LINK_source_unit_x = more_data(&rest, argv, argc);
569 RETURN_IF_FAULT(rest);
570
571 LINK_source_unit_y = more_data(&rest, argv, argc);
572 RETURN_IF_FAULT(rest);
573
574 LINK_source_move_delta_x = more_data(&rest, argv, argc);
575 RETURN_IF_FAULT(rest);
576
577 LINK_source_move_delta_y = more_data(&rest, argv, argc);
578 RETURN_IF_FAULT(rest);
579 if (*argc > 0 && strcmp(**argv, "+") == 0)
580 {
581 (*argc)--;
582 (*argv)++;
583 }
584
585 if (*argc <= 0)
586 return 0;
587 LINK_target_plane = more_data(&rest, argv, argc);
588 RETURN_IF_FAULT(rest);
589
590 LINK_target_cluster_x = more_data(&rest, argv, argc);
591 RETURN_IF_FAULT(rest);
592
593 LINK_target_cluster_y = more_data(&rest, argv, argc);
594 RETURN_IF_FAULT(rest);
595
596 LINK_target_cluster_width = more_data(&rest, argv, argc);
597 RETURN_IF_FAULT(rest);
598
599 LINK_target_cluster_height = more_data(&rest, argv, argc);
600 RETURN_IF_FAULT(rest);
601
602 LINK_target_unit_x = more_data(&rest, argv, argc);
603 RETURN_IF_FAULT(rest);
604
605 LINK_target_unit_y = more_data(&rest, argv, argc);
606 RETURN_IF_FAULT(rest);
607
608 LINK_target_move_delta_x = more_data(&rest, argv, argc);
609 RETURN_IF_FAULT(rest);
610
611 LINK_target_move_delta_y = more_data(&rest, argv, argc);
612 RETURN_IF_FAULT(rest);
613
614 if (*argc > 0 && strcmp(**argv, "+") == 0)
615 {
616 (*argc)--;
617 (*argv)++;
618 }
619
620 return correct_link_input();
621 }
622
623 #undef RETURN_IF_FAULT
624
625 /*****************************************************************************
626 FUNCNCTION : correct_link_input
627
628 PURPOSE : tests whether the input datas of Edit Link are correct and decides
629 what kind of link (PLANE_TO_PLANE, PLANE_TO_LINK...) we have.
630
631 NOTES :
632 RETURNS : Correct = 1 ; ERROR = 0
633
634 UPDATE : 20.12.1991
635 ******************************************************************************/
correct_link_input(void)636 static int correct_link_input(void)
637 {
638 PLANE *PLANE_source_no, *PLANE_target_no;
639
640 int link_type;
641 int target_plane=0, source_plane=0;
642 int target_cluster=0, source_cluster=0;
643 int target_unit=0, source_unit=0;
644 int a,b,c,d;
645
646 PLANE_source_no = get_plane(LINK_source_plane);
647 PLANE_target_no = get_plane(LINK_target_plane);
648
649 LINK_move = 0;
650
651
652 /* check plane numbers */
653 if((PLANE_source_no == NULL) || (PLANE_target_no == NULL))
654 return 0;
655
656 /* check source plane dimensions */
657 if((LINK_source_cluster_x + LINK_source_cluster_width
658 > (*PLANE_source_no).width + 1) ||
659 (LINK_source_cluster_y + LINK_source_cluster_height
660 > (*PLANE_source_no).height + 1) ||
661 (LINK_source_unit_x > (*PLANE_source_no).width) ||
662 (LINK_source_unit_y > (*PLANE_source_no).height))
663 return 0;
664
665 /* check target plane dimensions */
666 if((LINK_target_cluster_x + LINK_target_cluster_width
667 > (*PLANE_target_no).width + 1) ||
668 (LINK_target_cluster_y + LINK_target_cluster_height
669 > (*PLANE_target_no).height + 1) ||
670 (LINK_target_unit_x > (*PLANE_target_no).width) ||
671 (LINK_target_unit_y > (*PLANE_target_no).height))
672 return 0;
673
674 target_plane = TARGET_PLANE;
675 source_plane = SOURCE_PLANE;
676
677 a = b = c = d = 0;
678
679 if(((a=LINK_source_cluster_x) >= 1) && ((b=LINK_source_cluster_y) >= 1) &&
680 ((c=LINK_source_cluster_width) >= 1) &&
681 ((d=LINK_source_cluster_height) >= 1)) {
682 source_cluster = SOURCE_CLUSTER;
683 }
684
685 if((! source_cluster) && a+b+c+d)
686 return 0;
687
688 a = b = 0;
689
690 if(((a=LINK_source_unit_x) >= 1) && ((b=LINK_source_unit_y) >= 1))
691 source_unit = SOURCE_UNIT;
692
693 if((! source_unit) && a+b)
694 return 0;
695
696 a = b = c = d = 0;
697
698 if(((a=LINK_target_cluster_x) >= 1) && ((b=LINK_target_cluster_y) >= 1) &&
699 ((c=LINK_target_cluster_width) >= 1) &&
700 ((d=LINK_target_cluster_height) >= 1)) {
701 target_cluster = TARGET_CLUSTER;
702 }
703
704 if((! target_cluster) && a+b+c+d)
705 return 0;
706
707 a = b = 0;
708
709 if(((a=LINK_target_unit_x) >= 1) && ((b=LINK_target_unit_y) >= 1))
710 target_unit = TARGET_UNIT;
711
712 if((! target_unit) && a+b)
713 return 0;
714
715 link_type = target_plane + source_plane + target_cluster+
716 source_cluster + target_unit + source_unit;
717
718 if((link_type == PLANE_TO_PLANE) || (link_type == PLANE_TO_CLUSTER) ||
719 (link_type == PLANE_TO_UNIT) || (link_type == CLUSTER_TO_PLANE) ||
720 (link_type == CLUSTER_TO_CLUSTER) || (link_type == CLUSTER_TO_UNIT) ||
721 (link_type == UNIT_TO_PLANE) ||(link_type == UNIT_TO_CLUSTER) ||
722 (link_type == UNIT_TO_UNIT)) {
723
724 LINK_type_of_connection = link_type;
725
726 if((LINK_source_move_delta_x || LINK_source_move_delta_y ||
727 LINK_target_move_delta_x || LINK_target_move_delta_y) &&
728 ((link_type==CLUSTER_TO_CLUSTER) || (link_type==CLUSTER_TO_UNIT) ||
729 (link_type==UNIT_TO_CLUSTER) || (link_type == UNIT_TO_UNIT))) {
730 LINK_move = 1;
731 } else {
732 LINK_source_move_delta_x =
733 LINK_source_move_delta_y =
734 LINK_target_move_delta_x =
735 LINK_target_move_delta_y = 0;
736 }
737 }
738
739 return 1;
740 }
741
742
743 /*****************************************************************************
744 FUNCTION : enter_link
745
746 PURPOSE : enters a link element at the end of the link list.
747
748 NOTES :
749 RETURNS :
750
751 UPDATE : 20.12.1991
752 ******************************************************************************/
753
enter_link(void)754 static void enter_link(void)
755
756 {
757 LINK *LINK_element;
758
759 LINK_element = (LINK *)malloc(sizeof(LINK));
760
761 (*LINK_element).SOURCE.plane = LINK_source_plane;
762 (*LINK_element).SOURCE.CLUSTER.x = LINK_source_cluster_x;
763 (*LINK_element).SOURCE.CLUSTER.y = LINK_source_cluster_y;
764 (*LINK_element).SOURCE.CLUSTER.width = LINK_source_cluster_width;
765 (*LINK_element).SOURCE.CLUSTER.height = LINK_source_cluster_height;
766 (*LINK_element).SOURCE.UNIT.x = LINK_source_unit_x;
767 (*LINK_element).SOURCE.UNIT.y = LINK_source_unit_y;
768 (*LINK_element).SOURCE.MOVE.delta_x = LINK_source_move_delta_x;
769 (*LINK_element).SOURCE.MOVE.delta_y = LINK_source_move_delta_y;
770
771 (*LINK_element).TARGET.plane = LINK_target_plane;
772 (*LINK_element).TARGET.CLUSTER.x = LINK_target_cluster_x;
773 (*LINK_element).TARGET.CLUSTER.y = LINK_target_cluster_y;
774 (*LINK_element).TARGET.CLUSTER.width = LINK_target_cluster_width;
775 (*LINK_element).TARGET.CLUSTER.height = LINK_target_cluster_height;
776 (*LINK_element).TARGET.UNIT.x = LINK_target_unit_x;
777 (*LINK_element).TARGET.UNIT.y = LINK_target_unit_y;
778 (*LINK_element).TARGET.MOVE.delta_x = LINK_target_move_delta_x;
779 (*LINK_element).TARGET.MOVE.delta_y = LINK_target_move_delta_y;
780
781 (*LINK_element).move = LINK_move;
782 (*LINK_element).type_of_connection = LINK_type_of_connection;
783
784 (*LINK_element).next = NULL;
785 (*LINK_element).before = LINK_last_element;
786
787 if(LINK_last_element != NULL) {
788 (*LINK_last_element).next = LINK_element;
789 }
790
791 if(LINK_first_element == NULL) {
792 LINK_first_element = LINK_element;
793 }
794
795 LINK_last_element = LINK_element;
796 LINK_current_element = LINK_last_element;
797
798 LINK_length++;
799 }/* enter_link */
800
801
802
803 /*****************************************************************************
804 FUNCTION : read_plane_elements
805
806 PURPOSE : reads the input datas of the plane editor (Edit Plane).
807
808 NOTES :
809 RETURNS : Error = 0 ; Succes = 1
810
811 UPDATE : 20.12.1991
812 ******************************************************************************/
813
read_plane_elements(int * argc,char ** argv[])814 static int read_plane_elements(int *argc, char **argv[])
815 {
816
817 if (*argc > 0)
818 {
819 PLANE_width = atoi(**argv);
820 (*argv)++;
821 (*argc)--;
822 }
823 else return 0;
824
825 if (*argc > 0)
826 {
827 PLANE_height = atoi(**argv);
828 (*argv)++;
829 (*argc)--;
830 }
831 else return 0;
832
833 PLANE_type = BN_HIDDEN;
834 PLANE_type_was_set = 0;
835 PLANE_act_func = DEFAULT_ACT_FUNC;
836 PLANE_out_func = DEFAULT_OUT_FUNC;
837
838 if (*argc > 0 && krui_isFunction(**argv, ACT_FUNC))
839 {
840 PLANE_act_func = **argv;
841 (*argv)++;
842 (*argc)--;
843 if (*argc > 0 && krui_isFunction(**argv, OUT_FUNC))
844 {
845 PLANE_out_func = **argv;
846 (*argv)++;
847 (*argc)--;
848
849 if (*argc > 0)
850 {
851 if (strcasecmp(**argv, "input") == 0)
852 {
853 PLANE_type = BN_INPUT;
854 PLANE_type_was_set = 1;
855 (*argv)++;
856 (*argc)--;
857 }
858 else if (strcasecmp(**argv, "hidden") == 0)
859 {
860 PLANE_type = BN_HIDDEN;
861 PLANE_type_was_set = 1;
862 (*argv)++;
863 (*argc)--;
864 }
865 else if (strcasecmp(**argv, "output") == 0)
866 {
867 PLANE_type = BN_OUTPUT;
868 PLANE_type_was_set = 1;
869 (*argv)++;
870 (*argc)--;
871 }
872 }
873 }
874 }
875
876 return (PLANE_width > 0 && PLANE_height > 0) ? 1 : 0;
877 }
878
879
880 /*****************************************************************************
881 FUNCTION : enter_plane
882
883 PURPOSE : enters a plane element at the end of the plane list.
884
885 NOTES :
886 RETURNS :
887
888 UPDATE : 20.12.1991
889 ******************************************************************************/
890
enter_plane(void)891 static void enter_plane(void)
892
893 {
894 PLANE *PLANE_element;
895
896 PLANE_element = (PLANE *)malloc(sizeof(PLANE));
897 (*PLANE_element).width = PLANE_width;
898 (*PLANE_element).height = PLANE_height;
899 (*PLANE_element).pos = BN_RIGHT;
900 (*PLANE_element).type = PLANE_type;
901 (*PLANE_element).type_was_set = PLANE_type_was_set;
902 (*PLANE_element).act_func = PLANE_act_func;
903 (*PLANE_element).out_func = PLANE_out_func;
904 (*PLANE_element).next = NULL;
905 (*PLANE_element).before = PLANE_last_element;
906
907 if(PLANE_last_element != NULL) {
908 (*PLANE_last_element).next = PLANE_element;
909 }
910
911 if(PLANE_first_element == NULL) {
912 PLANE_first_element = PLANE_element;
913 }
914
915 PLANE_last_element = PLANE_element;
916 PLANE_current_element = PLANE_last_element;
917
918 PLANE_no = ++PLANE_length;
919 }
920
921
922 /*****************************************************************************
923 FUNCTION : get_plane
924
925 PURPOSE : returns a pointer to the plane element "plane_no"
926
927 NOTES :
928 RETURNS : returns a pointer to the plane element "plane_no"
929
930 UPDATE : 20.12.1991
931 ******************************************************************************/
932
get_plane(int plane_no)933 static PLANE *get_plane(int plane_no)
934
935 {
936 PLANE *PLANE_element = PLANE_first_element;
937 int counter = 1;
938
939 while((PLANE_element != NULL) &&
940 (counter != plane_no)) {
941 counter++;
942 PLANE_element = (*PLANE_element).next;
943
944 }
945 return PLANE_element;
946 }
947
948
949 /*****************************************************************************
950 FUNCTION : usage
951
952 PURPOSE : gives usage information
953
954 NOTES :
955 RETURNS :
956
957 UPDATE :
958 ******************************************************************************/
usage(void)959 void usage(void)
960 {
961
962 fprintf(stderr, "usage: ff_bignet <plane definition> ... <link definition> ... [<output file>]\n");
963 fprintf(stderr, "\n");
964 fprintf(stderr, "<plane definition> : -p <x> <y> [<act> [<out> [<type>]]]\n");
965 fprintf(stderr, " <x> : number of units in x-direction\n");
966 fprintf(stderr, " <y> : number of units in y-direction\n");
967 fprintf(stderr, " <act> : opt. activation function\n");
968 fprintf(stderr, " e.g.: Act_Logistic\n");
969 fprintf(stderr, " <out> : opt. activation function, <act> must be given too\n");
970 fprintf(stderr, " e.g.: Out_Identity\n");
971 fprintf(stderr, " <type>: opt. layer type, <act> and <out> must be given too\n");
972 fprintf(stderr, " valid types: input, hidden, or output\n\n");
973 fprintf(stderr, "<link defintion> : -l <sp> ... [+] <tp> ... [+]\n");
974 fprintf(stderr, " Link parameters must be given in the following order.\n");
975 fprintf(stderr, " All remaing Parameters within one section may be filled\n");
976 fprintf(stderr, " with 0 by giving the '+' character (0 means: not used)\n\n");
977 fprintf(stderr, " Source section:\n");
978 fprintf(stderr, " <sp> : source plane (1, 2, ...)\n");
979 fprintf(stderr, " <scx> : x position of source cluster\n");
980 fprintf(stderr, " <scy> : y position of source cluster\n");
981 fprintf(stderr, " <scw> : width of source cluster\n");
982 fprintf(stderr, " <sch> : height of source cluster\n");
983 fprintf(stderr, " <sux> : x position of a distinct source unit\n");
984 fprintf(stderr, " <suy> : y position of a distinct source unit\n");
985 fprintf(stderr, " <smx> : delta x for multiple source fields\n");
986 fprintf(stderr, " <smy> : delta y for multiple source fields\n\n");
987 fprintf(stderr, " Target section:\n");
988 fprintf(stderr, " <tp> : target plane (1, 2, ...)\n");
989 fprintf(stderr, " <tcx> : x position of target cluster\n");
990 fprintf(stderr, " <tcy> : y position of target cluster\n");
991 fprintf(stderr, " <tcw> : width of target cluster\n");
992 fprintf(stderr, " <tch> : height of target cluster\n");
993 fprintf(stderr, " <tux> : x position of a distinct target unit\n");
994 fprintf(stderr, " <tuy> : y position of a distinct target unit\n");
995 fprintf(stderr, " <tmx> : delta x for multiple target fields\n");
996 fprintf(stderr, " <tmy> : delta y for multiple target fields\n\n");
997 fprintf(stderr, "<output file> : name of the output file (default SNNS_FF_NET.net)\n");
998 exit(1);
999 }
1000
1001 /*****************************************************************************
1002 FUNCTION : main
1003
1004 PURPOSE :
1005
1006 NOTES :
1007 RETURNS :
1008
1009 UPDATE :
1010 ******************************************************************************/
1011
main(int argc,char * argv[])1012 int main(int argc, char *argv[])
1013 {
1014 char *file_name;
1015 int err;
1016
1017 file_name = "SNNS_FF_NET.net";
1018
1019 if (argc <= 1)
1020 usage();
1021
1022 argc--;
1023 argv++;
1024 while (argc > 0)
1025 {
1026 if (strcmp(*argv, "-p") == 0)
1027 {
1028 argc--;
1029 argv++;
1030
1031 if (!read_plane_elements(&argc, &argv)){
1032 fprintf(stderr, "Illegal plane definition\n");
1033 exit(1);
1034 }
1035
1036 enter_plane();
1037 }
1038 else if (strcmp(*argv, "-l") == 0)
1039 {
1040 argc--;
1041 argv++;
1042
1043 if (!read_link_elements(&argc, &argv)){
1044 fprintf(stderr, "Illegal link definition\n");
1045 exit(1);
1046 }
1047
1048 enter_link();
1049 }
1050 else
1051 {
1052 if (argc != 1)
1053 {
1054 fprintf(stderr, "Parameters not understood. Invalid function or type name?\n");
1055 exit(1);
1056 }
1057 file_name = *argv;
1058 argc--;
1059 argv++;
1060 }
1061 }
1062
1063 if(PLANE_first_element != NULL && !PLANE_first_element->type_was_set)
1064 {
1065 PLANE_first_element -> type = BN_INPUT;
1066 }
1067
1068 if(PLANE_last_element != NULL && !PLANE_last_element->type_was_set)
1069 {
1070 PLANE_last_element -> type = BN_OUTPUT;
1071 }
1072
1073 create_net_PROC();
1074
1075 err = krui_setUpdateFunc("Topological_Order");
1076 if (err != KRERR_NO_ERROR){
1077 fprintf(stderr, "%s\n", krui_error(err));
1078 exit(1);
1079 }
1080 err = krui_setLearnFunc("Std_Backpropagation");
1081 if (err != KRERR_NO_ERROR){
1082 fprintf(stderr, "%s\n", krui_error(err));
1083 exit(1);
1084 }
1085 err = krui_saveNet(file_name, "SNNS_FF_NET");
1086 if (err != KRERR_NO_ERROR){
1087 fprintf(stderr, "%s\n", krui_error(err));
1088 exit(1);
1089 }
1090
1091 exit(0);
1092 }
1093
1094 /* end of file */
1095