1 /*****************************************************************************
2 FILE : $Source: /projects/higgs1/SNNS/CVS/SNNS/kernel/sources/update_f.c,v $
3 SHORTNAME :
4 SNNS VERSION : 4.2
5
6 PURPOSE : SNNS-Kernel Network Update Functions
7 NOTES :
8
9 AUTHOR : Niels Mache
10 DATE : 18.03.91
11
12 CHANGED BY : Sven Doering, Michael Vogt (Martin Reczko)
13 RCS VERSION : $Revision: 2.18 $
14 LAST CHANGE : $Date: 1998/03/13 16:24: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 #include <stdlib.h>
22 #include <stdio.h>
23 #include <math.h>
24 #ifdef HAVE_VALUES_H
25 #include <values.h>
26 #endif
27
28 #include "kr_typ.h" /* Kernel Types and Constants */
29 #include "kr_const.h" /* Constant Declarators for SNNS-Kernel */
30 #include "kr_def.h" /* Default Values */
31 #include "kernel.h" /* Kernel Functions */
32 #include "glob_typ.h"
33 #include "kr_ui.h"
34 #include "kr_mem.h" /* Memory Manager Functions */
35 #include "random.h" /* Randomize Library Function Prototypes */
36 #include "kr_mac.h" /* Kernel Macros */
37 #include "krart_df.h" /* Macros and Definitions for ART */
38 #include "kr_art1.h"
39 #include "kr_art2.h"
40 #include "kr_amap.h"
41 #include "kr_art.h" /* Function Prototypes of ART kernel functions */
42 #include "kr_td.h" /* Function Prototypes of Time Delay functions */
43 #include "cc_glob.h"
44 #include "cc_mac.h"
45 #include "dlvq_learn.h"
46 #include "update_f.ph"
47 #include "kr_JordElm.h"
48 #include "func_mac.h"
49 #include "kr_newpattern.h"
50
51 extern FlintType OUT_Custom_Python(FlintType act);
52
53 /*#################################################
54
55 GROUP: Update Functions
56
57 #################################################*/
58
59 /*****************************************************************************
60 FUNCTION : UPDATE_syncPropagate
61
62 PURPOSE : synchronous propagation
63 RETURNS :
64 NOTES :
65
66 UPDATE : 01.12.93
67 ******************************************************************************/
UPDATE_syncPropagate(float * parameterArray,int NoOfParams)68 krui_err UPDATE_syncPropagate(float *parameterArray, int NoOfParams)
69 {
70 register struct Unit *unit_ptr;
71
72
73 /* update unit activations first */
74 FOR_ALL_UNITS( unit_ptr )
75 if ( !IS_INPUT_UNIT( unit_ptr) && UNIT_IN_USE( unit_ptr ))
76 /* unit isn't an input unit and is in use and enabled */
77 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
78
79 /* update unit outputs */
80 FOR_ALL_UNITS( unit_ptr )
81 if UNIT_IN_USE( unit_ptr )
82 /* unit is in use and enabled */
83 if (unit_ptr->out_func == OUT_IDENTITY)
84 /* identity output function: don't call the output function */
85 unit_ptr->Out.output = unit_ptr->act;
86 else if(unit_ptr->out_func == OUT_Custom_Python)
87 unit_ptr->Out.output =
88 kr_PythonOutFunction(unit_ptr->python_out_func,
89 unit_ptr->act);
90 else
91 /* no identity output function: calculate unit's output also */
92 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
93
94 return( KRERR_NO_ERROR );
95 }
96
97
98
99 /*****************************************************************************
100 FUNCTION : UPDATE_serialPropagate
101
102 PURPOSE : serial propagation
103 RETURNS :
104 NOTES :
105
106 UPDATE : 01.12.93
107 ******************************************************************************/
UPDATE_serialPropagate(float * parameterArray,int NoOfParams)108 krui_err UPDATE_serialPropagate(float *parameterArray, int NoOfParams)
109 {
110 register struct Unit *unit_ptr;
111
112
113 /* update unit activations and outputs */
114 FOR_ALL_UNITS( unit_ptr )
115 if UNIT_IN_USE( unit_ptr ){
116 /* unit is in use and enabled */
117 if (!IS_INPUT_UNIT( unit_ptr ))
118 /* this isn't a input unit: calculate the activation of
119 the unit by calling the activation function */
120 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
121
122 if (unit_ptr->out_func == OUT_IDENTITY)
123 /* identity output function: don't call the output function */
124 unit_ptr->Out.output = unit_ptr->act;
125 else if(unit_ptr->out_func == OUT_Custom_Python)
126 unit_ptr->Out.output =
127 kr_PythonOutFunction(unit_ptr->python_out_func,
128 unit_ptr->act);
129 else
130 /* no identity output function: calculate unit's output also */
131 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
132 }
133
134 return( KRERR_NO_ERROR );
135 }
136
137
138
139 /*****************************************************************************
140 FUNCTION : UPDATE_randomOrderPropagate
141
142 PURPOSE : random order propagation
143 RETURNS :
144 NOTES :
145
146 UPDATE :
147 ******************************************************************************/
UPDATE_randomOrderPropagate(float * parameterArray,int NoOfParams)148 krui_err UPDATE_randomOrderPropagate(float *parameterArray, int NoOfParams)
149 {
150 register struct Unit *unit_ptr, *u_array;
151 register int no_of_units;
152 int n;
153
154
155 u_array = unit_array;
156 no_of_units = NoOfUnits;
157
158 for (n = 0; n < no_of_units; n++){
159 /* choose unit */
160 unit_ptr = u_array + (1 + lrand48() % no_of_units);
161
162 if (!IS_INPUT_UNIT( unit_ptr ))
163 /* this isn't a input unit: calculate the activation of the unit by
164 calling the activation function */
165 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
166
167 if (unit_ptr->out_func == OUT_IDENTITY)
168 /* identity output function: don't call the output function */
169 unit_ptr->Out.output = unit_ptr->act;
170 else if(unit_ptr->out_func == OUT_Custom_Python)
171 unit_ptr->Out.output =
172 kr_PythonOutFunction(unit_ptr->python_out_func,
173 unit_ptr->act);
174 else
175 /* no identity output function: calculate unit's output also */
176 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
177 }
178
179 return( KRERR_NO_ERROR );
180 }
181
182
183
184 /*****************************************************************************
185 FUNCTION : UPDATE_randomPermutPropagate
186
187 PURPOSE : random permutation propagation
188 RETURNS :
189 NOTES :
190
191 UPDATE :
192 ******************************************************************************/
UPDATE_randomPermutPropagate(float * parameterArray,int NoOfParams)193 krui_err UPDATE_randomPermutPropagate(float *parameterArray, int NoOfParams)
194 {
195 register struct Unit *unit_ptr;
196 register TopoPtrArray topo_ptr;
197 int ret_code;
198
199
200 if (NetModified || (TopoSortID != PERMUTATION)){
201 /* networt was modified or permutation array isn't initialized */
202 ret_code = kr_makeUnitPermutation();
203 if (ret_code != KRERR_NO_ERROR)
204 return( ret_code );
205 }
206
207 topo_ptr = topo_ptr_array;
208
209 /* propagate net */
210 while ((unit_ptr = *++topo_ptr) != NULL){
211 if (!IS_INPUT_UNIT( unit_ptr ))
212 /* this isn't a input unit: calculate the activation of the unit
213 by calling the activation function */
214 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
215
216 if (unit_ptr->out_func == OUT_IDENTITY)
217 /* identity output function: don't call the output function */
218 unit_ptr->Out.output = unit_ptr->act;
219 else if(unit_ptr->out_func == OUT_Custom_Python)
220 unit_ptr->Out.output =
221 kr_PythonOutFunction(unit_ptr->python_out_func,
222 unit_ptr->act);
223 else
224 /* no identity output function: calculate unit's output also */
225 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
226 }
227
228 return( KRERR_NO_ERROR );
229 }
230
231
232
233 /*****************************************************************************
234 FUNCTION : UPDATE_topologicalPropagate
235
236 PURPOSE : Propagate Units in topological order
237 RETURNS :
238 NOTES :
239
240 UPDATE :
241 ******************************************************************************/
UPDATE_topologicalPropagate(float * parameterArray,int NoOfParams)242 krui_err UPDATE_topologicalPropagate(float *parameterArray, int NoOfParams)
243 {
244 register struct Unit *unit_ptr;
245 register TopoPtrArray topo_ptr;
246 int ret_code;
247
248
249 if (NetModified || (TopoSortID != TOPOLOGICAL_FF)){
250 /* networt was modified or topologic array isn't initialized */
251 ret_code = kr_topoSort( TOPOLOGICAL_FF );
252 if (ret_code != KRERR_NO_ERROR)
253 return( ret_code );
254
255 NetModified = FALSE;
256 }
257
258
259 topo_ptr = topo_ptr_array + 1;
260
261 /* propagate input units only */
262 while ((unit_ptr = *topo_ptr++) != NULL){
263 /* input units, don't call the activation function */
264
265 if (unit_ptr->out_func == OUT_IDENTITY)
266 /* identity output function: don't call the output function */
267 unit_ptr->Out.output = unit_ptr->act;
268 else if(unit_ptr->out_func == OUT_Custom_Python)
269 unit_ptr->Out.output =
270 kr_PythonOutFunction(unit_ptr->python_out_func,
271 unit_ptr->act);
272 else
273 /* no identity output function: calculate unit's output also */
274 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
275 }
276
277 /* propagate hidden units only */
278 while ((unit_ptr = *topo_ptr++) != NULL){
279 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
280
281 if (unit_ptr->out_func == OUT_IDENTITY)
282 /* identity output function: don't call the output function */
283 unit_ptr->Out.output = unit_ptr->act;
284 else if(unit_ptr->out_func == OUT_Custom_Python)
285 unit_ptr->Out.output =
286 kr_PythonOutFunction(unit_ptr->python_out_func,
287 unit_ptr->act);
288 else
289 /* no identity output function: calculate unit's output also */
290 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
291 }
292
293 /* propagate output units only */
294 while ((unit_ptr = *topo_ptr++) != NULL){
295 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
296
297 if (unit_ptr->out_func == OUT_IDENTITY)
298 /* identity output function: don't call the output function */
299 unit_ptr->Out.output = unit_ptr->act;
300 else if(unit_ptr->out_func == OUT_Custom_Python)
301 unit_ptr->Out.output =
302 kr_PythonOutFunction(unit_ptr->python_out_func,
303 unit_ptr->act);
304 else
305 /* no identity output function: calculate unit's output also */
306 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
307 }
308
309 return( KRERR_NO_ERROR );
310 }
311
312
313
314 /*****************************************************************************
315 FUNCTION : UPDATE_KohonenPropagate
316
317 PURPOSE : Propagate Units in topological order for Kohonen networks
318 RETURNS :
319 NOTES :
320
321 UPDATE :
322 ******************************************************************************/
UPDATE_KohonenPropagate(float * parameterArray,int NoOfParams)323 krui_err UPDATE_KohonenPropagate(float *parameterArray, int NoOfParams)
324 {
325 register struct Unit *unit_ptr;
326 register TopoPtrArray topo_ptr;
327 int ret_code;
328
329
330 if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
331 /* networt was modified or topologic array isn't initialized */
332 ret_code = kr_topoSort( TOPOLOGIC_TYPE );
333 if (ret_code == KRERR_NO_OUTPUT_UNITS) ret_code = KRERR_NO_ERROR;
334 if (ret_code != KRERR_NO_ERROR)
335 return( ret_code );
336
337 NetModified = FALSE;
338 }
339
340
341 topo_ptr = topo_ptr_array + 1;
342
343 /* propagate input units only */
344 while ((unit_ptr = *topo_ptr++) != NULL){
345 if (unit_ptr->out_func == OUT_IDENTITY)
346 unit_ptr->Out.output = unit_ptr->act;
347 else if(unit_ptr->out_func == OUT_Custom_Python)
348 unit_ptr->Out.output =
349 kr_PythonOutFunction(unit_ptr->python_out_func,
350 unit_ptr->act);
351 else
352 /* no identity output function: calculate unit's output also */
353 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
354 }
355
356 /* propagate hidden units only */
357 while ((unit_ptr = *topo_ptr++) != NULL){
358 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
359
360 if (unit_ptr->out_func == OUT_IDENTITY)
361 unit_ptr->Out.output = unit_ptr->act;
362 else if(unit_ptr->out_func == OUT_Custom_Python)
363 unit_ptr->Out.output =
364 kr_PythonOutFunction(unit_ptr->python_out_func,
365 unit_ptr->act);
366 else
367 /* no identity output function: calculate unit's output also */
368 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
369 }
370 return( KRERR_NO_ERROR );
371 }
372
373
374
375 /*****************************************************************************
376 FUNCTION : normalize_inputvector
377
378 PURPOSE : normalize input vector for Counterpropagation Update Function
379 RETURNS :
380 NOTES :
381
382 UPDATE :
383 ******************************************************************************/
normalize_inputvector(float sum)384 static void normalize_inputvector(float sum)
385 {
386 register struct Unit *unit_ptr;
387 register float amount;
388
389
390 amount = 1.0 / sqrt( sum );
391
392 FOR_ALL_UNITS( unit_ptr )
393 if (IS_INPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
394 /* this is a input unit */
395 unit_ptr->Out.output = unit_ptr->Out.output * amount;
396 }
397
398
399
400 /*****************************************************************************
401 FUNCTION : UPDATE_CPNPropagate
402
403 PURPOSE : Counterpropagation Update Function
404 RETURNS :
405 NOTES :
406
407 UPDATE :
408 ******************************************************************************/
UPDATE_CPNPropagate(float * parameterArray,int NoOfParams)409 krui_err UPDATE_CPNPropagate(float *parameterArray, int NoOfParams)
410 {
411 register struct Unit *unit_ptr, *winner_ptr;
412 register struct Site *site_ptr;
413 register struct Link *link_ptr;
414 register TopoPtrArray topo_ptr;
415
416 float maximum, unit_ptr_net, sum;
417 int ret_code;
418
419
420 if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
421 /* networt was modified or topologic array isn't initialized */
422 ret_code = kr_topoSort( TOPOLOGIC_TYPE );
423 if (ret_code != KRERR_NO_ERROR)
424 return( ret_code );
425
426 NetModified = FALSE;
427 }
428
429 topo_ptr = topo_ptr_array;
430 sum = 0.0;
431
432 /* propagagate all input units */
433 while ((unit_ptr = *++topo_ptr) != NULL){
434 /* this is an input unit */
435 unit_ptr->Out.output = unit_ptr->act;
436 sum += unit_ptr->Out.output * unit_ptr->Out.output;
437 }
438
439 if (sum != 0.0)
440 /* normalize the inputvector */
441 normalize_inputvector( sum );
442
443
444 /* propagate Kohonen Layer */
445
446 /* calculate the activation and the output values
447 of the hidden units (Kohonen Layer) */
448
449 winner_ptr = NULL;
450 maximum = -1.0e30; /* contains the maximum of the activations */
451
452 /* propagagate all hidden units */
453 while ((unit_ptr = *++topo_ptr) != NULL){
454 /* this is a hidden unit */
455 unit_ptr_net = 0.0;
456
457 if (unit_ptr->flags & UFLAG_SITES){
458 /* the unit has sites */
459 FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
460 unit_ptr_net += (link_ptr->weight * link_ptr->to->Out.output);
461 }else{ /* the unit has direct links */
462 FOR_ALL_LINKS( unit_ptr, link_ptr )
463 unit_ptr_net += (link_ptr->weight * link_ptr->to->Out.output);
464 }
465
466 if (maximum < unit_ptr_net){ /* determine winner unit */
467 winner_ptr = unit_ptr;
468 maximum = unit_ptr_net;
469 }
470
471 /* reset output and activation of hidden units */
472 unit_ptr->Out.output = unit_ptr->act = (FlintType) 0;
473 }
474
475 /* the competitive winner is chosen */
476 winner_ptr->Out.output = winner_ptr->act = (FlintType) 1;
477
478
479 /* propagate the Grossberg Layer */
480
481 /* propagagate all output units */
482 while ((unit_ptr = *++topo_ptr) != NULL){ /* this is a output unit */
483 /* the activation function is the identity function ( weighted sum) */
484 unit_ptr->Out.output = unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
485 }
486
487 return( KRERR_NO_ERROR );
488 }
489
490
491
492 /*****************************************************************************
493 FUNCTION : UPDATE_TimeDelayPropagate
494
495 PURPOSE :
496 RETURNS :
497 NOTES :
498
499 UPDATE :
500 ******************************************************************************/
UPDATE_TimeDelayPropagate(float parameterArray[],int NoOfParams)501 krui_err UPDATE_TimeDelayPropagate(float parameterArray[], int NoOfParams )
502 {
503 register struct Unit *unit_ptr;
504 register TopoPtrArray topo_ptr;
505 int ret_code;
506
507 /* initialization if necessary */
508 if (NetModified || (TopoSortID != TOPOLOGIC_LOGICAL)){
509
510 /* Net has been modified or topologic array isn't initialized */
511 /* check the topology of the network */
512 /* first: save the logical layer numbers, restore them after check */
513 FOR_ALL_UNITS(unit_ptr)
514 unit_ptr -> Aux.int_no = unit_ptr -> lln;
515 ret_code = kr_topoCheck();
516 FOR_ALL_UNITS(unit_ptr)
517 unit_ptr -> lln = unit_ptr -> Aux.int_no;
518 if (ret_code < KRERR_NO_ERROR)
519 return( ret_code ); /* an error has occured */
520 if (ret_code < 2)
521 return( KRERR_NET_DEPTH ); /* the network has less then 2 layers */
522
523 /* count the no. of I/O units and check the patterns */
524 ret_code = kr_IOCheck();
525 if (ret_code < KRERR_NO_ERROR) return( ret_code );
526
527 ret_code = kr_topoSort( TOPOLOGIC_LOGICAL );
528 if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
529 return( ret_code );
530
531 NetModified = FALSE;
532 }
533
534 topo_ptr = topo_ptr_array;
535 unit_ptr = *++topo_ptr;
536
537 /* propagate input units only */
538 while (unit_ptr != (struct Unit *) NULL){
539 /* input units doesn't have inputs, so don't call the
540 activation function */
541
542 if (unit_ptr->out_func == OUT_IDENTITY)
543 /* identity output function: there is no need to call the
544 output function */
545 unit_ptr->Out.output = unit_ptr->act;
546 else if(unit_ptr->out_func == OUT_Custom_Python)
547 unit_ptr->Out.output =
548 kr_PythonOutFunction(unit_ptr->python_out_func,
549 unit_ptr->act);
550 else
551 /* no identity output function: calculate unit's output also */
552 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
553 unit_ptr = *++topo_ptr;
554 }
555
556 /* use the propagation function of the learning function for the update */
557 /* This way, the necessary time delay code is present only once */
558 /* Use the special pattern_no -1, to prevent loading of a pattern */
559 propagateTDNetForward(-1,-1);
560
561 return (KRERR_NO_ERROR);
562
563 } /* UPDATE_TimeDelayPropagate */
564
565
566
567
568
569 /*****************************************************************************
570 FUNCTION : UPDATE_ART1_syncPropagate
571
572 PURPOSE : ART 1 update function which does exactly the same as the normal
573 synchronous propagate function except that additionally the winner
574 of the ART 1 recognition layer is calculated.
575 RETURNS :
576 NOTES :
577
578 UPDATE :
579 ******************************************************************************/
UPDATE_ART1_syncPropagate(float * parameterArray,int NoOfParams)580 krui_err UPDATE_ART1_syncPropagate(float *parameterArray, int NoOfParams)
581 {
582 krui_err ret_code = KRERR_NO_ERROR;
583
584 int i;
585 struct Unit *winner_ptr; /* recognition unit which is the winner of w.t.a*/
586 struct Unit *unit_ptr;
587 TopoPtrArray topo_layer[6]; /* topo_layer[0] : *first input unit
588 topo_layer[1] : *first comp. unit
589 topo_layer[2] : *first rec. unit
590 topo_layer[3] : *first delay unit
591 topo_layer[4] : *first local reset unit
592 topo_layer[5] : *first special unit
593 (classified_unit)*/
594 TopoPtrArray topo_ptr;
595 static float rho;
596 bool inp_pat_changed = FALSE;
597 bool rho_has_changed = FALSE;
598
599
600 /* Check vigilance parameter */
601
602 if (NoOfParams < 1) {
603 ret_code = KRERR_PARAMETERS;
604 return (ret_code);
605 } /*if*/
606
607 /* Check if rho has changed from last to actual call of this update function
608 If rho has changed, then put new activation value into unit rho */
609 if (rho != parameterArray[0]) {
610 rho_has_changed = TRUE;
611 }
612
613 rho = parameterArray[0];
614
615 if ((rho < 0.0) || (rho > 1.0)) {
616 ret_code = KRERR_PARAMETERS;
617 return (ret_code);
618 }
619
620
621 /* Check if network has been modified or learning function has just
622 been changed */
623
624 if (NetModified || (TopoSortID != ART1_TOPO_TYPE)) {
625 (void) kr_topoSort (ART1_TOPO_TYPE);
626 ret_code = KernelErrorCode;
627 if (ret_code != KRERR_NO_ERROR) {
628 NetModified = TRUE;
629 return (ret_code);
630 } /*if*/
631
632 NetModified = FALSE;
633 }
634
635
636 /* get pointers to resep. first elements of each layer in topo_ptr_array */
637
638 topo_ptr = topo_ptr_array+1;
639
640 for(i=0; i<=5; i++){
641 topo_layer[i] = topo_ptr;
642 do {
643 } while (*topo_ptr++ != NULL);
644
645 }
646
647
648 /* Check if input pattern changed since last call to this function */
649 if (krart_inp_pat_changed(topo_layer[0])) {
650 inp_pat_changed = TRUE;
651 krart_save_inp_pat(topo_layer[0]);
652 }
653
654
655 /* Push activation of input units to their output value.
656 This is important for the first cycle. */
657
658 topo_ptr = topo_layer[0];
659 for (unit_ptr = *topo_ptr; *topo_ptr != NULL; unit_ptr = *topo_ptr++) {
660 if (unit_ptr->out_func == OUT_IDENTITY) {
661 unit_ptr->Out.output = unit_ptr->act;
662 } else if(unit_ptr->out_func == OUT_Custom_Python) {
663 unit_ptr->Out.output =
664 kr_PythonOutFunction(unit_ptr->python_out_func,
665 unit_ptr->act);
666 } else {
667 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
668 }
669
670 }
671
672 /* if rho had changed from last to this call of this update function then
673 reinitialize the values of the i_act field of the unit structure and
674 reset the activations of all non input units */
675 if (rho_has_changed || inp_pat_changed) {
676 ret_code = kra1_init_i_act (rho);
677 if (ret_code != KRERR_NO_ERROR)
678 return (ret_code);
679
680 ret_code = krart_reset_activations ();
681 if (ret_code != KRERR_NO_ERROR)
682 return (ret_code);
683 }
684
685 /* 1 propagation step (all units push their information onto
686 their output and calculate their new activation.*/
687
688 krart_prop_synch ();
689
690 /* look for the recognition unit with the highest activation
691 returns a NULL pointer if all recognition units have
692 activation 0.0 */
693 winner_ptr = krart_get_winner (topo_layer[2],1.0);
694
695 return (ret_code);
696
697 }
698
699
700
701 /*****************************************************************************
702 FUNCTION : UPDATE_ART1_Propagate
703
704 PURPOSE : ART1 Update function for updating until a stable state is reached,
705 e.g. either the 'classified' unit is on or the 'not classifiable'
706 unit is.
707 RETURNS :
708 NOTES :
709
710 UPDATE :
711 ******************************************************************************/
UPDATE_ART1_Propagate(float * parameterArray,int NoOfParams)712 krui_err UPDATE_ART1_Propagate(float *parameterArray, int NoOfParams)
713 {
714 krui_err ret_code = KRERR_NO_ERROR;
715 int i;
716 struct Unit *winner_ptr; /* recogn. unit which is the winner of w.t.a */
717 TopoPtrArray topo_layer[6]; /* topo_layer[0] : *first input unit
718 topo_layer[1] : *first comp. unit
719 topo_layer[2] : *first rec. unit
720 topo_layer[3] : *first delay unit
721 topo_layer[4] : *first local reset unit
722 topo_layer[5] : *first special unit
723 (classified_unit) */
724 TopoPtrArray topo_ptr;
725 float rho;
726
727
728 /* Check vigilance parameter */
729
730 if (NoOfParams < 1) {
731 ret_code = KRERR_PARAMETERS;
732 return (ret_code);
733 }
734
735 rho = parameterArray[0];
736
737 if ((rho < 0.0) || (rho > 1.0)) {
738 ret_code = KRERR_PARAMETERS;
739 return (ret_code);
740 }
741
742
743 /* Check if network has been modified or learning function has just
744 been changed */
745
746 if (NetModified || (TopoSortID != ART1_TOPO_TYPE)) {
747 (void) kr_topoSort (ART1_TOPO_TYPE);
748 ret_code = KernelErrorCode;
749 if (ret_code != KRERR_NO_ERROR) {
750 NetModified = TRUE;
751 return (ret_code);
752 }
753
754 NetModified = FALSE;
755 }
756
757 ret_code = kra1_init_i_act (rho);
758
759 if (ret_code != KRERR_NO_ERROR) {
760 return (ret_code);
761 }
762
763 /* get pointers to resp. first elements of each layer in topo_ptr_array */
764
765 topo_ptr = topo_ptr_array+1;
766
767 for (i=0; i<=5; i++) {
768 topo_layer[i] = topo_ptr;
769 do {
770 } while (*topo_ptr++ != NULL);
771 }
772
773 /* initialize activations of non input units */
774
775 ret_code = krart_reset_activations ();
776 if (ret_code != KRERR_NO_ERROR)
777 return (ret_code);
778
779 do {
780 /* 1 propagation step (all units push their information onto
781 their output and calculate their new activation */
782
783 krart_prop_synch ();
784
785 /* look for the recognition unit with the highest activation
786 returns a NULL pointer if all recognition units have
787 activation 0.0 */
788 winner_ptr = krart_get_winner (topo_layer[2],1.0);
789
790 } while (!(ART1_CLASSIFIED) && !(ART1_NOT_CLASSIFIABLE));
791
792 return (ret_code);
793
794 }
795
796
797
798
799 /*****************************************************************************
800 FUNCTION : UPDATE_ART2_syncPropagate
801
802 PURPOSE : ART 2 update function which does exactly the same as the normal
803 synchronous propagate function except that additionally the winner
804 of the ART 1 recognition layer is calculated.
805 RETURNS :
806 NOTES :
807
808 UPDATE :
809 ******************************************************************************/
UPDATE_ART2_syncPropagate(float * parameterArray,int NoOfParams)810 krui_err UPDATE_ART2_syncPropagate(float *parameterArray, int NoOfParams)
811 {
812 krui_err ret_code = KRERR_NO_ERROR;
813 int i;
814 struct Unit *winner_ptr; /* recogn. unit which is the winner of w.t.a */
815 struct Unit *unit_ptr;
816 TopoPtrArray topo_layer[12]; /* topo_layer[0] : *first input unit
817 topo_layer[1] : *first w unit
818 topo_layer[2] : *first x unit
819 topo_layer[3] : *first u unit
820 topo_layer[4] : *first v unit
821 topo_layer[5] : *first p unit
822 topo_layer[6] : *first q unit
823 topo_layer[7] : *first r unit
824 topo_layer[8] : *first rec. unit
825 topo_layer[9] : *first local reset unit */
826 TopoPtrArray topo_ptr;
827 static float rho, param_a, param_b, param_c, param_d, theta;
828 bool inp_pat_changed = FALSE;
829 bool rho_has_changed = FALSE;
830 bool a_has_changed = FALSE;
831 bool b_has_changed = FALSE;
832 bool c_has_changed = FALSE;
833 bool theta_has_changed = FALSE;
834
835
836
837
838 /* Check vigilance parameter */
839
840 if (NoOfParams < 5) {
841 ret_code = KRERR_PARAMETERS;
842 return (ret_code);
843 }
844
845
846 /* Check if input pattern had changed from last step to this one */
847
848
849 /* Check if one of the parameters has changed from last to actual
850 call of this update function.
851 If so, then put new activation value into unit rho or change
852 the weights of the relevant links. */
853 if (rho != parameterArray[0])
854 rho_has_changed = TRUE;
855
856 if (param_a != parameterArray[1])
857 a_has_changed = TRUE;
858
859 if (param_b != parameterArray[2])
860 b_has_changed = TRUE;
861
862 if (param_c != parameterArray[3])
863 c_has_changed = TRUE;
864
865 if (theta != parameterArray[4])
866 theta_has_changed = TRUE;
867
868 rho = parameterArray[0];
869 param_a = parameterArray[1];
870 param_b = parameterArray[2];
871 param_c = parameterArray[3];
872 theta = parameterArray[4];
873
874
875 /* Check if network has been modified */
876
877 if (NetModified || (TopoSortID != ART2_TOPO_TYPE)) {
878 (void) kr_topoSort (ART2_TOPO_TYPE);
879 ret_code = KernelErrorCode;
880 if (ret_code != KRERR_NO_ERROR) {
881 NetModified = TRUE;
882 return (ret_code);
883 }
884 NetModified = FALSE;
885 }
886
887 /* get pointers to resp. first elements of each layer in topo_ptr_array */
888
889 topo_ptr = topo_ptr_array+1;
890
891 for (i=0; i<=9; i++) {
892 topo_layer[i] = topo_ptr;
893 do {
894 } while (*topo_ptr++ != NULL);
895 }
896
897 /* Check if input pattern changed since last call to this function */
898 if (krart_inp_pat_changed(topo_layer[0])) {
899 inp_pat_changed = TRUE;
900 krart_save_inp_pat(topo_layer[0]);
901 }
902
903
904 /* Read out value of parameter d from bias field of any unit. The
905 value has been written into the bias field by the init-function */
906 param_d = (*(topo_ptr_array+1))->bias;
907
908
909 /* Check values of the parameters */
910
911 if ((rho < 0.0) || (rho > 1.0) || (param_a <= 0.0) || (param_b <= 0.0) ||
912 ((param_c*param_d)/(1-param_d) > 1.0) ||(theta < 0.0) || (theta > 1.0)){
913 ret_code = KRERR_PARAMETERS;
914 return (ret_code);
915 }
916
917
918 /* if one of the parameters had changed from last to this call
919 of this update function then reinitialize the values of the i_act
920 field of the unit structure, set the weights of the relevant links and
921 reset the activations of all non input units */
922 if (rho_has_changed || a_has_changed || b_has_changed ||
923 c_has_changed || theta_has_changed || inp_pat_changed){
924
925 ret_code = kra2_set_params (rho,param_a,param_b,param_c,param_d,theta);
926
927 if (ret_code != KRERR_NO_ERROR)
928 return (ret_code);
929
930 ret_code = kra2_init_propagate();
931
932 if (ret_code != KRERR_NO_ERROR)
933 return (ret_code);
934
935 kra2_init_pattern();
936 }
937
938
939 /* Push activation of input units to their output value.
940 This is important for the first cycle. */
941
942 topo_ptr = topo_layer[ART2_INP_LAY-1];
943 unit_ptr = *topo_ptr;
944 while (unit_ptr != NULL) {
945 if (unit_ptr->out_func == OUT_IDENTITY) {
946 unit_ptr->Out.output = unit_ptr->act;
947 } else if(unit_ptr->out_func == OUT_Custom_Python) {
948 unit_ptr->Out.output =
949 kr_PythonOutFunction(unit_ptr->python_out_func,
950 unit_ptr->act);
951 } else {
952 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
953 }
954 topo_ptr++;
955 unit_ptr = *topo_ptr;
956 }
957
958 /* compute vector norms */
959 kra2_compute_norms();
960
961 /* save old activation values of f1-units */
962 kra2_save_for_stability_check ();
963
964 /* Propagate */
965 krart_prop_synch ();
966
967 /* Get winner */
968 winner_ptr = krart_get_winner (topo_layer[ART2_REC_LAY-1], param_d);
969
970 /* Check F1 stability */
971 kra2_check_f1_stability ();
972
973 /* Check reset */
974 kra2_checkReset ();
975
976 return (ret_code);
977
978 }
979
980
981
982 /*****************************************************************************
983 FUNCTION : UPDATE_ART2_Propagate
984
985 PURPOSE :
986 RETURNS :
987 NOTES :
988
989 UPDATE :
990 ******************************************************************************/
UPDATE_ART2_Propagate(float * parameterArray,int NoOfParams)991 krui_err UPDATE_ART2_Propagate(float *parameterArray, int NoOfParams)
992 {
993 krui_err ret_code = KRERR_NO_ERROR;
994 int i;
995 struct Unit *winner_ptr; /* recogn. unit which is the winner of w.t.a */
996 TopoPtrArray topo_layer[12]; /* topo_layer[0] : *first input unit
997 topo_layer[1] : *first w unit
998 topo_layer[2] : *first x unit
999 topo_layer[3] : *first u unit
1000 topo_layer[4] : *first v unit
1001 topo_layer[5] : *first p unit
1002 topo_layer[6] : *first q unit
1003 topo_layer[7] : *first r unit
1004 topo_layer[8] : *first rec. unit
1005 topo_layer[10] : *first local reset
1006 unit */
1007 TopoPtrArray topo_ptr;
1008 FlintType rho, param_a, param_b, param_c, param_d, theta;
1009
1010
1011 /* Check number of incoming parameters */
1012
1013 if (NoOfParams < 5) {
1014 ret_code = KRERR_PARAMETERS;
1015 return (ret_code);
1016 }
1017
1018 rho = parameterArray[0];
1019 param_a = parameterArray[1];
1020 param_b = parameterArray[2];
1021 param_c = parameterArray[3];
1022 theta = parameterArray[4];
1023
1024
1025
1026 /* Check if network has been modified or learning function has just
1027 been changed */
1028
1029 if (NetModified || (TopoSortID != ART2_TOPO_TYPE)) {
1030 (void) kr_topoSort (ART2_TOPO_TYPE);
1031 ret_code = KernelErrorCode;
1032 if (ret_code != KRERR_NO_ERROR) {
1033 NetModified = TRUE;
1034 return (ret_code);
1035 }
1036
1037 NetModified = FALSE;
1038 }
1039
1040
1041 /* Read out value of parameter d from bias field of any unit. The
1042 value has been written into the bias field by the init-function */
1043 param_d = (*(topo_ptr_array+1))->bias;
1044
1045
1046 /* Check values of the parameters */
1047
1048 if ((rho < 0.0) || (rho > 1.0) ||(param_a <= 0.0) || (param_b <= 0.0) ||
1049 ((param_c*param_d)/(1-param_d)>1.0) || (theta<0.0) || (theta>1.0)){
1050 ret_code = KRERR_PARAMETERS;
1051 return (ret_code);
1052 }
1053
1054 ret_code = kra2_set_params (rho, param_a, param_b, param_c, param_d, theta);
1055
1056 if (ret_code != KRERR_NO_ERROR)
1057 return (ret_code);
1058
1059 ret_code = kra2_init_propagate ();
1060
1061 if (ret_code != KRERR_NO_ERROR)
1062 return (ret_code);
1063
1064 /* get pointers to resp. first elements of each layer in topo_ptr_array */
1065 topo_ptr = topo_ptr_array+1;
1066
1067 for (i=0; i<=9; i++){
1068 topo_layer[i] = topo_ptr;
1069 do {
1070 } while (*topo_ptr++ != NULL);
1071 }
1072
1073
1074 /* initialize the unit activations of the whole net */
1075 ret_code = krart_reset_activations();
1076 if (ret_code != KRERR_NO_ERROR)
1077 return (ret_code);
1078
1079 /* initialize of ART2 Simulator for new pattern */
1080 kra2_init_pattern ();
1081
1082
1083 /* repeat synchronous propagation and look for winner until pattern is
1084 classified or network tells us, that pattern is not classifiable */
1085 do {
1086 /* compute vector norms */
1087 kra2_compute_norms();
1088
1089 /* save old activation values of f1-units */
1090 kra2_save_for_stability_check ();
1091
1092 /* 1 propagation step (all units push their information onto
1093 their output and calculate their new activation. */
1094 krart_prop_synch ();
1095
1096 /* look for the recognition unit with the highest activation returns
1097 a NULL pointer if all recognition units have activation 0.0 */
1098 winner_ptr = krart_get_winner (topo_layer[ART2_REC_LAY-1], param_d);
1099
1100 /* Check if F1-Layer is stable */
1101 kra2_check_f1_stability();
1102
1103 /* Check Reset */
1104 kra2_checkReset ();
1105
1106 } while (!(ART2_CLASSIFIED) && !(ART2_NOT_CLASSIFIABLE));
1107
1108 return (ret_code);
1109 }
1110
1111
1112 /*****************************************************************************
1113 FUNCTION : UPDATE_ARTMAP_syncPropagate
1114
1115 PURPOSE : ARTMAP update function which does exactly the same as the normal
1116 synchronous propagate function except that additionally the winner
1117 of the ARTMAP recognition layer is calculated.
1118 RETURNS :
1119 NOTES :
1120
1121 UPDATE :
1122 ******************************************************************************/
UPDATE_ARTMAP_syncPropagate(float * parameterArray,int NoOfParams)1123 krui_err UPDATE_ARTMAP_syncPropagate(float *parameterArray, int NoOfParams)
1124 {
1125 krui_err ret_code = KRERR_NO_ERROR;
1126 int i;
1127 struct Unit *winner_ptr_a; /* the winner of wta of ARTa */
1128 struct Unit *winner_ptr_b; /* the winner of w.t.a of ARTb */
1129 struct Unit *unit_ptr;
1130 TopoPtrArray topo_layer[14]; /* topo_layer[0] : *first input unit ARTa
1131 topo_layer[1] : *first comp. unit ARTa
1132 topo_layer[2] : *first rec. unit ARTa
1133 topo_layer[3] : *first delay unit ARTa
1134 topo_layer[4] : *first local reset unit ARTa
1135 topo_layer[5] : *first special unit ARTa
1136 (classified_unit)
1137 topo_layer[6] : *first input unit ARTb
1138 topo_layer[7] : *first comp. unit ARTb
1139 topo_layer[8] : *first rec. unit ARTb
1140 topo_layer[9] : *first delay unit ARTb
1141 topo_layer[10]: *first local reset unit ARTb
1142 topo_layer[11]: *first special unit ARTb
1143 (classified_unit)
1144 topo_layer[12]: *first map unit
1145 topo_layer[13]: *first special map unit */
1146 TopoPtrArray topo_ptr;
1147 static float rho_a = -1.0;
1148 static float rho_b = -1.0;
1149 static float rho = -1.0;
1150 bool inp_pat_changed = FALSE;
1151 bool rho_has_changed = FALSE;
1152
1153
1154 /* Check vigilance parameter */
1155 if (NoOfParams < 3) {
1156 ret_code = KRERR_PARAMETERS;
1157 return (ret_code);
1158 }
1159
1160 /* Check if rho has changed from last to actual call of this update function
1161 If rho has changed, then put new activation value into unit rho */
1162 if ((rho_a != parameterArray[0]) || (rho_b != parameterArray[1]) ||
1163 (rho != parameterArray[2]))
1164 rho_has_changed = TRUE;
1165
1166 rho_a = parameterArray[0];
1167 rho_b = parameterArray[1];
1168 rho = parameterArray[2];
1169
1170
1171 if((rho_a<0.0) || (rho_a>1.0) || (rho_b<0.0) || (rho_b>1.0) ||
1172 (rho<0.0) || (rho>1.0)){
1173 ret_code = KRERR_PARAMETERS;
1174 return (ret_code);
1175 }
1176
1177
1178 /* Check if network has been modified or learn func has just been changed */
1179
1180 if (NetModified || (TopoSortID != ARTMAP_TOPO_TYPE)) {
1181 (void) kr_topoSort (ARTMAP_TOPO_TYPE);
1182 ret_code = KernelErrorCode;
1183 if (ret_code != KRERR_NO_ERROR) {
1184 NetModified = TRUE;
1185 return (ret_code);
1186 }
1187
1188 NetModified = FALSE;
1189 }
1190
1191
1192 /* get pointers to resp. first elements of each layer in topo_ptr_array */
1193 topo_ptr = topo_ptr_array+1;
1194
1195 for (i=0; i<=13; i++) {
1196 topo_layer[i] = topo_ptr;
1197 do {
1198 } while (*topo_ptr++ != NULL);
1199 }
1200
1201
1202 /* Check if input pattern changed since last call to this function */
1203 if (krart_inp_pat_changed(topo_layer[0]) ||
1204 krart_inp_pat_changed(topo_layer[6])){
1205 inp_pat_changed = TRUE;
1206 krart_save_inp_pat(topo_layer[0]);
1207 krart_save_inp_pat(topo_layer[6]);
1208 }
1209
1210
1211 /* Push activation of input units to their output value.
1212 This is important for the first cycle. */
1213
1214 /* inpa - units */
1215 topo_ptr = topo_layer[0];
1216 for (unit_ptr = *topo_ptr; *topo_ptr != NULL; unit_ptr = *++topo_ptr) {
1217 if (unit_ptr->out_func == OUT_IDENTITY) {
1218 unit_ptr->Out.output = unit_ptr->act;
1219 } else if(unit_ptr->out_func == OUT_Custom_Python) {
1220 unit_ptr->Out.output =
1221 kr_PythonOutFunction(unit_ptr->python_out_func,
1222 unit_ptr->act);
1223 } else {
1224 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
1225 }
1226 }
1227
1228 topo_ptr = topo_layer[6];
1229 for (unit_ptr = *topo_ptr; *topo_ptr != NULL; unit_ptr = *++topo_ptr) {
1230 if (unit_ptr->out_func == OUT_IDENTITY) {
1231 unit_ptr->Out.output = unit_ptr->act;
1232 } else if(unit_ptr->out_func == OUT_Custom_Python) {
1233 unit_ptr->Out.output =
1234 kr_PythonOutFunction(unit_ptr->python_out_func,
1235 unit_ptr->act);
1236 } else {
1237 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
1238 }
1239 }
1240
1241 /* if rho or input pattern had changed from last to this call of this
1242 update function then reinitialize the values of the i_act field of the
1243 unit structure and reset the activations of all non input units */
1244 if (rho_has_changed || inp_pat_changed) {
1245
1246 ret_code = kram_init_i_act (rho_a, rho_b, rho);
1247 if (ret_code != KRERR_NO_ERROR)
1248 return (ret_code);
1249
1250 ret_code = krart_reset_activations ();
1251 if (ret_code != KRERR_NO_ERROR)
1252 return (ret_code);
1253 }
1254
1255 /* 1 propagation step (all units push their information onto
1256 their output and calculate their new activation. */
1257
1258 krart_prop_synch ();
1259
1260 /* look for the recognition unit with the highest activation returns a
1261 NULL pointer if all recognition units have activation 0.0 */
1262 winner_ptr_a = krart_get_winner (topo_layer[2],1.0);
1263 winner_ptr_b = krart_get_winner (topo_layer[8],1.0);
1264
1265 return (ret_code);
1266
1267 }
1268
1269
1270 /*****************************************************************************
1271 FUNCTION : UPDATE_ARTMAP_Propagate
1272
1273 PURPOSE : ARTMAP Update function for updating until a stable state is
1274 reached, e.g. either the 'classified' unit is on or the 'not
1275 classifiable' unit is.
1276 RETURNS :
1277 NOTES :
1278
1279 UPDATE :
1280 ******************************************************************************/
UPDATE_ARTMAP_Propagate(float * parameterArray,int NoOfParams)1281 krui_err UPDATE_ARTMAP_Propagate(float *parameterArray, int NoOfParams)
1282 {
1283 krui_err ret_code = KRERR_NO_ERROR;
1284 int i;
1285 struct Unit *winner_ptr_a; /* the winner of w.t.a of ARTa */
1286 struct Unit *winner_ptr_b; /* the winner of w.t.a of ARTb */
1287 TopoPtrArray topo_layer[14]; /* topo_layer[0] : *first input unit ARTa
1288 topo_layer[1] : *first comp. unit ARTa
1289 topo_layer[2] : *first rec. unit ARTa
1290 topo_layer[3] : *first delay unit ARTa
1291 topo_layer[4] : *first local reset unit ARTa
1292 topo_layer[5] : *first special unit ARTa
1293 (classified_unit)
1294 topo_layer[6] : *first input unit ARTb
1295 topo_layer[7] : *first comp. unit ARTb
1296 topo_layer[8] : *first rec. unit ARTb
1297 topo_layer[9] : *first delay unit ARTb
1298 topo_layer[10]: *first local reset unit ARTb
1299 topo_layer[11]: *first special unit ARTb
1300 (classified_unit)
1301 topo_layer[12]: *first map unit
1302 topo_layer[13]: *first special map unit */
1303 TopoPtrArray topo_ptr;
1304 float rho_a;
1305 float rho_b;
1306 float rho;
1307
1308
1309 /* Check vigilance parameters */
1310
1311 if (NoOfParams < 3) {
1312 ret_code = KRERR_PARAMETERS;
1313 return (ret_code);
1314 }
1315
1316 rho_a = parameterArray[0];
1317 rho_b = parameterArray[1];
1318 rho = parameterArray[2];
1319
1320 if ((rho_a < 0.0) || (rho_a > 1.0) || (rho_b < 0.0) ||
1321 (rho_b > 1.0) || (rho < 0.0) || (rho > 1.0)){
1322 ret_code = KRERR_PARAMETERS;
1323 return (ret_code);
1324 }
1325
1326
1327 /* Check if network has been modified or learn func has just been changed */
1328 if (NetModified || (TopoSortID != ARTMAP_TOPO_TYPE)) {
1329 (void) kr_topoSort (ARTMAP_TOPO_TYPE);
1330 ret_code = KernelErrorCode;
1331 if (ret_code != KRERR_NO_ERROR) {
1332 NetModified = TRUE;
1333 return (ret_code);
1334 }
1335
1336 NetModified = FALSE;
1337 }
1338
1339
1340 ret_code = kram_init_i_act (rho_a, rho_b, rho);
1341
1342 if (ret_code != KRERR_NO_ERROR)
1343 return (ret_code);
1344
1345 /* get pointers to resp. first elements of each layer in topo_ptr_array */
1346 topo_ptr = topo_ptr_array+1;
1347
1348 for (i=0; i<=13; i++) {
1349 topo_layer[i] = topo_ptr;
1350 do {
1351 } while (*topo_ptr++ != NULL);
1352 }
1353
1354 /* initialize activations of non input units */
1355 ret_code = krart_reset_activations ();
1356 if (ret_code != KRERR_NO_ERROR)
1357 return (ret_code);
1358
1359 do {
1360 /* 1 propagation step (all units push their information onto
1361 their output and calculate their new activation. */
1362 krart_prop_synch ();
1363
1364 /* look for the recognition unit with the highest activation
1365 returns a NULL pointer if all recognition units have
1366 activation 0.0 */
1367 winner_ptr_a = krart_get_winner (topo_layer[2],1.0);
1368 winner_ptr_b = krart_get_winner (topo_layer[8],1.0);
1369
1370 } while (!(ARTMAP_CLASSIFIED) && !(ARTMAP_NOT_CLASSIFIABLE));
1371
1372 return (ret_code);
1373
1374 }
1375
1376
1377
1378 /*****************************************************************************
1379 FUNCTION : UPDATE_CC_Propagate
1380
1381 PURPOSE : Propagates a pattern through the net after pressing the test
1382 button.
1383 NOTES :
1384
1385 UPDATE : 5.2.93
1386 ******************************************************************************/
UPDATE_CC_Propagate(float parameterArray[],int NoOfParams)1387 krui_err UPDATE_CC_Propagate(float parameterArray[], int NoOfParams)
1388 {
1389 register struct Unit *inputUnitPtr,*outputUnitPtr,*hiddenUnitPtr,*unitPtr;
1390 register int dummy,o;
1391
1392 if(NetModified || LearnFuncHasChanged) {
1393
1394 NoOfInputUnits = NoOfHiddenUnits = NoOfOutputUnits = 0;
1395 FOR_ALL_UNITS(unitPtr) {
1396 if(IS_INPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
1397 NoOfInputUnits++;
1398 }
1399 if(IS_HIDDEN_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
1400 NoOfHiddenUnits++;
1401 }
1402 if(IS_OUTPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
1403 NoOfOutputUnits++;
1404 }
1405 }
1406 KernelErrorCode = cc_deleteAllSpecialUnits();
1407 ERROR_CHECK;
1408
1409 KernelErrorCode = kr_topoSort(TOPOLOGICAL_CC);
1410 ERROR_CHECK;
1411
1412 KernelErrorCode = cc_setPointers();
1413 ERROR_CHECK;
1414
1415 NetModified = FALSE;
1416 LearnFuncHasChanged = FALSE;
1417 }
1418
1419 FOR_ALL_INPUT_UNITS(inputUnitPtr,dummy){
1420 if(inputUnitPtr->out_func == OUT_IDENTITY) {
1421 inputUnitPtr->Out.output = inputUnitPtr->act;
1422 } else if(inputUnitPtr->out_func == OUT_Custom_Python) {
1423 inputUnitPtr->Out.output =
1424 kr_PythonOutFunction(inputUnitPtr->python_out_func,
1425 inputUnitPtr->act);
1426 }else{
1427 inputUnitPtr->Out.output =
1428 (*inputUnitPtr->out_func) (inputUnitPtr->act);
1429 }
1430 }
1431
1432 FOR_ALL_HIDDEN_UNITS(hiddenUnitPtr,dummy) {
1433 hiddenUnitPtr->act = (*hiddenUnitPtr->act_func) (hiddenUnitPtr);
1434 if(hiddenUnitPtr->out_func == OUT_IDENTITY) {
1435 hiddenUnitPtr->Out.output = hiddenUnitPtr->act;
1436 } else if(hiddenUnitPtr->out_func == OUT_Custom_Python) {
1437 hiddenUnitPtr->Out.output =
1438 kr_PythonOutFunction(hiddenUnitPtr->python_out_func,
1439 hiddenUnitPtr->act);
1440 }else{
1441 hiddenUnitPtr->Out.output =
1442 (*hiddenUnitPtr->out_func) (hiddenUnitPtr->act);
1443 }
1444 }
1445
1446 FOR_ALL_OUTPUT_UNITS(outputUnitPtr,o) {
1447 outputUnitPtr->act = (*outputUnitPtr->act_func) (outputUnitPtr);
1448 if(outputUnitPtr->out_func == OUT_IDENTITY) {
1449 outputUnitPtr->Out.output = outputUnitPtr->act;
1450 }else if(outputUnitPtr->out_func == OUT_Custom_Python){
1451 outputUnitPtr->Out.output =
1452 kr_PythonOutFunction(outputUnitPtr->python_out_func,
1453 outputUnitPtr->act);
1454 }else{
1455 outputUnitPtr->Out.output =
1456 (*outputUnitPtr->out_func) (outputUnitPtr->act);
1457 }
1458 }
1459 return(KRERR_NO_ERROR);
1460 }
1461
1462
1463
1464 /*****************************************************************************
1465 FUNCTION : UPDATE_DLVQ_Propagate
1466
1467 PURPOSE :
1468 RETURNS :
1469 NOTES :
1470
1471 UPDATE :
1472 ******************************************************************************/
UPDATE_DLVQ_Propagate(float parameterArray[],int NoOfParams)1473 krui_err UPDATE_DLVQ_Propagate(float parameterArray[], int NoOfParams)
1474 {
1475 struct Unit *inputUnitPtr,*hiddenUnitPtr,*maxActivatedUnitPtr=NULL;
1476 double maxAct,act;
1477 int i,h,startPattern,endPattern,d1,d2,d3,generatedNewUnit,noOfLinks;
1478
1479 if(newPatternsLoaded){
1480 newPatternsLoaded = 0;
1481 startPattern = 0;
1482 /* endPattern = krui_getNoOfPatterns()-1;*/
1483 endPattern = kr_TotalNoOfSubPatPairs()-1;
1484 KernelErrorCode = getNoOfClasses(startPattern,endPattern);
1485 ERROR_CHECK;
1486
1487 normPatterns(startPattern,endPattern);
1488 allocInitialUnitArray();
1489 initInitialUnitArray(startPattern,endPattern);
1490 }
1491
1492 if(NetModified || LearnFuncHasChanged) {
1493 NoOfInputUnits = NoOfHiddenUnits = NoOfOutputUnits = 0;
1494 FOR_ALL_UNITS(unitPtr) {
1495 if(IS_INPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
1496 NoOfInputUnits++;
1497 }
1498 if(IS_HIDDEN_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
1499 NoOfHiddenUnits++;
1500 }
1501 if(IS_OUTPUT_UNIT(unitPtr) && UNIT_IN_USE(unitPtr)) {
1502 NoOfOutputUnits++;
1503 }
1504 }
1505 if(NoOfOutputUnits != 1){
1506 return(DLVQ_ERROR3); /* Wrong no. of output units */
1507 }
1508 allocArrays();
1509 KernelErrorCode = kr_topoSort(TOPOLOGICAL_FF);
1510 ERROR_CHECK;
1511
1512 KernelErrorCode = dlvq_setPointers();
1513 ERROR_CHECK;
1514
1515 krui_getNetInfo(&d1,&noOfLinks,&d2,&d3);
1516 if(noOfLinks != NoOfInputUnits * NoOfHiddenUnits + NoOfHiddenUnits) {
1517 return(DLVQ_ERROR4); /* wrong topology */
1518 }
1519
1520 generateMissingClassHiddenUnits(&generatedNewUnit);
1521 if(generatedNewUnit) {
1522 return(DLVQ_ERROR5); /* There is not a class for every unit */
1523 }
1524 NetModified = FALSE;
1525 LearnFuncHasChanged = FALSE;
1526 }
1527
1528 FOR_ALL_INPUT_UNITS(inputUnitPtr,i){
1529 inputUnitPtr->Out.output = inputUnitPtr->act;
1530 }
1531
1532 maxAct = -1.0;
1533
1534 FOR_ALL_HIDDEN_UNITS(hiddenUnitPtr,h) {
1535 hiddenUnitPtr->Out.output = hiddenUnitPtr->act = act = 0.0;
1536 FOR_ALL_LINKS(hiddenUnitPtr,linkPtr) {
1537 act += linkPtr->weight * linkPtr->to->Out.output;
1538 }
1539 if(maxAct < act){
1540 maxAct = act;
1541 maxActivatedUnitPtr = hiddenUnitPtr;
1542 }
1543 }
1544
1545 maxActivatedUnitPtr->Out.output = maxActivatedUnitPtr->act = 1.0;
1546 (*FirstOutputUnitPtr)->Out.output =
1547 (*FirstOutputUnitPtr)->act = maxActivatedUnitPtr->bias;
1548 return(KRERR_NO_ERROR);
1549 }
1550
1551
1552
1553 /*****************************************************************************
1554 FUNCTION : UPDATE_BPTT
1555
1556 PURPOSE : Backpropagation through time synchronous order using activity
1557 buffer for each unit.
1558 RETURNS :
1559 NOTES : The "TEST" button in the remote panel first increases the pattern
1560 number, copies the input pattern to the input units and,
1561 depending on the setting of the "SHOW" button,
1562 - does not copy the output pattern with setting "none"
1563 - copies the output pattern to unit_ptr->act with setting
1564 "activation"
1565 - copies the output pattern to unit_ptr->act and
1566 unit_ptr->Out.output with setting "output"
1567 An all-zero-input pattern for reset is only effective using
1568 "TEST" if the current pattern is the pattern immediatly before
1569 the reset pattern.
1570 UPDATE :
1571 ******************************************************************************/
UPDATE_BPTT(float * parameterArray,int NoOfParams)1572 krui_err UPDATE_BPTT(float *parameterArray, int NoOfParams)
1573 {
1574 krui_err ret_code;
1575 register struct Unit *unit_ptr;
1576 register TopoPtrArray topo_ptr;
1577 register TopoPtrArray first_hidden_ptr;
1578 int all_zero_input=1; /* flag to reset net-copies */
1579 int done_hidden;
1580
1581 if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
1582 /* Net has been modified or topologic array isn't initialized */
1583 /* any connected topology allowed */
1584 /* count the no. of I/O units and check the patterns */
1585 ret_code = kr_IOCheck();
1586 if (ret_code < KRERR_NO_ERROR)
1587 return( ret_code );
1588
1589 /* sort units by ''topologic type'',
1590 criterion is visibility (input,hidden,output), not topology */
1591 ret_code = kr_topoSort( TOPOLOGIC_TYPE );
1592 if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
1593 return( ret_code );
1594
1595 NetModified = FALSE;
1596 }
1597
1598
1599 /* check all zero pattern in input layer => reset net_activities */
1600 topo_ptr = topo_ptr_array;
1601
1602 while ((unit_ptr = *++topo_ptr) != NULL) {
1603 unit_ptr->Out.output = unit_ptr->act;
1604 if(fabs(unit_ptr->act)>0.0001) all_zero_input = 0; /* no reset-input */
1605 }
1606 first_hidden_ptr = topo_ptr;
1607
1608 if (all_zero_input) { /* clear netact-copies */
1609 FOR_ALL_UNITS( unit_ptr ) unit_ptr->i_act = 0.0;
1610 }
1611
1612 /* copy last unit_ptr->i_act to unit_ptr->Out.output */
1613 /* one step back in time, make most recent activity
1614 visible in unit_ptr->Out.output for subsequent calls to act_func */
1615
1616 while ((unit_ptr = *++topo_ptr) != NULL) { /* hidden layer */
1617 unit_ptr->Out.output = unit_ptr->i_act; }
1618
1619 while ((unit_ptr = *++topo_ptr) != NULL) { /* output layer */
1620 unit_ptr->Out.output = unit_ptr->i_act; }
1621
1622 /* calculate new activities for hidden and output units */
1623 /* point to first hidden unit */
1624 topo_ptr = first_hidden_ptr;
1625 done_hidden=0;
1626 while ( ((unit_ptr = *++topo_ptr) != NULL) || (done_hidden==0))
1627 if (unit_ptr == NULL) {
1628 done_hidden = 1;
1629 }else{
1630 /* calc act using i_act copied to Out.output, SYNCHRONOUS UPDATE:
1631 don't update Out.output while updating units, wait until all
1632 units are processed */
1633 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
1634 }
1635
1636 /* calculate new Out.output values from act by calling out_func,
1637 and save values in i_act (since they may be disturbed by show pattern)*/
1638
1639 /* point to first hidden unit */
1640 topo_ptr = first_hidden_ptr;
1641 done_hidden=0;
1642 while ( ((unit_ptr = *++topo_ptr) != NULL) || (done_hidden==0))
1643 if (unit_ptr == NULL) {
1644 done_hidden = 1;
1645 }else{
1646 if (unit_ptr->out_func == OUT_IDENTITY) {
1647 unit_ptr->Out.output = unit_ptr->act;
1648 }else if(unit_ptr->out_func == OUT_Custom_Python){
1649 unit_ptr->Out.output =
1650 kr_PythonOutFunction(unit_ptr->python_out_func,
1651 unit_ptr->act);
1652 }else{
1653 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
1654 }
1655 unit_ptr->i_act = unit_ptr->Out.output;
1656 }
1657
1658 return( KRERR_NO_ERROR );
1659 }
1660
1661
1662
1663 /*****************************************************************************
1664 FUNCTION : UPDATE_BAM
1665
1666 PURPOSE :
1667 RETURNS :
1668 NOTES :
1669
1670 UPDATE :
1671 ******************************************************************************/
UPDATE_BAM(float * parameterArray,int NoOfParams)1672 krui_err UPDATE_BAM(float *parameterArray, int NoOfParams)
1673 {
1674 krui_err ret_code;
1675 register struct Unit *unit_ptr;
1676 register TopoPtrArray topo_ptr;
1677 register TopoPtrArray first_hidden_ptr;
1678 int done_hidden;
1679 FlintType new_output;
1680
1681 if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
1682 /* Net has been modified or topologic array isn't initialized */
1683 /* any connected topology allowed */
1684 /* count the no. of I/O units and check the patterns */
1685 ret_code = kr_IOCheck();
1686 if (ret_code < KRERR_NO_ERROR)
1687 return( ret_code );
1688
1689 /* sort units by ''topologic type'',
1690 criterion is visibility (input,hidden,output), not topology */
1691 ret_code = kr_topoSort( TOPOLOGIC_TYPE );
1692 if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
1693 return( ret_code );
1694
1695 NetModified = FALSE;
1696 }
1697
1698 /* Search hidden Units */
1699 topo_ptr = topo_ptr_array;
1700 while ((unit_ptr = *++topo_ptr) != NULL) {
1701 }
1702 first_hidden_ptr = topo_ptr;
1703
1704 /* calculate new Out.output values from act by calling out_func */
1705 /* point to first hidden unit and remember the old ones*/
1706 topo_ptr = first_hidden_ptr;
1707 done_hidden=0;
1708 while ( ((unit_ptr = *++topo_ptr) != NULL) || (done_hidden==0))
1709 if (unit_ptr == NULL) {
1710 done_hidden = 1;
1711 }else{
1712 unit_ptr->value_a = unit_ptr->Out.output;
1713 if (unit_ptr->out_func == OUT_IDENTITY) {
1714 unit_ptr->Out.output = unit_ptr->act;
1715 }else if(unit_ptr->out_func == OUT_Custom_Python){
1716 unit_ptr->Out.output =
1717 kr_PythonOutFunction(unit_ptr->python_out_func,
1718 unit_ptr->act);
1719 }else{
1720 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
1721 }
1722 }
1723
1724
1725 /* calculate new activities for hidden and output units */
1726 /* point to first hidden unit */
1727 topo_ptr = first_hidden_ptr;
1728 done_hidden=0;
1729 while ( ((unit_ptr = *++topo_ptr) != NULL) || (done_hidden==0))
1730 if (unit_ptr == NULL) {
1731 done_hidden = 1;
1732 }else{
1733 /* save new value and restore old value from output */
1734 new_output = unit_ptr->Out.output;
1735 unit_ptr->Out.output = unit_ptr->value_a;
1736
1737 /* calc act */
1738 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
1739
1740 /* restore new value */
1741 unit_ptr->Out.output = new_output;
1742 }
1743
1744 return( KRERR_NO_ERROR );
1745 }
1746
1747
1748
1749 /*****************************************************************************
1750 FUNCTION : UPDATE_JE_Propagate
1751
1752 PURPOSE : update function for JORDAN / ELMAN networks
1753 NOTES :
1754
1755 UPDATE :
1756 ******************************************************************************/
UPDATE_JE_Propagate(float * parameterArray,int NoOfParams)1757 krui_err UPDATE_JE_Propagate (float *parameterArray, int NoOfParams)
1758 {
1759 register struct Unit *unit_ptr ;
1760 register TopoPtrArray topo_ptr, help_ptr ;
1761 int ret_code, i ;
1762
1763
1764 if (NetModified || (TopoSortID != TOPOLOGICAL_JE)){
1765 /* network was modified or topologic array isn't initialized */
1766
1767 ret_code = kr_topoCheckJE () ;
1768 if (ret_code != KRERR_NO_ERROR) return (ret_code) ;
1769
1770 ret_code = kr_topoSort (TOPOLOGICAL_JE) ;
1771 if (ret_code != KRERR_NO_ERROR) return (ret_code) ;
1772
1773 NetModified = FALSE ;
1774 }
1775
1776 topo_ptr = topo_ptr_array ;
1777
1778
1779 /* calculate output of input units */
1780
1781 while ((unit_ptr = *++topo_ptr) != NULL){
1782 if (unit_ptr->out_func == OUT_IDENTITY)
1783 unit_ptr->Out.output = unit_ptr->act ;
1784 else if(unit_ptr->out_func == OUT_Custom_Python)
1785 unit_ptr->Out.output =
1786 kr_PythonOutFunction(unit_ptr->python_out_func,
1787 unit_ptr->act) ;
1788 else
1789 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
1790 }
1791
1792
1793 /* propagate hidden and output units */
1794
1795 for (i = 0 ; i < 2 ; i++){
1796 while ((unit_ptr = *++topo_ptr) != NULL){
1797 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr) ;
1798
1799 if (unit_ptr->out_func == OUT_IDENTITY)
1800 unit_ptr->Out.output = unit_ptr->act ;
1801 else if(unit_ptr->out_func == OUT_Custom_Python)
1802 unit_ptr->Out.output =
1803 kr_PythonOutFunction(unit_ptr->python_out_func,
1804 unit_ptr->act) ;
1805 else
1806 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
1807 }
1808 }
1809
1810
1811 /* update of context units */
1812
1813 help_ptr = topo_ptr ;
1814
1815 while ((unit_ptr = *++help_ptr) != NULL){
1816 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr) ;
1817 }
1818
1819 while ((unit_ptr = *++topo_ptr) != NULL){
1820 if (unit_ptr->out_func == OUT_IDENTITY)
1821 unit_ptr->Out.output = unit_ptr->act ;
1822 else if(unit_ptr->out_func == OUT_Custom_Python)
1823 unit_ptr->Out.output =
1824 kr_PythonOutFunction(unit_ptr->python_out_func,
1825 unit_ptr->act) ;
1826 else
1827 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
1828 }
1829
1830 return (KRERR_NO_ERROR) ;
1831 }
1832
1833
1834
1835 /*****************************************************************************
1836 FUNCTION : UPDATE_JE_Special
1837
1838 PURPOSE : update function with dynamic pattern generation for JORDAN /
1839 ELMAN networks
1840 NOTES :
1841
1842 UPDATE :
1843 ******************************************************************************/
UPDATE_JE_Special(float * parameterArray,int NoOfParams)1844 krui_err UPDATE_JE_Special (float *parameterArray, int NoOfParams)
1845 {
1846 register struct Unit *unit_ptr ;
1847 register TopoPtrArray topo_ptr, help_ptr ;
1848 int ret_code, i ;
1849
1850
1851 if (NetModified || (TopoSortID != TOPOLOGICAL_JE)){
1852 /* network was modified or topologic array isn't initialized */
1853
1854 ret_code = kr_topoCheckJE () ;
1855 if (ret_code != KRERR_NO_ERROR) return (ret_code) ;
1856
1857 ret_code = kr_topoSort (TOPOLOGICAL_JE) ;
1858 if (ret_code != KRERR_NO_ERROR) return (ret_code) ;
1859
1860 NetModified = FALSE ;
1861 }
1862
1863 if (NoOfInputUnits < NoOfOutputUnits) return (-1) ;
1864
1865
1866 /* create new input pattern from the output of input and output units */
1867
1868 help_ptr = topo_ptr_array ;
1869 while (*++help_ptr != NULL) ; /* skip input units */
1870 while (*++help_ptr != NULL) ; /* skip hidden units */
1871
1872 topo_ptr = topo_ptr_array ;
1873
1874 for (i = 1 ; i <= NoOfInputUnits ; i++)
1875 if (i <= NoOfInputUnits - NoOfOutputUnits)
1876 (*(topo_ptr+i))->act = (*(topo_ptr+i+NoOfOutputUnits))->Out.output;
1877 else
1878 (*(topo_ptr+i))->act = (*++help_ptr)->Out.output ;
1879
1880 topo_ptr = topo_ptr_array ;
1881
1882
1883 /* calculate output of input units */
1884
1885 while ((unit_ptr = *++topo_ptr) != NULL){
1886 if (unit_ptr->out_func == OUT_IDENTITY)
1887 unit_ptr->Out.output = unit_ptr->act ;
1888 else if(unit_ptr->out_func == OUT_Custom_Python)
1889 unit_ptr->Out.output =
1890 kr_PythonOutFunction(unit_ptr->python_out_func,
1891 unit_ptr->act) ;
1892 else
1893 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
1894 }
1895
1896
1897 /* propagate hidden and output units */
1898
1899 for (i = 0 ; i < 2 ; i++){
1900 while ((unit_ptr = *++topo_ptr) != NULL){
1901 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr) ;
1902
1903 if (unit_ptr->out_func == OUT_IDENTITY)
1904 unit_ptr->Out.output = unit_ptr->act ;
1905 else if(unit_ptr->out_func == OUT_Custom_Python)
1906 unit_ptr->Out.output =
1907 kr_PythonOutFunction(unit_ptr->python_out_func,
1908 unit_ptr->act) ;
1909 else
1910 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
1911 }
1912 }
1913
1914
1915 /* synchronous update of context units */
1916
1917 help_ptr = topo_ptr ;
1918
1919 while ((unit_ptr = *++help_ptr) != NULL){
1920 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr) ;
1921 }
1922
1923 while ((unit_ptr = *++topo_ptr) != NULL){
1924 if (unit_ptr->out_func == OUT_IDENTITY)
1925 unit_ptr->Out.output = unit_ptr->act ;
1926 else if(unit_ptr->out_func == OUT_Custom_Python)
1927 unit_ptr->Out.output =
1928 kr_PythonOutFunction(unit_ptr->python_out_func,
1929 unit_ptr->act) ;
1930 else
1931 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act) ;
1932 }
1933
1934 return (KRERR_NO_ERROR) ;
1935 }
1936
1937
1938
1939 /*****************************************************************************
1940 FUNCTION : UPDATE_syncPropagateHop
1941
1942 PURPOSE : synchronous propagation for Hopfield
1943 RETURNS :
1944 NOTES :
1945
1946 UPDATE :
1947 ******************************************************************************/
UPDATE_syncPropagateHop(float * parameterArray,int NoOfParams)1948 krui_err UPDATE_syncPropagateHop(float *parameterArray, int NoOfParams)
1949 {
1950 register struct Unit *unit_ptr;
1951
1952 /* update unit outputs first, because the patterns set only */
1953 /* the activations of the input units, and they would be overwritten */
1954 FOR_ALL_UNITS( unit_ptr ) {
1955 if UNIT_IN_USE(unit_ptr) {
1956 if (unit_ptr->out_func == OUT_IDENTITY) {
1957 unit_ptr->Out.output = unit_ptr->act;
1958 }else if(unit_ptr->out_func == OUT_Custom_Python){ /* the default way */
1959 unit_ptr->Out.output =
1960 kr_PythonOutFunction(unit_ptr->python_out_func,
1961 unit_ptr->act);
1962 }else{ /* the default way */
1963 unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
1964 }
1965 }
1966 }
1967
1968 /* update unit activations second */
1969
1970 /* first non input, then input units, so function can be used for BAM too */
1971 FOR_ALL_UNITS( unit_ptr ){
1972 if (UNIT_IN_USE(unit_ptr)&&!IS_INPUT_UNIT(unit_ptr))
1973 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
1974 }
1975
1976 /* output update of non input units (for resultfile) */
1977 FOR_ALL_UNITS( unit_ptr ) {
1978 if (UNIT_IN_USE(unit_ptr) && !IS_INPUT_UNIT(unit_ptr)) {
1979 if (unit_ptr->out_func == OUT_IDENTITY) {
1980 unit_ptr->Out.output = unit_ptr->act;
1981 }else if(unit_ptr->out_func == OUT_Custom_Python){ /* the default way */
1982 unit_ptr->Out.output =
1983 kr_PythonOutFunction(unit_ptr->python_out_func,
1984 unit_ptr->act);
1985 }else{ /* the default way */
1986 unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
1987 }
1988 }
1989 }
1990
1991 /* update input units */
1992
1993 FOR_ALL_UNITS( unit_ptr ){
1994 if (UNIT_IN_USE(unit_ptr)&&IS_INPUT_UNIT(unit_ptr))
1995 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
1996 }
1997
1998 /* output update of input units (for resultfile) */
1999
2000 FOR_ALL_UNITS( unit_ptr ) {
2001 if (UNIT_IN_USE(unit_ptr) && IS_INPUT_UNIT(unit_ptr)) {
2002 if (*unit_ptr->out_func == OUT_IDENTITY) {
2003 unit_ptr->Out.output = unit_ptr->act;
2004 }else if(unit_ptr->out_func == OUT_Custom_Python){ /* the default way */
2005 unit_ptr->Out.output =
2006 kr_PythonOutFunction(unit_ptr->python_out_func,
2007 unit_ptr->act);
2008 }else{ /* the default way */
2009 unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
2010 }
2011 }
2012 }
2013
2014 return( KRERR_NO_ERROR );
2015 }
2016
2017
2018
2019 /*****************************************************************************
2020 FUNCTION : UPDATE_FixAct_Hop
2021
2022 PURPOSE : synchronous update with fixed activity
2023 RETURNS :
2024 NOTES : the units updated are given the activity 1 the others 0
2025 To decide which units are to be updated, the arrays
2026 'unitsToUpdate' and 'netInputArray' are needed:
2027 'netInputArray' contains the n highest netinputs ( n = NoOfOnes )
2028 'unitsToUpdate' contains the corresponding unit pointers, so that
2029 unitsToUpdate[i] points to the unit which has netinput equal to
2030 netInputArray[i].
2031 UPDATE :
2032 ******************************************************************************/
UPDATE_FixAct_Hop(float * parameterArray,int NoOfParams)2033 krui_err UPDATE_FixAct_Hop(float *parameterArray, int NoOfParams)
2034 {
2035 register struct Unit *unit_ptr;
2036 FlintType sum, aux, min;
2037 ACT_FUNC_DEFS /* defines link- and site-pointer */
2038 register int i;
2039 int NoOfOnes, where;
2040 struct Unit **unitsToUpdate;
2041 FlintType *netInputArray;
2042
2043
2044 NoOfOnes = parameterArray[0]; /* the fixed Number of 1 */
2045
2046 /* init netInputArray and unitsToUpdate */
2047 netInputArray = (FlintType *) calloc(NoOfOnes, sizeof(FlintType));
2048 unitsToUpdate = (struct Unit * *) calloc(NoOfOnes, sizeof( struct Unit *));
2049 for(i=0; i<= NoOfOnes-1; i++) {
2050 unitsToUpdate[i] = NULL;
2051 netInputArray[i] = -9e37;
2052 }
2053
2054 FOR_ALL_UNITS(unit_ptr) {
2055 if UNIT_IN_USE(unit_ptr) {
2056 if (*unit_ptr->out_func == OUT_IDENTITY) {
2057 unit_ptr->Out.output = unit_ptr->act;
2058 }else if(unit_ptr->out_func == OUT_Custom_Python){/* the default way */
2059 unit_ptr->Out.output =
2060 kr_PythonOutFunction(unit_ptr->python_out_func,
2061 unit_ptr->act);
2062 }else{/* the default way */
2063 unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
2064 }
2065 }
2066 }
2067
2068
2069 /* find the units to update (their nr. is given by "NoOfOnes") by
2070 saving the units with highest netinputs ( the netinputs are held in
2071 the netInputArray and if a higher netinput occures, it replaces the
2072 lowest value in the array ) */
2073
2074 FOR_ALL_UNITS(unit_ptr) {
2075 /* get the netInput of this unit */
2076 sum = 0.0; aux = 0.0;
2077 if (GET_FIRST_UNIT_LINK( unit_ptr )){
2078 do
2079 sum += GET_WEIGHTED_OUTPUT;
2080 while (GET_NEXT_LINK);
2081 }
2082
2083 /* get the min of netInputArray, i.e. the worst netinput value already
2084 computed */
2085
2086 min = netInputArray[0];
2087 where = 0;
2088 for(i = 1; i <= NoOfOnes - 1; i++) {
2089 if( netInputArray[i] < min) {
2090 min = netInputArray[i];
2091 where = i;
2092 }
2093 }
2094
2095 /* replace the lowest netinput with the actual one if this is higher
2096 and save the pointer to the actual unit in 'unitsToUpdate' */
2097
2098 if( sum > min ){
2099 netInputArray[where] = sum;
2100 unitsToUpdate[where] = unit_ptr;
2101 }
2102 }
2103
2104 /* update unit activations */
2105 FOR_ALL_UNITS(unit_ptr){
2106 unit_ptr->act = 0.0;
2107 }
2108 for(i=0; i<= NoOfOnes-1; i++){
2109 unit_ptr = unitsToUpdate[i];
2110 unit_ptr->act = 1.0;
2111 }
2112
2113 /* output update for resultfile */
2114 FOR_ALL_UNITS(unit_ptr) {
2115 if UNIT_IN_USE(unit_ptr) {
2116 if (*unit_ptr->out_func == OUT_IDENTITY) {
2117 unit_ptr->Out.output = unit_ptr->act;
2118 }else if(unit_ptr->out_func == OUT_Custom_Python){/* the default way */
2119 unit_ptr->Out.output =
2120 kr_PythonOutFunction(unit_ptr->python_out_func,
2121 unit_ptr->act);
2122 }else{/* the default way */
2123 unit_ptr->Out.output = (*unit_ptr->out_func)(unit_ptr->act);
2124 }
2125 }
2126 }
2127 free(netInputArray);
2128 free(unitsToUpdate);
2129
2130 return( KRERR_NO_ERROR );
2131 }
2132
2133
2134 /*****************************************************************************
2135 FUNCTION : UPDATE_RM_Propagate
2136
2137 PURPOSE :
2138 RETURNS :
2139 NOTES : McClelland & Rummelhart's update rule
2140
2141 UPDATE :
2142 ******************************************************************************/
UPDATE_RM_Propagate(float * parameterArray,int NoOfParams)2143 krui_err UPDATE_RM_Propagate (float *parameterArray, int NoOfParams)
2144 {
2145 register struct Unit *unit_ptr;
2146 int t, NoTimes;
2147
2148 NoTimes = parameterArray[0];
2149
2150 for (t=0; t < NoTimes; ++t){
2151
2152 /* update unit activations */
2153 FOR_ALL_UNITS( unit_ptr )
2154 if UNIT_IN_USE( unit_ptr )
2155 if ( !IS_INPUT_UNIT( unit_ptr))
2156 /* unit isn't an input unit and is in use and enabled */
2157 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
2158
2159 /* update unit outputs */
2160 FOR_ALL_UNITS( unit_ptr )
2161 if UNIT_IN_USE( unit_ptr )
2162 if (unit_ptr->out_func == OUT_IDENTITY)
2163 /* identity output function: don't call output function */
2164 unit_ptr->Out.output = unit_ptr->act;
2165 else if(unit_ptr->out_func == OUT_Custom_Python)
2166 unit_ptr->Out.output =
2167 kr_PythonOutFunction(unit_ptr->python_out_func,
2168 unit_ptr->act);
2169 else
2170 /* calculate unit's output also */
2171 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
2172 }
2173
2174 return( KRERR_NO_ERROR );
2175
2176 }
2177
2178
2179 /*#########################################################
2180
2181 GROUP: Update Functions for the use with the GA tool Enzo
2182
2183 #########################################################*/
2184
2185
2186
2187 /*****************************************************************************
2188 FUNCTION : ENZO_PROPAGATE_error_back()
2189
2190 PURPOSE :
2191 RETURNS :
2192 NOTES :
2193
2194 UPDATE :
2195 ******************************************************************************/
ENZO_PROPAGATE_error_back(void)2196 static krui_err ENZO_PROPAGATE_error_back(void)
2197 {
2198 register struct Link *link_ptr;
2199 register struct Site *site_ptr;
2200 register struct Unit *unit_ptr;
2201 register float error; /* error */
2202 TopoPtrArray topo_ptr;
2203 int ret_code;
2204
2205 if (NetModified || (TopoSortID != TOPOLOGICAL_FF))
2206 { /* Net has been modified or topologic array isn't initialized */
2207 /* check the topology of the network */
2208 ret_code = kr_topoCheck();
2209 if(ret_code < KRERR_NO_ERROR) return(ret_code); /* an error has occured */
2210 if(ret_code<2)return(KRERR_NET_DEPTH); /* network has less than 2 layers */
2211
2212 /* count the no. of I/O units and check the patterns */
2213 ret_code = kr_IOCheck();
2214 if (ret_code < KRERR_NO_ERROR) return( ret_code );
2215
2216 /* sort units by topology and by topologic type */
2217 ret_code = kr_topoSort( TOPOLOGICAL_FF );
2218 if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
2219 return( ret_code );
2220
2221 NetModified = FALSE;
2222 }
2223
2224 /* add 3 to no_of_topo_units because the topologic array contains
2225 4 NULL pointers */
2226 topo_ptr = topo_ptr_array + (no_of_topo_units + 3);
2227
2228 /* calculate output units only */
2229 while ((unit_ptr = *--topo_ptr) != NULL) {
2230 /* Out.output == dEdw */
2231 error = - unit_ptr->Out.output * ((unit_ptr->act_deriv_func) ( unit_ptr ));
2232 unit_ptr->value_c += -error /* * 1 */; /* calculate the bias slopes */
2233 /* learn bias like a weight */
2234 if (UNIT_HAS_DIRECT_INPUTS( unit_ptr ))
2235 { /* the unit has direct links */
2236 FOR_ALL_LINKS( unit_ptr, link_ptr )
2237 { /* calculate the slopes */
2238 link_ptr->value_c += - error * link_ptr->to->Out.output;
2239 link_ptr->to->Aux.flint_no += link_ptr->weight * error;
2240 }
2241 }
2242 else
2243 { /* the unit has sites */
2244 FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
2245 { /* calculate the value_cs */
2246 link_ptr->value_c += - error * link_ptr->to->Out.output;
2247 link_ptr->to->Aux.flint_no += link_ptr->weight * error;
2248 }
2249 }
2250 }
2251
2252
2253 /* calculate hidden units only */
2254 while ((unit_ptr = *--topo_ptr) != NULL) {
2255 error = ((unit_ptr->act_deriv_func) (unit_ptr)) * unit_ptr->Aux.flint_no;
2256
2257 unit_ptr->value_c += - error /* * 1 */; /* calculate the bias slopes */
2258 /* learn bias like a weight */
2259 if (UNIT_HAS_DIRECT_INPUTS( unit_ptr )){
2260 /* the unit has direct links */
2261 FOR_ALL_LINKS( unit_ptr, link_ptr ){
2262 /* calculate the slopes */
2263 if (link_ptr->to->flags & UFLAG_TTYP_HIDD)
2264 /* this link points to a hidden unit:
2265 sum up the error's from previos units */
2266 link_ptr->to->Aux.flint_no += link_ptr->weight * error;
2267
2268 link_ptr->value_c += - error * link_ptr->to->Out.output;
2269 }
2270 } else { /* the unit has sites */
2271 FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr ){
2272 /* calculate the slopes */
2273 if (link_ptr->to->flags & UFLAG_TTYP_HIDD)
2274 /* this link points to a hidden unit:
2275 sum up the error's from previos units */
2276 link_ptr->to->Aux.flint_no += link_ptr->weight * error;
2277
2278 link_ptr->value_c += - error * link_ptr->to->Out.output;
2279 }
2280 }
2281 }
2282 return( KRERR_NO_ERROR );
2283 }
2284
2285
2286
2287 /*****************************************************************************
2288 FUNCTION : ENZO_PROPAGATE_ff
2289
2290 PURPOSE :
2291 RETURNS :
2292 NOTES :
2293
2294 UPDATE :
2295 ******************************************************************************/
ENZO_PROPAGATE_ff(void)2296 static krui_err ENZO_PROPAGATE_ff(void)
2297 {
2298 register struct Unit *unit_ptr;
2299 register TopoPtrArray topo_ptr;
2300 int ret_code;
2301
2302 if (NetModified || (TopoSortID != TOPOLOGICAL_FF))
2303 { /* Net has been modified or topologic array isn't initialized */
2304 /* check the topology of the network */
2305 ret_code = kr_topoCheck();
2306 if(ret_code < KRERR_NO_ERROR) return(ret_code); /* an error has occured */
2307 if(ret_code<2)return(KRERR_NET_DEPTH); /* network has less than 2 layers */
2308
2309 /* count the no. of I/O units and check the patterns */
2310 ret_code = kr_IOCheck();
2311 if (ret_code < KRERR_NO_ERROR) return( ret_code );
2312
2313 /* sort units by topology and by topologic type */
2314 ret_code = kr_topoSort( TOPOLOGICAL_FF );
2315 if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
2316 return( ret_code );
2317
2318 NetModified = FALSE;
2319 }
2320
2321
2322 topo_ptr = topo_ptr_array;
2323
2324 /* copy pattern into input unit's activation and
2325 calculate output of the input units
2326 */
2327 while ((unit_ptr = *++topo_ptr) != NULL)
2328 { /* topo_ptr points to a (topological sorted) unit stucture (input units first) */
2329 if (unit_ptr->out_func == OUT_IDENTITY)
2330 /* identity output function: no need to call the output function */
2331 unit_ptr->Out.output = unit_ptr->act;
2332 else if(unit_ptr->out_func == OUT_Custom_Python)
2333 unit_ptr->Out.output =
2334 kr_PythonOutFunction(unit_ptr->python_out_func,
2335 unit_ptr->act);
2336 else
2337 /* no identity output function: calculate unit's output also */
2338 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
2339 }
2340
2341 /* popagate hidden units */
2342 while ((unit_ptr = *++topo_ptr) != NULL)
2343 { /* topo_ptr points to a (topological sorted) unit stucture */
2344 /* clear error values */
2345 unit_ptr->Aux.flint_no = 0.0;
2346
2347 /* calculate the activation value of the unit:
2348 call the activation function if needed */
2349 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
2350
2351 if (unit_ptr->out_func == OUT_IDENTITY)
2352 /* identity output function: no need to call the output function */
2353 unit_ptr->Out.output = unit_ptr->act;
2354 else if(unit_ptr->out_func == OUT_Custom_Python)
2355 unit_ptr->Out.output =
2356 kr_PythonOutFunction(unit_ptr->python_out_func,
2357 unit_ptr->act);
2358 else
2359 /* no identity output function: calculate unit's output also */
2360 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
2361 }
2362
2363 /* popagate output units */
2364 while ((unit_ptr = *++topo_ptr) != NULL)
2365 { /* topo_ptr points to a (topological sorted) unit stucture */
2366 /* clear error values */
2367 unit_ptr->Aux.flint_no = 0.0;
2368
2369 /* calculate the activation value of the unit:
2370 call the activation function if needed */
2371 unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
2372
2373 if (unit_ptr->out_func == OUT_IDENTITY)
2374 /* identity output function: no need to call the output function */
2375 unit_ptr->Out.output = unit_ptr->act;
2376 else if(unit_ptr->out_func == OUT_Custom_Python)
2377 unit_ptr->Out.output =
2378 kr_PythonOutFunction(unit_ptr->python_out_func,
2379 unit_ptr->act);
2380 else
2381 /* no identity output function: calculate unit's output also */
2382 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
2383 }
2384 return( KRERR_NO_ERROR );
2385 }
2386
2387
2388
2389 /*****************************************************************************
2390 FUNCTION : ENZO_propagate
2391
2392 PURPOSE :
2393 RETURNS :
2394 NOTES : If the Input-Parameter is 0, the input activation is propagated
2395 forward, else the error gradient is propagated backward.
2396 This is done because NetInitialized is set TRUE every
2397 time the Update-function is changed.
2398 UPDATE :
2399 ******************************************************************************/
ENZO_propagate(float * parameterArray,int NoOfParams)2400 krui_err ENZO_propagate( float *parameterArray, int NoOfParams )
2401 {
2402 if (NoOfParams < 1)
2403 return( KRERR_PARAMETERS ); /* not enough input parameters */
2404
2405 if (UPDATE_PARAM1 (parameterArray))
2406 return (ENZO_PROPAGATE_error_back()); /* rueckwaerts-Propagieren */
2407 else
2408 return (ENZO_PROPAGATE_ff()); /* vorwaerts-Propagieren */
2409 }
2410
2411
2412
2413
2414 /*#################################################
2415
2416 GROUP: User Defined Update Functions
2417
2418 #################################################*/
2419
2420