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