1 /*****************************************************************************
2   FILE           : $Source: /projects/higgs1/SNNS/CVS/SNNS/kernel/sources/kr_ui.c,v $
3   SHORTNAME      : kr_ui.c
4   SNNS VERSION   : 4.2
5 
6   PURPOSE        : SNNS-Kernel User Interface
7   NOTES          :
8 
9   AUTHOR         : Niels Mache
10   DATE           : 27.02.90
11 
12   CHANGED BY     : Michael Vogt, Guenter Mamier
13   RCS VERSION    : $Revision: 2.51 $
14   LAST CHANGE    : $Date: 1998/05/25 16:00:40 $
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 <stdio.h>
22 #include <stdlib.h>
23 #include <time.h>
24 #ifdef HAVE_SYS_TIME_H
25 #include <sys/time.h>
26 #endif
27 #include <string.h>
28 #include <memory.h>
29 #include <math.h>
30 
31 #ifndef rand
32 #include "random.h"      /*  Randomize Library Function Prototypes  */
33 #endif
34 
35 #include "kr_typ.h"      /*  Kernel Types and Constants  */
36 #include "glob_typ.h"
37 #include "kr_const.h"    /*  Constant Declarators for SNNS-Kernel  */
38 #include "kr_def.h"      /*  Default Values  */
39 
40 #include "kr_io.h"       /*  Kernel I/O-Routines */
41 #include "kr_funcs.h"    /*  Function Prototypes */
42 #include "kernel.h"      /*  Function Prototypes */
43 #include "kr_mem.h"      /*  Function Prototypes */
44 #include "kr_ui.ph"      /*  Interface function prototypes  */
45 #include "version.h"     /*  Version and Patchlevel  */
46 #include "kr_mac.h"      /*  Kernel Macros  */
47 #include "kr_newpattern.h"   /* new style pattern handling */
48 #include "kr_inversion.h" /* inversion algorithm routines */
49 #include "cc_glob.h"
50 #include "cc_display.h"
51 #include "trans_f.h"
52 #include "learn_f.h"
53 
54 #ifdef MASPAR_KERNEL
55 
56 #include "kr_feedf.h"    /*  Function Prototypes */
57 
58 #endif
59 
60 /************ Random seed storage **************/
61 long randomSeedVal=0;
62 /***********************************************/
63 
64 /*****************************************************************************
65   FUNCTION : krui_getNoOfUnits
66 
67   PURPOSE  :
68   NOTES    :
69 
70   RETURNS  : Returns the number of units used by the network.
71   UPDATE   :
72 ******************************************************************************/
krui_getNoOfUnits(void)73 int krui_getNoOfUnits(void)
74 {
75     return( NoOfUnits );
76 }
77 
78 
79 /*****************************************************************************
80   FUNCTION : krui_getFirstUnit
81 
82   PURPOSE  : Initializes the first available unit for access. If the unit has
83              sites, the first site will be set to the current site.
84   NOTES    :
85 
86   RETURNS  : Returns the unit no. of the first unit or 0 if no units available.
87   UPDATE   :
88 ******************************************************************************/
krui_getFirstUnit(void)89 int  krui_getFirstUnit(void)
90 {
91     return( kr_getUnit( FIRST ) );
92 }
93 
94 /*****************************************************************************
95   FUNCTION : krui_getNextUnit
96 
97   PURPOSE  : Initializes the next available unit for access. If the unit has
98              sites, the first site will be set to the current site.
99   NOTES    :
100 
101   RETURNS  : Returns the unit no. of the next unit or 0 if no more units
102              available.
103   UPDATE   :
104 ******************************************************************************/
krui_getNextUnit(void)105 int  krui_getNextUnit(void)
106 {
107     return( kr_getUnit( NEXT ) );
108 }
109 
110 /*****************************************************************************
111   FUNCTION : krui_getCurrentUnit
112 
113   PURPOSE  :
114   NOTES    :
115 
116   RETURNS  : Returns the no. of the current unit or 0 if no units available
117   UPDATE   :
118 ******************************************************************************/
krui_getCurrentUnit(void)119 int  krui_getCurrentUnit(void)
120 {
121     return( kr_getUnit( CURRENT ) );
122 }
123 
124 /*****************************************************************************
125   FUNCTION : krui_setCurrentUnit
126 
127   PURPOSE  : Initializes a unit for access. If the unit has sites, the first site
128     will be set to the current site.
129   NOTES    :
130 
131   RETURNS  : Returns error code if the given unit doesn't exist, 0 otherwise.
132   UPDATE   :
133 ******************************************************************************/
krui_setCurrentUnit(int unit_no)134 krui_err  krui_setCurrentUnit(int unit_no)
135 {
136     return( kr_setCurrUnit( unit_no ) );
137 }
138 
139 /*****************************************************************************
140   FUNCTION : krui_getUnitName
141 
142   PURPOSE  :
143   NOTES    :
144 
145   RETURNS  : Returns the name of the unit. (NULL if not available)
146   UPDATE   :
147 ******************************************************************************/
krui_getUnitName(int UnitNo)148 char  *krui_getUnitName(int UnitNo)
149 {
150     struct Unit   *unit_ptr;
151 
152     if ((unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
153         return( NULL );         /*  invalid unit #  */
154 
155     return( unit_ptr->unit_name );
156 }
157 
158 
159 /*****************************************************************************
160   FUNCTION : krui_setUnitName
161 
162   PURPOSE  : Sets the name of the unit <UnitNo>.
163              If the unit_name pointer is NULL, the unit's symbol will be deleted.
164              Function has no effect on the current unit.
165   NOTES    :
166 
167   RETURNS  : Returns error code if memory allocation fails, 0 otherwise.
168   UPDATE   :
169 ******************************************************************************/
krui_setUnitName(int unit_no,char * unit_name)170 krui_err  krui_setUnitName(int unit_no, char *unit_name)
171 {
172     struct Unit   *unit_ptr;
173     char    *str_ptr;
174 
175 
176     KernelErrorCode = KRERR_NO_ERROR;
177     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
178         return( KernelErrorCode );
179 
180     NetModified = TRUE;
181 
182     if (unit_name == NULL)
183         {
184             krm_NTableReleaseSymbol( unit_ptr->unit_name, UNIT_SYM );
185             unit_ptr->unit_name = NULL;
186             return( KernelErrorCode );
187         }
188 
189     if (!kr_symbolCheck( unit_name ))  return( KernelErrorCode );
190 
191     if ( (str_ptr = krm_NTableInsertSymbol( unit_name, UNIT_SYM ) ) == NULL)
192         return( KernelErrorCode );
193 
194     unit_ptr->unit_name = str_ptr;
195 
196     return( KernelErrorCode );
197 }
198 
199 /*****************************************************************************
200   FUNCTION : krui_searchUnitName
201 
202   PURPOSE  : Searches for a unit with the given name
203   NOTES    :
204 
205   RETURNS  : Returns the first unit no. if a unit with the given name was found,
206              0 otherwise.
207   UPDATE   :
208 ******************************************************************************/
krui_searchUnitName(char * unit_name)209 int  krui_searchUnitName(char *unit_name)
210 {
211     struct  NameTable  *n_ptr;
212 
213     if (NoOfUnits <= 0)  {
214         UICurrentNameSearchUnitNo = 0;
215         return( (int) KRERR_NO_UNITS ); /*  No Units defined  */
216     }
217 
218     if ((n_ptr = krm_NTableSymbolSearch( unit_name, UNIT_SYM )) == NULL)  {
219         UICurrentNameSearchUnitNo = 0;
220         return( 0 );
221     }
222 
223     UICurrentNameSearchUnitSymbolPtr = n_ptr->Entry.symbol;
224     UICurrentNameSearchUnitNo =
225 	kr_unitNameSearch( MinUnitNo, UICurrentNameSearchUnitSymbolPtr );
226 
227     return( UICurrentNameSearchUnitNo );
228 }
229 
230 
231 /*****************************************************************************
232   FUNCTION : krui_searchNextUnitName
233 
234   PURPOSE  : Searches for the next unit with the given name.
235   NOTES    : Call krui_searchUnitName( unit_name ) before calling krui_searchNextUnitName().
236              Returns error code if no units defined.
237 
238   RETURNS  : Returns the first unit no. if a unit with the given name was found,
239              0 otherwise.
240   UPDATE   :
241 ******************************************************************************/
krui_searchNextUnitName(void)242 int  krui_searchNextUnitName(void)
243 {
244 
245     if (NoOfUnits <= 0) {
246         UICurrentNameSearchUnitNo = 0;
247         return( KRERR_NO_UNITS ); /*  No Units defined  */
248     }
249 
250     if (UICurrentNameSearchUnitNo != 0) {
251         UICurrentNameSearchUnitNo =
252 	    kr_unitNameSearch( UICurrentNameSearchUnitNo + 1,
253 			       UICurrentNameSearchUnitSymbolPtr );
254         return( UICurrentNameSearchUnitNo );
255     }
256     else
257         return( 0 );
258 }
259 
260 /*****************************************************************************
261   FUNCTION : krui_getUnitOutFuncName
262 
263   PURPOSE  :
264   NOTES    :
265 
266   RETURNS  : Returns the output function name of the unit.
267   UPDATE   :
268 ******************************************************************************/
krui_getUnitOutFuncName(int UnitNo)269 char  *krui_getUnitOutFuncName(int UnitNo)
270 {
271     struct Unit   *unit_ptr;
272     static char  out_func_name[FUNCTION_NAME_MAX_LEN];
273 
274     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
275         return( NULL );         /*  invalid unit #  */
276 
277     if(unit_ptr->out_func == OUT_Custom_Python) {
278     	strncpy(out_func_name,
279 		krf_getFuncName((FunctionPtr) unit_ptr->python_out_func),
280 		sizeof(out_func_name)-1);
281 	out_func_name[sizeof(out_func_name)-1]=0;
282     } else strcpy( out_func_name, krf_getFuncName( (FunctionPtr) unit_ptr->out_func ));
283 
284     return( out_func_name );
285 }
286 
287 /*****************************************************************************
288   FUNCTION : krui_setUnitOutFunc(
289 
290   PURPOSE  : he unit's FType will be set to 0, i.e. the
291              unit's functionality type will be deleted.
292              Function has no effect on the current unit.
293   NOTES    :
294 
295   RETURNS  : returns 0, if the function is a valid output function,
296              error code otherwise.
297   UPDATE   :
298 ******************************************************************************/
krui_setUnitOutFunc(int unit_no,char * unitOutFuncName)299 krui_err  krui_setUnitOutFunc(int unit_no, char *unitOutFuncName)
300 {
301     struct Unit   *unit_ptr;
302     FunctionPtr func_ptr;
303 
304 
305 #ifdef MASPAR_KERNEL
306     MASPAR_FF1_VALIDATE_OP;
307 #endif
308 
309     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
310         return( KernelErrorCode );
311 
312     if ( !krf_funcSearch( unitOutFuncName, OUT_FUNC, &func_ptr ))
313         return( KernelErrorCode );
314 
315     unit_ptr->out_func = (OutFuncPtr) func_ptr;
316     unit_ptr->Ftype_entry = NULL;
317     if((OutFuncPtr)func_ptr == OUT_Custom_Python) {
318     	unit_ptr->python_out_func
319     			= kr_findPythonFunction(unitOutFuncName, OUT_FUNC);
320     }
321 
322     NetModified = TRUE;
323 
324     return( KRERR_NO_ERROR );
325 }
326 
327 /*****************************************************************************
328   FUNCTION : krui_getUnitActFuncName
329 
330   PURPOSE  :
331   NOTES    :
332 
333   RETURNS  : Returns the activation function name of the unit.
334   UPDATE   :
335 ******************************************************************************/
krui_getUnitActFuncName(int UnitNo)336 char  *krui_getUnitActFuncName(int UnitNo)
337 {
338     struct Unit   *unit_ptr;
339     static char  act_func_name[FUNCTION_NAME_MAX_LEN];
340 
341     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
342         return( NULL );         /*  invalid unit #  */
343 
344     if(unit_ptr->act_func == ACT_Custom_Python) {
345     	strncpy(act_func_name,
346 		krf_getFuncName((FunctionPtr) unit_ptr->python_act_func),
347 		sizeof(act_func_name)-1);
348 	act_func_name[sizeof(act_func_name)-1]=0;
349     } else strcpy( act_func_name, krf_getFuncName( (FunctionPtr) unit_ptr->act_func ));
350 
351     return( act_func_name );
352 }
353 
354 /*****************************************************************************
355   FUNCTION : krui_setUnitActFunc
356 
357   PURPOSE  : The unit's FType will be set to 0, i.e. the
358              unit's functionality type will be deleted.
359              Function has no effect on the current unit.
360   NOTES    :
361 
362   RETURNS  : returns 0, if the function is a valid activation function,
363              error code otherwise.
364   UPDATE   :
365 ******************************************************************************/
366 
367 extern FlintType ACT_Custom_Python(struct Unit *unit_ptr);
368 
krui_setUnitActFunc(int unit_no,char * unitActFuncName)369 krui_err  krui_setUnitActFunc(int unit_no, char *unitActFuncName)
370 {
371     struct Unit   *unit_ptr;
372     FunctionPtr   act_func_ptr, act_deriv_func_ptr, act_2_deriv_func_ptr;
373 
374 #ifdef MASPAR_KERNE
375     MASPAR_FF1_VALIDATE_OP;
376 #endif
377 
378     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
379         return( KernelErrorCode );
380     if ( !krf_funcSearch( unitActFuncName, ACT_FUNC, &act_func_ptr ))
381         return( KernelErrorCode );
382     /*  set the derivation function of the activation function  */
383     if( !krf_funcSearch( unitActFuncName, ACT_DERIV_FUNC, &act_deriv_func_ptr ))
384         return( KernelErrorCode );
385     /*  set the second derivation function of the activation function  */
386     if ( !krf_funcSearch( unitActFuncName, ACT_2_DERIV_FUNC,
387 			  &act_2_deriv_func_ptr ))
388         return( KernelErrorCode );
389 
390 
391     unit_ptr->act_func = (ActFuncPtr) act_func_ptr;
392     unit_ptr->act_deriv_func = (ActDerivFuncPtr) act_deriv_func_ptr;
393     unit_ptr->act_2_deriv_func = (ActDerivFuncPtr) act_2_deriv_func_ptr;
394     unit_ptr->Ftype_entry = NULL;
395 
396     if((ActFuncPtr)act_func_ptr == ACT_Custom_Python) {
397 	 unit_ptr->python_act_func =
398 	 	kr_findPythonFunction(unitActFuncName,ACT_FUNC);
399 	 unit_ptr->python_act_deriv_func =
400 	 	kr_findPythonFunction(unitActFuncName,ACT_DERIV_FUNC);
401 	 unit_ptr->python_act_2_deriv_func =
402 	 	kr_findPythonFunction(unitActFuncName,ACT_2_DERIV_FUNC);
403     }
404 
405     NetModified = TRUE;
406 
407     return( KRERR_NO_ERROR );
408 }
409 
410 /*****************************************************************************
411   FUNCTION : krui_getUnitFTypeName
412 
413   PURPOSE  :
414   NOTES    : Function has no effect on the current unit.
415 
416   RETURNS  : Returns the functionality type name of the unit.
417              Function has no effect on the current unit.
418              Returns NULL if unit has no FType.
419   UPDATE   :
420 ******************************************************************************/
krui_getUnitFTypeName(int UnitNo)421 char  *krui_getUnitFTypeName(int UnitNo)
422 {
423     struct FtypeUnitStruct    *Ftype_entry;
424     struct Unit   *unit_ptr;
425 
426     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
427         return( NULL );         /*  invalid unit #  */
428 
429     if ( (Ftype_entry = unit_ptr->Ftype_entry) == NULL)
430         return( NULL );
431 
432     return( Ftype_entry->Ftype_symbol->Entry.symbol );
433 }
434 
435 
436 
437 
438 /*****************************************************************************
439   FUNCTION : krui_getUnitActivation
440 
441   PURPOSE  :
442   NOTES    : Function has no effect on the current unit.
443 
444   RETURNS  : Returns the activation value of the unit.
445   UPDATE   :
446 ******************************************************************************/
krui_getUnitActivation(int UnitNo)447 FlintType  krui_getUnitActivation(int UnitNo)
448 {
449 
450     if KERNEL_STANDARD {
451         return( kr_getUnitValues( UnitNo, SEL_UNIT_ACT ) );
452     }
453     else  {
454 
455 #ifdef MASPAR_KERNEL
456 
457         return( krff_getUnitValues( UnitNo, SEL_UNIT_ACT ) );
458 
459 #else
460 
461         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
462         return( 0.0 );
463 
464 #endif
465     }
466 }
467 
468 
469 /*****************************************************************************
470   FUNCTION : krui_setUnitActivation
471 
472   PURPOSE  : Sets the activation value of the unit.
473              Function has no effect on the current unit.
474   NOTES    :
475 
476   RETURNS  :
477   UPDATE   :
478 ******************************************************************************/
479 krui_err  krui_setUnitActivation(int UnitNo, FlintTypeParam unit_activation)
480 {
481     krui_err err = KRERR_NO_ERROR;
482 
483     if KERNEL_STANDARD  {
484         err = kr_setUnitValues( UnitNo, SEL_UNIT_ACT, unit_activation );
485     }
486     else  {
487 
488 #ifdef MASPAR_KERNEL
489 
490         (void) krff_setUnitValues( UnitNo, SEL_UNIT_ACT, unit_activation );
491 
492 #else
493 
494         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
495 
496 #endif
497     }
498     return(err);
499 }
500 
501 /*****************************************************************************
502   FUNCTION : krui_getUnitInitialActivation
503 
504   PURPOSE  :
505   NOTES    : Function has no effect on the current unit.
506 
507   RETURNS  : Returns the initial activation value of the unit.
508   UPDATE   :
509 ******************************************************************************/
510 FlintType  krui_getUnitInitialActivation(int UnitNo)
511 {
512 
513     if KERNEL_STANDARD
514         return( kr_getUnitValues( UnitNo, SEL_UNIT_IACT ) );
515     else  {
516 
517 #ifdef MASPAR_KERNEL
518 
519         return( krff_getUnitValues( UnitNo, SEL_UNIT_IACT ) );
520 
521 #else
522 
523         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
524         return( 0.0 );
525 
526 #endif
527     }
528 }
529 
530 /*****************************************************************************
531   FUNCTION : krui_setUnitInitialActivation
532 
533   PURPOSE  : Sets the initial activation value of the unit.
534              Function has no effect on the current unit.
535   NOTES    :
536 
537   RETURNS  :
538   UPDATE   :
539 ******************************************************************************/
540 void  krui_setUnitInitialActivation(int UnitNo,
541 				    FlintTypeParam unit_i_activation)
542 {
543 
544     if KERNEL_STANDARD
545         kr_setUnitValues( UnitNo, SEL_UNIT_IACT, unit_i_activation );
546     else  {
547 
548 #ifdef MASPAR_KERNEL
549 
550         krff_setUnitValues( UnitNo, SEL_UNIT_IACT, unit_i_activation );
551 
552 #else
553 
554         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
555 
556 #endif
557     }
558 }
559 
560 
561 /*****************************************************************************
562   FUNCTION : krui_getUnitOutput
563 
564   PURPOSE  :
565   NOTES    : Function has no effect on the current unit.
566 
567   RETURNS  : Returns the output value of the unit.
568   UPDATE   :
569 ******************************************************************************/
570 FlintType  krui_getUnitOutput(int UnitNo)
571 {
572 
573     if KERNEL_STANDARD
574         return( kr_getUnitValues( UnitNo, SEL_UNIT_OUT ) );
575     else  {
576 
577 #ifdef MASPAR_KERNEL
578 
579         return( krff_getUnitValues( UnitNo, SEL_UNIT_OUT ) );
580 
581 #else
582 
583         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
584         return( 0.0 );
585 
586 #endif
587     }
588 }
589 
590 /*****************************************************************************
591   FUNCTION : krui_setUnitOutput
592 
593   PURPOSE  : Sets the output value of the unit.
594              Function has no effect on the current unit.
595   NOTES    :
596 
597   RETURNS  :
598   UPDATE   :
599 ******************************************************************************/
600 krui_err  krui_setUnitOutput(int unit_no, FlintTypeParam unit_output)
601 {
602 
603     if KERNEL_STANDARD  {
604         kr_setUnitValues( unit_no, SEL_UNIT_OUT, unit_output );
605     }
606     else  {
607 
608 #ifdef MASPAR_KERNEL
609 
610         krff_setUnitValues( unit_no, SEL_UNIT_OUT, unit_output );
611 
612 #else
613 
614         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
615 
616 #endif
617     }
618 
619     return( KernelErrorCode );
620 }
621 
622 /*****************************************************************************
623   FUNCTION : krui_getUnitBias
624 
625   PURPOSE  :
626   NOTES    : Function has no effect on the current unit.
627 
628   RETURNS  : Returns the bias value of the unit.
629   UPDATE   :
630 ******************************************************************************/
631 FlintType  krui_getUnitBias(int UnitNo)
632 {
633 
634     if KERNEL_STANDARD  {
635         return( kr_getUnitValues( UnitNo, SEL_UNIT_BIAS ) );
636     }
637     else  {
638 
639 #ifdef MASPAR_KERNEL
640 
641         return( krff_getUnitValues( UnitNo, SEL_UNIT_BIAS ) );
642 
643 #else
644 
645         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
646         return( 0.0 );
647 
648 #endif
649     }
650 }
651 /*****************************************************************************
652   FUNCTION : krui_setUnitBias
653 
654   PURPOSE  : Sets the bias value of the unit.
655              Function has no effect on the current unit.
656   NOTES    :
657 
658   RETURNS  :
659   UPDATE   :
660 ******************************************************************************/
661 void  krui_setUnitBias(int UnitNo, FlintTypeParam unit_bias)
662 {
663 
664     if KERNEL_STANDARD  {
665         kr_setUnitValues( UnitNo, SEL_UNIT_BIAS, unit_bias );
666     }
667     else  {
668 
669 #ifdef MASPAR_KERNEL
670 
671         krff_setUnitValues( UnitNo, SEL_UNIT_BIAS, unit_bias );
672 
673 #else
674 
675         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
676 
677 #endif
678     }
679 }
680 
681 /****************************************************************************
682   FUNCTION : krui_getUnitValueA
683   PURPOSE  :
684   NOTES    : Function has no effect on the current unit.
685 
686   RETURNS  : Returns Value A of the unit.
687   UPDATE   :
688 ****************************************************************************/
689 FlintType  krui_getUnitValueA(int UnitNo)
690 {
691 
692     if KERNEL_STANDARD  {
693         return( kr_getUnitValues( UnitNo, SEL_UNIT_VALA ) );
694     }
695     else  {
696 
697 #ifdef MASPAR_KERNEL
698 
699         return( krff_getUnitValues( UnitNo, SEL_UNIT_VALA ) );
700 
701 #else
702 
703         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
704         return( 0.0 );
705 
706 #endif
707     }
708 }
709 
710 /******************************************************************************
711   FUNCTION : krui_setUnitValueA
712 
713   PURPOSE  : Sets value a of the unit.
714   NOTES    : Function has no effect on the current unit.
715 
716 
717   RETURNS  :
718   UPDATE   :
719 *****************************************************************************/
720 void  krui_setUnitValueA(int UnitNo, FlintTypeParam unit_valueA)
721 {
722 
723     if KERNEL_STANDARD  {
724         kr_setUnitValues( UnitNo, SEL_UNIT_VALA, unit_valueA );
725     }
726     else  {
727 
728 #ifdef MASPAR_KERNEL
729 
730         krff_setUnitValues( UnitNo, SEL_UNIT_VALA, unit_valueA );
731 
732 #else
733 
734         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
735 
736 #endif
737     }
738 }
739 
740 /*****************************************************************************
741   FUNCTION : krui_getUnitSubnetNo
742 
743   PURPOSE  :
744   NOTES    : Function has no effect on the current unit.
745              The range of the subnet no. is -32736...+32735
746 
747   RETURNS  : Returns the subnet number of the unit.
748   UPDATE   :
749 ******************************************************************************/
750 int  krui_getUnitSubnetNo(int UnitNo)
751 {
752     struct Unit   *unit_ptr;
753 
754     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
755         return( 0 );            /*  invalid unit #  */
756 
757     return( (int) unit_ptr->subnet_no );
758 }
759 
760 
761 /*****************************************************************************
762   FUNCTION : krui_setUnitSubnetNo
763 
764   PURPOSE  : Sets the subnet number of the unit.
765              Function has no effect on the current unit.
766   NOTES    : The range of the subnet no. is -32736...+32735
767 
768   RETURNS  :
769   UPDATE   :
770 ******************************************************************************/
771 void  krui_setUnitSubnetNo(int UnitNo, int subnet_no)
772 {
773     struct Unit   *unit_ptr;
774 
775     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
776         return;                 /*  invalid unit #  */
777 
778     NetModified = TRUE;
779 
780     unit_ptr->subnet_no = (short) subnet_no;
781 }
782 
783 
784 /*****************************************************************************
785   FUNCTION : krui_getUnitLayerNo
786 
787   PURPOSE  :
788   NOTES    : Function has no effect on the current unit.
789              The range of the layer no. is -32736...+32735
790 
791   RETURNS  : Returns the layer number of the unit.
792   UPDATE   :
793 ******************************************************************************/
794 unsigned short  krui_getUnitLayerNo(int UnitNo)
795 {
796     struct Unit   *unit_ptr;
797 
798     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
799         return( 0 );            /*  invalid unit #  */
800 
801     return( (unsigned short) unit_ptr->layer_no );
802 }
803 
804 
805 /*****************************************************************************
806   FUNCTION : krui_setUnitLayerNo
807 
808   PURPOSE  : Sets the layer number of the unit.
809   NOTES    : Function has no effect on the current unit.
810              The range of the layer no. is -32736...+32735
811   RETURNS  :
812   UPDATE   :
813 ******************************************************************************/
814 void    krui_setUnitLayerNo(int UnitNo, int layer_no)
815 {
816     struct Unit   *unit_ptr;
817 
818     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
819         return;                 /*  invalid unit #  */
820 
821     NetModified = TRUE;
822 
823     unit_ptr->layer_no = (unsigned short) layer_no;
824 }
825 
826 
827 /*****************************************************************************
828   FUNCTION : krui_getUnitPosition
829 
830   PURPOSE  :
831   NOTES    : Function has no effect on the current unit.
832 
833   RETURNS  : Returns the position of the unit.
834   UPDATE   :
835 ******************************************************************************/
836 void    krui_getUnitPosition(int UnitNo, struct PosType *position)
837 {
838     struct Unit   *unit_ptr;
839 
840     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
841         return;                 /*  invalid unit #  */
842 
843     position->x = unit_ptr->unit_pos.x;
844     position->y = unit_ptr->unit_pos.y;
845     position->z = unit_ptr->unit_pos.z;
846 }
847 
848 
849 /*****************************************************************************
850   FUNCTION : krui_setUnitPosition
851 
852   PURPOSE  : Sets the position of the unit.
853   NOTES    : Function has no effect on the current unit
854 
855   RETURNS  :
856   UPDATE   :
857 ******************************************************************************/
858 void    krui_setUnitPosition(int UnitNo, struct PosType *position)
859 {
860     struct Unit   *unit_ptr;
861 
862     if ( (unit_ptr = kr_getUnitPtr( UnitNo ) ) == NULL)
863         return;                 /*  invalid unit #  */
864 
865     unit_ptr->unit_pos.x = position->x;
866     unit_ptr->unit_pos.y = position->y;
867     unit_ptr->unit_pos.z = position->z;
868 }
869 
870 
871 /*****************************************************************************
872   FUNCTION : krui_getUnitNoAtPosition
873 
874   PURPOSE  :
875   NOTES    : Function has no effect on the current unit.
876              This function is slow because it uses linear search to
877              find the unit with the given position.
878   REMARK   : getUnitNoAtPosition is for downward compatibility only.
879              Do not use this function in future applications.
880 
881   RETURNS  : Returns the unit no. at the given position and subnet number or 0, if
882              no unit exists at this position
883   UPDATE   :
884 ******************************************************************************/
885 int   krui_getUnitNoAtPosition(struct PosType *position, int subnet_no)
886 {
887     register int       i;
888     register short     x, y, net_no;
889     struct Unit     *unit_ptr;
890 
891     x = position->x;
892     y = position->y;
893 
894     net_no = (short) subnet_no;
895 
896     for (i = 1, unit_ptr = unit_array + 1;
897          i <= MaxUnitNo;
898          i++, unit_ptr++)
899         {
900             if ( UNIT_IN_USE( unit_ptr ) &&
901                 (unit_ptr->subnet_no == net_no) &&
902                 (unit_ptr->unit_pos.x == x) && (unit_ptr->unit_pos.y == y) )
903 
904                 return( i );
905         }
906 
907     return( 0 );
908 }
909 
910 
911 /*****************************************************************************
912   FUNCTION : krui_getUnitNoNearPosition
913 
914   PURPOSE  :
915   NOTES    : Function has no effect on the current unit.
916              This function is slow because it uses linear search to
917              find the unit with the given position.
918 
919   RETURNS  : Returns the unit no. near the given position and the specified
920              subnet no or 0, if no unit exists at this position.
921   UPDATE   :
922 ******************************************************************************/
923 int  krui_getUnitNoNearPosition(struct PosType *position, int subnet_no, int range, int gridWidth)
924 {
925     register int       i, devit, width;
926     register short     x, y, net_no;
927     struct Unit        *unit_ptr;
928 
929     x = position->x;
930     y = position->y;
931     net_no = (short) subnet_no;
932     devit = range;
933     width = gridWidth;
934 
935     for (i = 1, unit_ptr = unit_array + 1; i <= MaxUnitNo;
936          i++, unit_ptr++)
937         {
938             if ( UNIT_IN_USE( unit_ptr ) &&
939                 (unit_ptr->subnet_no == net_no) &&
940                 (abs( unit_ptr->unit_pos.x - x) * width <= devit) &&
941                 (abs( unit_ptr->unit_pos.y - y) * width <= devit) )
942                 return( i );
943         }
944 
945     return( 0 );
946 }
947 
948 
949 /*****************************************************************************
950   FUNCTION : krui_getUnitTType
951 
952   PURPOSE  :
953   NOTES    : Function has no effect on the current unit.
954 
955   RETURNS  : Returns the topologic type, i.e. input, output, hidden
956   UPDATE   :
957 ******************************************************************************/
958 int  krui_getUnitTType(int unit_no)
959 {
960     struct Unit   *unit_ptr;
961 
962     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
963         return( KernelErrorCode );
964 
965     return( kr_flags2TType( (int) unit_ptr->flags & UFLAG_TTYP_PAT ) );
966 }
967 
968 
969 /*****************************************************************************
970   FUNCTION : krui_setUnitTType
971 
972   PURPOSE  : Sets the topologic type of the unit.
973              Function has no effect on the current unit.
974   NOTES    :
975 
976   RETURNS  : Returns error code if topologic type or unit number is invalid.
977   UPDATE   :
978 ******************************************************************************/
979 krui_err  krui_setUnitTType(int unit_no, int UnitTType)
980 {
981 
982 #ifdef MASPAR_KERNEL
983     MASPAR_FF1_VALIDATE_OP;
984 #endif
985 
986     return( kr_unitSetTType( unit_no, UnitTType ) );
987 }
988 
989 
990 /*****************************************************************************
991   FUNCTION : krui_freezeUnit
992 
993   PURPOSE  : Freezes the output of a unit, i.e. the unit is disabled.
994              Function has no effect on the current unit.
995   NOTES    :
996 
997   RETURNS  :
998   UPDATE   :
999 ******************************************************************************/
1000 krui_err  krui_freezeUnit(int unit_no)
1001 {
1002     struct Unit   *unit_ptr;
1003 
1004 #ifdef MASPAR_KERNEL
1005     MASPAR_FF1_VALIDATE_OP;
1006 #endif
1007 
1008     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
1009         return( KernelErrorCode );
1010 
1011     unit_ptr->flags &= (~UFLAG_ENABLED);
1012     return( KRERR_NO_ERROR );
1013 }
1014 
1015 
1016 /*****************************************************************************
1017   FUNCTION : krui_unfreezeUnit
1018 
1019   PURPOSE  : Enables a previosly freezed unit.
1020              Function has no effect on the current unit.
1021   NOTES    :
1022 
1023   RETURNS  :
1024   UPDATE   :
1025 ******************************************************************************/
1026 krui_err  krui_unfreezeUnit(int unit_no)
1027 {
1028     struct Unit   *unit_ptr;
1029 
1030 #ifdef MASPAR_KERNEL
1031     MASPAR_FF1_VALIDATE_OP;
1032 #endif
1033 
1034     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
1035         return( KernelErrorCode );
1036 
1037     unit_ptr->flags |= UFLAG_ENABLED;
1038     return( KRERR_NO_ERROR );
1039 }
1040 
1041 
1042 /*****************************************************************************
1043   FUNCTION : krui_isUnitFrozen
1044 
1045   PURPOSE  :
1046   NOTES    :
1047 
1048   RETURNS  : Returns true, if unit is frozen
1049   UPDATE   :
1050 ******************************************************************************/
1051 bool  krui_isUnitFrozen(int unit_no)
1052 {
1053     struct Unit   *unit_ptr;
1054 
1055     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
1056         return( KernelErrorCode );
1057 
1058     return( (unit_ptr->flags & UFLAG_ENABLED) == 0 );
1059 }
1060 
1061 
1062 /*****************************************************************************
1063   FUNCTION : krui_getUnitInputType
1064 
1065   PURPOSE  :
1066   NOTES    : Function has no effect on the current unit.
1067 
1068   RETURNS  : Returns the input type of the unit:
1069              NO_INPUTS    : if the unit has not inputs (at least not now)
1070              SITES        : if the unit has one or more sites (and no direct
1071 	                    input links !)
1072              DIRECT_LINKS : if the unit has direct input links (and no sites !)
1073 
1074   UPDATE   :
1075 ******************************************************************************/
1076 int  krui_getUnitInputType(int unit_no)
1077 {
1078     struct Unit  *unit_ptr;
1079 
1080     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
1081         return( KernelErrorCode );
1082 
1083     switch ((int) unit_ptr->flags & UFLAG_INPUT_PAT)    {
1084       case UFLAG_NO_INP :  return( NO_INPUTS    );
1085       case UFLAG_SITES  :  return( SITES        );
1086       case UFLAG_DLINKS :  return( DIRECT_LINKS );
1087 
1088       default :  return( NO_INPUTS );
1089     }
1090 }
1091 
1092 
1093 /*****************************************************************************
1094   FUNCTION : krui_createDefaultUnit
1095 
1096   PURPOSE  :  creates a unit with default properties:
1097               1. default activation and output functions
1098               2. default activation and bias
1099               3. default position, subnet and layer number
1100               4. no functionality type
1101               5. no sites
1102               6. no inputs and outputs
1103               7. no unit_name
1104   NOTES    :  See file "kr_def.h" for more details about default presettings.
1105               Function has no effect on the current unit.
1106 
1107   RETURNS  :  Returns an (negative) error code, if memory allocation fails or
1108               invalid functions occured. Returns (positive) unit number otherwise.
1109   UPDATE   :
1110 ******************************************************************************/
1111 int  krui_createDefaultUnit(void)
1112 {
1113 
1114 #ifdef MASPAR_KERNEL
1115     MASPAR_FF1_VALIDATE_OP;
1116 #endif
1117 
1118     NetModified = TRUE;
1119     return( kr_makeDefaultUnit() );
1120 }
1121 
1122 
1123 /*****************************************************************************
1124   FUNCTION : krui_createUnit
1125 
1126   PURPOSE  : Creates a user defined unit.
1127              Returns an (negative) error code, if memory allocation fails or
1128              invalid functions occured. Returns (positive) unit number otherwise.
1129              Function has no effect on the current unit.
1130 
1131              Unit has additional default settings:
1132              1. default position, subnet and layer number
1133              2. no functionality type
1134              3. no sites
1135              4. no inputs and outputs
1136 
1137   NOTES    :
1138 
1139   RETURNS  :
1140   UPDATE   :
1141 ******************************************************************************/
1142 int  krui_createUnit(char *unit_name, char *out_func_name, char *act_func_name,
1143 		     FlintTypeParam i_act, FlintTypeParam bias)
1144 {
1145 
1146 #ifdef MASPAR_KERNEL
1147     MASPAR_FF1_VALIDATE_OP;
1148 #endif
1149 
1150     return( kr_createUnit( unit_name, out_func_name, act_func_name,
1151 			   i_act, bias) );
1152 }
1153 
1154 
1155 /*****************************************************************************
1156                  UNDOCUMENTED FUNCTION SINCE SNNS VERSION 3.0
1157                    !!!! DO NOT USE THIS FUNCTION ANY MORE  !!!
1158                    !!!! USE: krui_deleteUnitList() INSTEAD !!!
1159 
1160   FUNCTION : krui_deleteUnit
1161 
1162   PURPOSE  : Deletes a unit from network. Removes all links to other units.
1163   NOTES    : !!!! DO NOT USE THIS FUNCTION ANY MORE !!!
1164              !!!! USE: krui_deleteUnitList() INSTEAD !!!
1165 
1166   RETURNS  : Returns error code if unit doesn't exist.
1167   UPDATE   :
1168 ******************************************************************************/
1169 krui_err  krui_deleteUnit(int unit_no)
1170 {
1171     struct  Unit      *unit_ptr;
1172 
1173 
1174 #ifdef MASPAR_KERNEL
1175     MASPAR_FF1_VALIDATE_OP;
1176 #endif
1177 
1178     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
1179         return( KernelErrorCode );
1180 
1181     (void) kr_removeUnit( unit_ptr );
1182     NetModified = TRUE;
1183     return( KernelErrorCode );
1184 }
1185 
1186 
1187 /*****************************************************************************
1188   FUNCTION : krui_deleteUnitList
1189 
1190   PURPOSE  : Deletes 'no_of_units' from the network. The numbers of the
1191              units that have to be deleted are listed up in an array
1192              of integers beginning with index 0.
1193              This array is passed to parameter 'unit_list'.
1194              Removes all links to and from these units.
1195 
1196   NOTES    : Always use this function instead of krui_deleteUnit()
1197 
1198   RETURNS  : Returns error code if unit doesn't exist.
1199   UPDATE   :
1200 ******************************************************************************/
1201 krui_err  krui_deleteUnitList(int no_of_units, int unit_list[])
1202 {
1203     struct  Unit      *unit_ptr;
1204     int               i;
1205 
1206 #ifdef MASPAR_KERNEL
1207     MASPAR_FF1_VALIDATE_OP;
1208 #endif
1209 
1210     for (i=0; i < no_of_units; i++) {
1211         if ((unit_ptr = kr_getUnitPtr( unit_list[i] )) == NULL) {
1212             return( KernelErrorCode );
1213         } /*if*/
1214 
1215         (void) kr_removeUnit( unit_ptr );
1216     } /*for*/
1217 
1218     /* Now perform Garbage Collection */
1219     kr_forceUnitGC();
1220 
1221     NetModified = TRUE;
1222     return( KernelErrorCode );
1223 }
1224 
1225 
1226 /*****************************************************************************
1227   FUNCTION : krui_createFTypeUnit
1228 
1229   PURPOSE  : creates a unit with FType properties, but:
1230              1. no inputs and outputs
1231              2. default position, subnet and layer
1232 
1233   NOTES    : Function has no effect on the current unit.
1234 
1235   RETURNS  : Returns the unit number or (negative) error code if memory
1236              allocation fails or functionality type isn't defined.
1237   UPDATE   :
1238 ******************************************************************************/
1239 int  krui_createFTypeUnit(char *Ftype_symbol)
1240 {
1241     int     unit_no;
1242 
1243 #ifdef MASPAR_KERNEL
1244     MASPAR_FF1_VALIDATE_OP;
1245 #endif
1246 
1247     unit_no = kr_makeFtypeUnit( Ftype_symbol );
1248     if (KernelErrorCode != KRERR_NO_ERROR)
1249         return( KernelErrorCode );
1250 
1251     NetModified = TRUE;
1252     return( unit_no );
1253 }
1254 
1255 
1256 /*****************************************************************************
1257   FUNCTION : krui_setUnitFType
1258 
1259   PURPOSE  : Changes the properties of unit <UnitNo> to FType properties.
1260              Changes: activation/output function and site name/functions.
1261   NOTES    : Function has no effect on the current unit.
1262 
1263   RETURNS  : Returns an error code if
1264              - FType name doesn't exist or
1265              - unit doesn't exist or
1266              - memory allocation fails
1267              otherwise 0.
1268 
1269   UPDATE   :
1270 ******************************************************************************/
1271 krui_err  krui_setUnitFType(int unit_no, char *Ftype_symbol)
1272 {
1273     struct  Unit      *unit_ptr;
1274     struct  FtypeUnitStruct   *ftype_ptr;
1275 
1276 #ifdef MASPAR_KERNEL
1277     MASPAR_FF1_VALIDATE_OP;
1278 #endif
1279 
1280     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
1281         return( KernelErrorCode );
1282     if (!kr_symbolCheck( Ftype_symbol ))
1283         return( KernelErrorCode );
1284 
1285     if ( (ftype_ptr = krm_FtypeSymbolSearch( Ftype_symbol ) ) == NULL)
1286         {                       /*  Ftype name isn't defined    */
1287             KernelErrorCode = KRERR_FTYPE_SYMBOL;
1288             return( KernelErrorCode );
1289         }
1290 
1291     NetModified = TRUE;
1292     kr_changeFtypeUnit( unit_ptr, ftype_ptr );
1293     return( KRERR_NO_ERROR );
1294 }
1295 
1296 
1297 /*****************************************************************************
1298   FUNCTION : krui_copyUnit
1299 
1300   PURPOSE  : Copy a given unit, according to the copy mode
1301              1. copy unit (with it sites, if available) and input/output links
1302              2. copy unit (with it sites, if available) and input links
1303              3. copy unit (with it sites, if available) and output links
1304              4. copy unit (with it sites, if available) but no input/output link
1305   NOTES    : Function has no effect on the current unit.
1306              Copying of output links is slow.
1307              If return code < 0, an error occured.
1308 
1309   RETURNS  : Returns the unit number of the new unit or error message < 0
1310   UPDATE   :
1311 ******************************************************************************/
1312 int   krui_copyUnit(int unit_no, int copy_mode)
1313 {
1314     int   new_unit_no;
1315 
1316 #ifdef MASPAR_KERNEL
1317     MASPAR_FF1_VALIDATE_OP;
1318 #endif
1319 
1320     new_unit_no = kr_copyUnit( copy_mode, unit_no );
1321     if (KernelErrorCode != KRERR_NO_ERROR)
1322         return( KernelErrorCode );
1323 
1324     return( new_unit_no );
1325 }
1326 
1327 
1328 
1329 /*###########################################################################
1330 
1331 GROUP: Functions for manipulation of the Unit-Functionality-List
1332 REMEMBER: The Unit-Functionality-List stores:
1333             1. unit activation and output functions
1334             2. if sites:  3. all site functions
1335                           4. all site names
1336 
1337 
1338 #############################################################################*/
1339 
1340 /*****************************************************************************
1341   FUNCTION : krui_setFirstFTypeEntry
1342 
1343   PURPOSE  : Initializes the first FType entry.
1344   NOTES    :
1345 
1346   RETURNS  : Returns true, if an entry is available
1347   UPDATE   :
1348 ******************************************************************************/
1349 bool  krui_setFirstFTypeEntry(void)
1350 {
1351     UICurrentFtypeEntry = krm_getFtypeFirstEntry();
1352     UICurrentFtypeSite = NULL;
1353     return( UICurrentFtypeEntry != NULL );
1354 }
1355 
1356 
1357 /*****************************************************************************
1358   FUNCTION : krui_setNextFTypeEntry
1359 
1360   PURPOSE  : Initializes the next FType entry.
1361   NOTES    :
1362 
1363   RETURNS  : Returns true, if an entry is available
1364   UPDATE   :
1365 ******************************************************************************/
1366 bool  krui_setNextFTypeEntry(void)
1367 {
1368     struct  FtypeUnitStruct   *ftype_ptr;
1369 
1370     UICurrentFtypeSite = NULL;
1371     if ( (ftype_ptr = krm_getFtypeNextEntry() ) != NULL)
1372         {
1373             UICurrentFtypeEntry = ftype_ptr;
1374             return( TRUE );
1375         }
1376 
1377     return( FALSE );
1378 }
1379 
1380 
1381 /*****************************************************************************
1382   FUNCTION : krui_setFTypeEntry
1383 
1384   PURPOSE  : Initializes the FType entry with the given name.
1385   NOTES    :
1386 
1387   RETURNS  : Returns true, if an entry with this name is available.
1388   UPDATE   :
1389 ******************************************************************************/
1390 bool  krui_setFTypeEntry(char *Ftype_symbol)
1391 {
1392     struct  FtypeUnitStruct   *ftype_ptr;
1393 
1394     if ( (ftype_ptr = krm_FtypeSymbolSearch( Ftype_symbol ) ) != NULL)
1395         {
1396             UICurrentFtypeEntry = ftype_ptr;
1397             return( TRUE );
1398         }
1399 
1400     return( FALSE );
1401 }
1402 
1403 
1404 /*****************************************************************************
1405   FUNCTION : krui_getFTypeName
1406 
1407   PURPOSE  :
1408   NOTES    : The FType name is definite and will never be
1409              a NULL pointer.
1410 
1411   RETURNS  : Returns the name of the current FType entry.
1412   UPDATE   :
1413 ******************************************************************************/
1414 char  *krui_getFTypeName(void)
1415 {
1416 
1417     if (UICurrentFtypeEntry == NULL)
1418         return( NULL );
1419 
1420     return( UICurrentFtypeEntry->Ftype_symbol->Entry.symbol );
1421 }
1422 
1423 
1424 /*****************************************************************************
1425   FUNCTION : krui_setFTypeName
1426 
1427   PURPOSE  : Sets the name of the current FType entry.
1428   NOTES    : The new FType name have to be definite and must not be
1429              a NULL pointer.
1430 
1431   RETURNS  : Returns error code if memory allocation fails or Ftype name
1432              isn't definite, 0 otherwise.
1433   UPDATE   :
1434 ******************************************************************************/
1435 krui_err  krui_setFTypeName(char *Ftype_symbol)
1436 {
1437     struct NameTable    *NTable_ptr;
1438 
1439     if (UICurrentFtypeEntry == NULL)
1440         return( KRERR_FTYPE_ENTRY ); /*  Current Ftype entry isn't defined   */
1441 
1442     if (Ftype_symbol == NULL)
1443         return( KRERR_FTYPE_NAME ); /*  Ftype name isn't definite   */
1444 
1445     if (!kr_symbolCheck( Ftype_symbol ))
1446         return( KRERR_SYMBOL ); /*  Symbol pattern invalid */
1447 
1448     if (krm_NTableSymbolSearch( Ftype_symbol, FTYPE_UNIT_SYM ) != NULL)
1449         return( KRERR_FTYPE_NAME ); /*  Ftype name isn't definite   */
1450 
1451     if((NTable_ptr=krm_NTableCreateEntry(Ftype_symbol, FTYPE_UNIT_SYM)) == NULL)
1452         return( KRERR_INSUFFICIENT_MEM ); /*  Insufficient memory  */
1453 
1454     krm_NTableReleaseEntry( UICurrentFtypeEntry->Ftype_symbol );
1455 
1456     UICurrentFtypeEntry->Ftype_symbol = NTable_ptr;
1457 
1458     return( KRERR_NO_ERROR );
1459 }
1460 
1461 
1462 /*****************************************************************************
1463   FUNCTION : krui_getFTypeActFuncName
1464 
1465   PURPOSE  :
1466   NOTES    :
1467 
1468   RETURNS  : Returns the name of the activation function in the current
1469              FType entry
1470   UPDATE   :
1471 ******************************************************************************/
1472 char  *krui_getFTypeActFuncName(void)
1473 {
1474     static char  act_func_name[FUNCTION_NAME_MAX_LEN];
1475 
1476     if (UICurrentFtypeEntry == NULL)
1477         return( NULL );
1478 
1479     strcpy( act_func_name,
1480 	    krf_getFuncName( (FunctionPtr) UICurrentFtypeEntry->act_func ) );
1481 
1482     return( act_func_name );
1483 }
1484 
1485 
1486 /*****************************************************************************
1487   FUNCTION : krui_setFTypeActFunc
1488 
1489   PURPOSE  :
1490   NOTES    : All units (in the existing network) of the current Ftype changes
1491              their activation function.
1492 
1493   RETURNS  : Sets the activation function in the current FType entry
1494              returns 0, if the function is a valid activation function,
1495              error code otherwise.
1496   UPDATE   :
1497 ******************************************************************************/
1498 krui_err  krui_setFTypeActFunc(char *act_func_name)
1499 {
1500     FunctionPtr  act_func_ptr, act_deriv_func_ptr, act_2_deriv_func_ptr;
1501 
1502 #ifdef MASPAR_KERNEL
1503     MASPAR_FF1_VALIDATE_OP;
1504 #endif
1505 
1506     KernelErrorCode = KRERR_NO_ERROR;
1507     if (UICurrentFtypeEntry == NULL)
1508         {                       /*  Current Ftype entry isn't defined   */
1509             KernelErrorCode = KRERR_FTYPE_ENTRY;
1510             return( KernelErrorCode );
1511         }
1512 
1513     if ( !krf_funcSearch( act_func_name, ACT_FUNC, &act_func_ptr ) )
1514         return( KernelErrorCode );
1515     /*  set the derivation function of the activation function  */
1516     if ( !krf_funcSearch( act_func_name, ACT_DERIV_FUNC, &act_deriv_func_ptr ))
1517         return( KernelErrorCode );
1518     /*  set the second derivation function of the activation function  */
1519     if ( !krf_funcSearch( act_func_name, ACT_2_DERIV_FUNC,
1520 			  &act_2_deriv_func_ptr ))
1521         return( KernelErrorCode );
1522 
1523     UICurrentFtypeEntry->act_func = (ActFuncPtr) act_func_ptr;
1524     UICurrentFtypeEntry->act_deriv_func = (ActDerivFuncPtr) act_deriv_func_ptr;
1525     UICurrentFtypeEntry->act_2_deriv_func =
1526 	(ActDerivFuncPtr) act_2_deriv_func_ptr;
1527 
1528     kr_changeFtypeUnits( UICurrentFtypeEntry );
1529     return( KernelErrorCode );
1530 }
1531 
1532 
1533 /*****************************************************************************
1534   FUNCTION : krui_getFTypeOutFuncName
1535 
1536   PURPOSE  :
1537   NOTES    :
1538 
1539   RETURNS  : Returns the name of the output function in the current
1540              FType entry
1541   UPDATE   :
1542 ******************************************************************************/
1543 
1544 char  *krui_getFTypeOutFuncName(void)
1545 {
1546     static char  out_func_name[FUNCTION_NAME_MAX_LEN];
1547 
1548     if (UICurrentFtypeEntry == NULL)
1549         return( NULL );
1550 
1551     strcpy( out_func_name,
1552 	    krf_getFuncName( (FunctionPtr) UICurrentFtypeEntry->out_func ) );
1553 
1554     return( out_func_name );
1555 }
1556 
1557 
1558 /*****************************************************************************
1559   FUNCTION : krui_setFTypeOutFunc
1560 
1561   PURPOSE  : Sets the output function in the current FType entry
1562   NOTES    : All units (in the existing network) of the current Ftype changes
1563              their output function.
1564 
1565   RETURNS  : Returns 0, if the function is a valid output function,
1566              error code otherwise.
1567   UPDATE   :
1568 ******************************************************************************/
1569 krui_err   krui_setFTypeOutFunc(char *out_func_name)
1570 {
1571     FunctionPtr  out_func_ptr;
1572 
1573     KernelErrorCode = KRERR_NO_ERROR;
1574     if (UICurrentFtypeEntry == NULL)
1575         {   /*  Current Ftype entry isn't defined   */
1576             KernelErrorCode = KRERR_FTYPE_ENTRY;
1577             return( KernelErrorCode );
1578         }
1579 
1580     if ( !krf_funcSearch( out_func_name, OUT_FUNC, &out_func_ptr ) )
1581         return( KernelErrorCode );
1582 
1583     UICurrentFtypeEntry->out_func = (OutFuncPtr) out_func_ptr;
1584 
1585     kr_changeFtypeUnits( UICurrentFtypeEntry );
1586     return( KernelErrorCode );
1587 }
1588 
1589 
1590 /*****************************************************************************
1591   FUNCTION : krui_setFirstFTypeSite
1592 
1593   PURPOSE  : Initializes the first site of the current FType.
1594   NOTES    :
1595 
1596   RETURNS  : Returns FALSE, if no sites are available in the current
1597              FType entry.
1598   UPDATE   :
1599 ******************************************************************************/
1600 bool  krui_setFirstFTypeSite(void)
1601 {
1602 
1603     if (UICurrentFtypeEntry == NULL)  {
1604         UICurrentFtypeSite = NULL;
1605         return( FALSE );
1606     }
1607 
1608     if (UICurrentFtypeEntry->sites == NULL)  {
1609         UICurrentFtypeSite = NULL;
1610         return( FALSE );
1611     } else {
1612         UICurrentFtypeSite = UICurrentFtypeEntry->sites;
1613         return( TRUE );
1614     }
1615 }
1616 
1617 
1618 /*****************************************************************************
1619   FUNCTION : krui_setNextFTypeSite
1620 
1621   PURPOSE  : Initializes the next FType site.
1622   NOTES    :
1623 
1624   RETURNS  : Returns FALSE, if no more sites are available in the current
1625              FType entry.
1626   UPDATE   :
1627 ******************************************************************************/
1628 bool  krui_setNextFTypeSite(void)
1629 {
1630 
1631     if (UICurrentFtypeSite == NULL)
1632         return( FALSE );
1633 
1634     if (UICurrentFtypeSite->next == NULL)
1635         return( FALSE );
1636 
1637     UICurrentFtypeSite = UICurrentFtypeSite->next;
1638     return( TRUE );
1639 }
1640 
1641 
1642 /*****************************************************************************
1643   FUNCTION : krui_getFTypeSiteName
1644 
1645   PURPOSE  :
1646   NOTES    :
1647 
1648   RETURNS  : Returns the name of the current FType site (in the current
1649              Ftype entry).
1650   UPDATE   :
1651 ******************************************************************************/
1652 char  *krui_getFTypeSiteName(void)
1653 {
1654 
1655     if (UICurrentFtypeSite == NULL)
1656         return( NULL );
1657 
1658     return( ((UICurrentFtypeSite->site_table)->Entry.site_name)->Entry.symbol );
1659 }
1660 
1661 
1662 /*****************************************************************************
1663   FUNCTION : krui_setFTypeSiteName
1664 
1665   PURPOSE  : Sets the name and function of the current FType site (in the
1666              current FType entry).
1667              All sites (in the existing network) of the current Ftype and the
1668              same (old) name changes their names and site functions.
1669 
1670   NOTES    :
1671 
1672   RETURNS  : Returns an error code if
1673              - current Ftype site isn't defined
1674              - site name does not exist in the site name table
1675              0 otherwise.
1676   UPDATE   :
1677 ******************************************************************************/
1678 krui_err  krui_setFTypeSiteName(char *FType_site_name)
1679 {
1680     struct  SiteTable     *stbl_ptr;
1681 
1682 #ifdef MASPAR_KERNEL
1683     MASPAR_FF1_VALIDATE_OP;
1684 #endif
1685 
1686     KernelErrorCode = KRERR_NO_ERROR;
1687     if (UICurrentFtypeEntry == NULL)
1688         {                       /*  Current Ftype entry isn't defined   */
1689             KernelErrorCode = KRERR_FTYPE_ENTRY;
1690             return( KernelErrorCode );
1691         }
1692 
1693     if (!kr_symbolCheck( FType_site_name ))
1694         return( KernelErrorCode );
1695 
1696     if ( (stbl_ptr = krm_STableSymbolSearch( FType_site_name )) == NULL)
1697         {                       /*   site name isn't defined */
1698             KernelErrorCode = KRERR_UNDEF_SITE_NAME;
1699             return( KernelErrorCode );
1700         }
1701 
1702     kr_changeFtypeSites( UICurrentFtypeEntry, UICurrentFtypeSite->site_table,
1703 			 stbl_ptr);
1704     UICurrentFtypeSite->site_table = stbl_ptr;
1705 
1706     return( KernelErrorCode );
1707 }
1708 
1709 
1710 /*****************************************************************************
1711   FUNCTION : krui_createFTypeEntry
1712 
1713   PURPOSE  : Create a new functionality type, needs a definite FType symbol,
1714              the unit output and activation function
1715              and the number of sites provided for this unit FType.
1716              An additional array with N elements of pointers to site names
1717              is required for the definition of the sites.
1718   NOTES    : The number of Ftype entries and the number of sites per Ftype is
1719              only limited by the size of system memory.
1720 
1721   RETURNS  : Returns error code if:
1722              - memory allocation fails
1723              - FType name isn't definite (symbol is used for another FType
1724                or symbol is a NULL pointer)
1725              - one or more site names are undefined
1726 
1727              0 otherwise.
1728   UPDATE   :
1729 ******************************************************************************/
1730 krui_err  krui_createFTypeEntry(char *Ftype_symbol, char *act_func_name,
1731 				char *out_func_name, int no_of_sites,
1732 				char **array_of_site_names)
1733 {
1734     FunctionPtr act_func, out_func, act_deriv_func, act_2_deriv_func;
1735     struct  FtypeUnitStruct   *Ftype_entry;
1736     struct  SiteTable         *STable_entry;
1737     int       i;
1738     char      *Ftype_site_name;
1739 
1740 
1741     KernelErrorCode = KRERR_NO_ERROR;
1742 
1743     if (Ftype_symbol == NULL)
1744     {   /*  Ftype name isn't defined   */
1745         KernelErrorCode = KRERR_FTYPE_NAME;
1746         return( KernelErrorCode );
1747     }
1748 
1749     if (!kr_symbolCheck( Ftype_symbol ))
1750         return( KernelErrorCode );
1751     if (krm_NTableSymbolSearch( Ftype_symbol, FTYPE_UNIT_SYM ) != NULL)
1752         return( KernelErrorCode );
1753     if ( !krf_funcSearch( out_func_name, OUT_FUNC, &out_func ) )
1754         return( KernelErrorCode );
1755     if ( !krf_funcSearch( act_func_name, ACT_FUNC, &act_func ) )
1756         return( KernelErrorCode );
1757     /*  set the derivation function of the activation function  */
1758     if ( !krf_funcSearch( act_func_name, ACT_DERIV_FUNC, &act_deriv_func ))
1759         return( KernelErrorCode );
1760     /*  set the second derivation function of the activation function  */
1761     if ( !krf_funcSearch( act_func_name, ACT_2_DERIV_FUNC, &act_2_deriv_func ))
1762 	return( KernelErrorCode );
1763 
1764     if ((Ftype_entry = krm_FtypeCreateEntry( Ftype_symbol
1765                                             ,(OutFuncPtr) out_func
1766                                             ,(ActFuncPtr) act_func
1767                                             ,(ActDerivFuncPtr) act_deriv_func
1768                                             ,(ActDerivFuncPtr) act_2_deriv_func
1769 					    ,kr_findPythonFunction(out_func_name,OUT_FUNC)
1770 					    ,kr_findPythonFunction(act_func_name, ACT_FUNC)
1771 					    ,kr_findPythonFunction(act_func_name,ACT_DERIV_FUNC)
1772 					    ,kr_findPythonFunction(act_func_name,ACT_2_DERIV_FUNC)
1773                                             )) == NULL)
1774         return( KernelErrorCode );
1775 
1776     /*  create sites at the Ftype  */
1777     for (i = 0; i < no_of_sites; i++)  {
1778         if ( (Ftype_site_name = array_of_site_names[ i ]) == NULL){
1779 	    /*   site name isn't defined because it is a NULL pointer  */
1780 	    KernelErrorCode = KRERR_UNDEF_SITE_NAME;
1781 	    return( KernelErrorCode );
1782 	}
1783 
1784         if ((STable_entry = krm_STableSymbolSearch( Ftype_site_name )) == NULL){
1785 	    /*  site isn't defined  */
1786 	    krm_releaseFtypeEntry( Ftype_entry );
1787 	    KernelErrorCode = KRERR_UNDEF_SITE_NAME;
1788 	    return( KernelErrorCode );
1789 	}
1790 
1791         if (krm_FtypeAddSite( Ftype_entry , STable_entry ) == NULL){
1792 	    /*  memory alloc failed */
1793 	    krm_releaseFtypeEntry( Ftype_entry );
1794 	    return( KernelErrorCode );
1795 	}
1796     }
1797 
1798     return( KernelErrorCode );
1799 }
1800 
1801 
1802 /*****************************************************************************
1803   FUNCTION : krui_deleteFTypeEntry
1804 
1805   PURPOSE  : Deletes the specified FType entry. If there exists units in the
1806              network with this FType, all these units will lost their FType
1807              but the functionality of the units will not be changed.
1808   NOTES    :
1809 
1810   RETURNS  : Returns error code if FType symbol dosn't exist, 0 otherwise.
1811   UPDATE   :
1812 ******************************************************************************/
1813 krui_err    krui_deleteFTypeEntry(char *Ftype_symbol)
1814 {
1815     struct  FtypeUnitStruct   *ftype_ptr;
1816 
1817     if ( (ftype_ptr = krm_FtypeSymbolSearch( Ftype_symbol ) ) == NULL)
1818         return( KRERR_FTYPE_SYMBOL ); /*  FType symbol isn't defined  */
1819 
1820     kr_deleteUnitsFtype( ftype_ptr );
1821     krm_releaseFtypeEntry( ftype_ptr );
1822     return( KRERR_NO_ERROR );
1823 }
1824 
1825 
1826 
1827 /*############################################################################
1828 
1829 GROUP: Functions for reading of the function table
1830 
1831 ############################################################################*/
1832 
1833 
1834 /*****************************************************************************
1835   FUNCTION : krui_getNoOfFunctions
1836 
1837   PURPOSE  :
1838   NOTES    :
1839 
1840   RETURNS  : Returns the number of available functions
1841   UPDATE   :
1842 ******************************************************************************/
1843 int  krui_getNoOfFunctions(void)
1844 {
1845     return( krf_getNoOfFuncs() );
1846 }
1847 
1848 
1849 /*****************************************************************************
1850   FUNCTION : krui_getFuncInfo
1851 
1852   PURPOSE  :
1853   NOTES    :
1854 
1855   RETURNS  : Returns the name of the function and the function type (Output,
1856              Activation, Site).
1857   UPDATE   :
1858 ******************************************************************************/
1859 void  krui_getFuncInfo(int func_no, char **func_name, int *func_type)
1860 {
1861     static struct FuncInfoDescriptor  functionDescr;
1862     functionDescr.number = func_no - 1;
1863     KernelErrorCode = krf_getFuncInfo( GET_FUNC_INFO, &functionDescr );
1864 
1865     *func_type = functionDescr.func_type;
1866     *func_name = functionDescr.func_name;
1867 }
1868 
1869 
1870 /*****************************************************************************
1871   FUNCTION : krui_isFunction
1872 
1873   PURPOSE  :
1874   NOTES    :
1875 
1876   RETURNS  : Returns true if the given function name and type exists.
1877   UPDATE   :
1878 ******************************************************************************/
1879 bool  krui_isFunction(char *func_name, int func_type)
1880 {
1881     FunctionPtr  dummy_func_ptr;
1882     bool        is_func;
1883 
1884     is_func = krf_funcSearch( func_name, func_type, &dummy_func_ptr );
1885     KernelErrorCode = KRERR_NO_ERROR;
1886     return( is_func );
1887 }
1888 
1889 
1890 /*****************************************************************************
1891   FUNCTION : krui_getFuncParamInfo
1892 
1893   PURPOSE  : Returns the no. of input and output parameters of the given
1894              function (only relevant for learning, update and initialisation
1895              functions).
1896   NOTES    :
1897 
1898   RETURNS  : Returns TRUE if the given function exists, FALSE otherwise.
1899   UPDATE   :
1900 ******************************************************************************/
1901 bool  krui_getFuncParamInfo(char *func_name, int func_type,
1902 			    int *no_of_input_params, int *no_of_output_params)
1903 {
1904     static struct FuncInfoDescriptor  functionDescr;
1905 
1906     functionDescr.func_type = func_type;
1907     strcpy( functionDescr.func_name, func_name );
1908 
1909     KernelErrorCode = krf_getFuncInfo( SEARCH_FUNC, &functionDescr );
1910 
1911     if (KernelErrorCode != KRERR_NO_ERROR)  return( FALSE );
1912 
1913     *no_of_input_params = functionDescr.no_of_input_parameters;
1914     *no_of_output_params = functionDescr.no_of_output_parameters;
1915     return( TRUE );
1916 }
1917 
1918 
1919 
1920 /*############################################################################
1921 
1922 GROUP: Site Table Functions
1923 
1924 #############################################################################*/
1925 
1926 
1927 /*****************************************************************************
1928   FUNCTION : krui_getFirstSiteTableEntry
1929 
1930   PURPOSE  :
1931   NOTES    :
1932 
1933   RETURNS  : Returns the first site name/function pair in the site table.
1934              Returns FALSE and NULL, if not available.
1935   UPDATE   :
1936 ******************************************************************************/
1937 bool   krui_getFirstSiteTableEntry(char **site_name, char **site_func)
1938 {
1939     struct  SiteTable   *s_ptr;
1940 
1941     if ( (s_ptr = krm_getSTableFirstEntry() ) == NULL) {
1942 	*site_name = NULL;
1943 	*site_func = NULL;
1944 	return( FALSE );
1945     } else {
1946 	*site_name = (s_ptr->Entry.site_name)->Entry.symbol;
1947 	*site_func = krf_getFuncName( (FunctionPtr) s_ptr->site_func );
1948 	return( TRUE );
1949     }
1950 }
1951 
1952 
1953 /*****************************************************************************
1954   FUNCTION : krui_getNextSiteTableEntry
1955 
1956   PURPOSE  :
1957   NOTES    :
1958 
1959   RETURNS  : Returns the next site name/function pair in the site table.
1960              Returns FALSE and NULL, if not available.
1961   UPDATE   :
1962 ******************************************************************************/
1963 bool  krui_getNextSiteTableEntry(char **site_name, char **site_func)
1964 {
1965     struct  SiteTable   *s_ptr;
1966 
1967     if ( (s_ptr = krm_getSTableNextEntry() ) == NULL) {
1968 	*site_name = NULL;
1969 	*site_func = NULL;
1970 	return( FALSE );
1971     } else {
1972 	*site_name = (s_ptr->Entry.site_name)->Entry.symbol;
1973 	*site_func = krf_getFuncName( (FunctionPtr) s_ptr->site_func );
1974 	return( TRUE );
1975     }
1976 }
1977 
1978 
1979 /*****************************************************************************
1980   FUNCTION : krui_getSiteTableFuncName
1981 
1982   PURPOSE  :
1983   NOTES    :
1984 
1985   RETURNS  : Returns the name of the site function that is associated with
1986              the site name.
1987              If the site name do not exist, function returns NULL.
1988   UPDATE   :
1989 ******************************************************************************/
1990 char  *krui_getSiteTableFuncName(char *site_name)
1991 {
1992     struct SiteTable  *s_ptr;
1993 
1994     if ( (s_ptr = krm_STableSymbolSearch( site_name )) == NULL)
1995         return( NULL );
1996 
1997     return( krf_getFuncName( (FunctionPtr) s_ptr->site_func ) );
1998 }
1999 
2000 
2001 /*****************************************************************************
2002   FUNCTION : krui_createSiteTableEntry
2003 
2004   PURPOSE  : Creates a new site name and associate this name with a site
2005              function.
2006   NOTES    :
2007 
2008   RETURNS  : Returns error code if:
2009              - site name already exists or
2010              - site function is invalid or
2011              - memory allocation has failed
2012             0 otherwise.
2013   UPDATE   :
2014 ******************************************************************************/
2015 krui_err  krui_createSiteTableEntry(char *site_name, char *site_func)
2016 {
2017     FunctionPtr   func_ptr;
2018 
2019     KernelErrorCode = KRERR_NO_ERROR;
2020     if ( !krf_funcSearch( site_func, SITE_FUNC, &func_ptr ) )
2021         return( KernelErrorCode );
2022     if (!kr_symbolCheck( site_name ))
2023         return( KernelErrorCode );
2024     if (krm_STableSymbolSearch( site_name ) != NULL) {
2025 	/*  symbol is already in the site table */
2026 	KernelErrorCode = KRERR_REDEF_SITE_NAME;
2027 	return( KernelErrorCode );
2028     }
2029 
2030     (void) krm_STableCreateEntry( site_name, (SiteFuncPtr) func_ptr );
2031 
2032     return( KernelErrorCode );
2033 }
2034 
2035 
2036 /*****************************************************************************
2037   FUNCTION : krui_changeSiteTableEntry
2038 
2039   PURPOSE  : Changes the site function of a previously defined site name.
2040   NOTES    : All sites in the network with the name <old_site_name>
2041              changes their names and functions.
2042 
2043   RETURNS  : Returns error code if <old_site_name> or <new_site_func>
2044              isn't defined, 0 otherwise.
2045   UPDATE   :
2046 ******************************************************************************/
2047 krui_err  krui_changeSiteTableEntry(char *old_site_name, char *new_site_name,
2048 				    char *new_site_func)
2049 {
2050     FunctionPtr   func_ptr;
2051     SiteFuncPtr     site_func_ptr;
2052     struct SiteTable  *stbl_ptr1,
2053     *stbl_ptr2;
2054 
2055 #ifdef MASPAR_KERNEL
2056     MASPAR_FF1_VALIDATE_OP;
2057 #endif
2058 
2059     KernelErrorCode = KRERR_NO_ERROR;
2060     if (!kr_symbolCheck( new_site_name ))
2061         return( KernelErrorCode );
2062     if ( !krf_funcSearch( new_site_func, SITE_FUNC, &func_ptr ) )
2063         return( KernelErrorCode );
2064 
2065     site_func_ptr = (SiteFuncPtr) func_ptr;
2066 
2067     if ( (stbl_ptr1 = krm_STableSymbolSearch( old_site_name )) == NULL) {
2068         /*  old site name isn't defined */
2069         KernelErrorCode = KRERR_UNDEF_SITE_NAME;
2070         return( KernelErrorCode );
2071     }
2072 
2073     stbl_ptr2 = krm_STableSymbolSearch( new_site_name );
2074     if ( (stbl_ptr2 != NULL) && (stbl_ptr2 != stbl_ptr1) ){
2075         /*  new symbol is already in the site table (and new_site_name and
2076             old_site_name are not identical) */
2077         KernelErrorCode = KRERR_REDEF_SITE_NAME;
2078         return( KernelErrorCode );
2079     }
2080 
2081     (void) krm_STableChangeEntry( stbl_ptr1 , new_site_name , site_func_ptr );
2082     return( KernelErrorCode );
2083 }
2084 
2085 
2086 /*****************************************************************************
2087   FUNCTION : krui_deleteSiteTableEntry
2088 
2089   PURPOSE  : Removes the current site name entry from the site table.
2090   NOTES    :
2091 
2092   RETURNS  : Returns an error code if
2093              - there exists sites with the given name in the network or
2094              - <site_name> isn't defined
2095              0 otherwise.
2096   UPDATE   :
2097 ******************************************************************************/
2098 krui_err  krui_deleteSiteTableEntry(char *site_name)
2099 {
2100     struct SiteTable    *st_ptr;
2101 
2102     if ((st_ptr = krm_STableSymbolSearch( site_name )) == NULL)
2103         return( KRERR_UNDEF_SITE_NAME ); /*  Site name isn't defined */
2104 
2105     if (kr_searchNetSite( st_ptr ) != 0)
2106         return( KRERR_INUSE_SITE ); /* Site is in use and must not be deleted */
2107 
2108     krm_STableRemoveEntry( st_ptr );
2109     return( KRERR_NO_ERROR );
2110 }
2111 
2112 
2113 /*############################################################################
2114 
2115 GROUP: Site Functions
2116 
2117 ############################################################################*/
2118 
2119 
2120 /*****************************************************************************
2121   FUNCTION : krui_setFirstSite
2122 
2123   PURPOSE  : Initializes the first site at the current unit.
2124   NOTES    :
2125 
2126   RETURNS  : Returns false if no site available or if no sites permitted at
2127              this unit.
2128   UPDATE   :
2129 ******************************************************************************/
2130 bool  krui_setFirstSite(void)
2131 {
2132     if KERNEL_STANDARD
2133         return( kr_setSite( FIRST, NULL ) );
2134 
2135     KernelErrorCode = KRERR_SITES_NO_SUPPORT;
2136     return( FALSE );
2137 }
2138 
2139 
2140 /*****************************************************************************
2141   FUNCTION : krui_setNextSite
2142 
2143   PURPOSE  : Initializes the next site at the current unit.
2144   NOTES    :
2145 
2146   RETURNS  : Returns false if no more sites available.
2147   UPDATE   :
2148 ******************************************************************************/
2149 bool  krui_setNextSite(void)
2150 {
2151     if KERNEL_STANDARD
2152         return( kr_setSite( NEXT, NULL ) );
2153 
2154     KernelErrorCode = KRERR_SITES_NO_SUPPORT;
2155     return( FALSE );
2156 }
2157 
2158 
2159 /*****************************************************************************
2160   FUNCTION : krui_setSite
2161 
2162   PURPOSE  : Initializes the given site at the current unit.
2163   NOTES    :
2164 
2165   RETURNS  : Returns error code if
2166              - unit dosn't exist
2167              - site name doesn't exist
2168              - unit don't has sites
2169              - unit don't has a site with this name
2170              0 otherwise.
2171   UPDATE   :
2172 ******************************************************************************/
2173 krui_err  krui_setSite(char *site_name)
2174 {
2175 
2176     if KERNEL_STANDARD
2177         return( kr_setSite( NAME, site_name ) );
2178 
2179     KernelErrorCode = KRERR_SITES_NO_SUPPORT;
2180     return( KernelErrorCode );
2181 }
2182 
2183 
2184 /*****************************************************************************
2185   FUNCTION : krui_getSiteValue
2186 
2187   PURPOSE  :
2188   NOTES    :
2189 
2190   RETURNS  : Returns the actual value of the current site
2191   UPDATE   :
2192 ******************************************************************************/
2193 FlintType   krui_getSiteValue(void)
2194 {
2195 
2196     if KERNEL_STANDARD  {
2197         if (sitePtr == NULL)
2198             KernelErrorCode = KRERR_NO_SITES;
2199         else
2200             return( (*sitePtr->site_table->site_func) (sitePtr) );
2201     }else
2202         KernelErrorCode = KRERR_SITES_NO_SUPPORT;
2203 
2204     return( (FlintType) 0 );
2205 }
2206 
2207 
2208 /*****************************************************************************
2209   FUNCTION : krui_getSiteName
2210 
2211   PURPOSE  :
2212   NOTES    :
2213 
2214   RETURNS  : returns the name of the current unit/site,
2215              NULL if not available.
2216   UPDATE   :
2217 ******************************************************************************/
2218 char  *krui_getSiteName(void)
2219 {
2220 
2221     if KERNEL_STANDARD    {
2222         if (sitePtr == NULL)
2223             KernelErrorCode = KRERR_NO_SITES;
2224         else
2225             return( ((sitePtr->site_table)->Entry.site_name)->Entry.symbol );
2226     }else
2227         KernelErrorCode = KRERR_SITES_NO_SUPPORT;
2228 
2229     return( NULL );
2230 }
2231 
2232 
2233 /*****************************************************************************
2234   FUNCTION : krui_setSiteName
2235 
2236   PURPOSE  : Sets the name/function of the current unit/site.
2237              Current Unit will loose the functionality type.
2238   NOTES    :
2239 
2240   RETURNS  : Returns error code if site name isn't defined.
2241   UPDATE   :
2242 ******************************************************************************/
2243 krui_err  krui_setSiteName(char *site_name)
2244 {
2245     struct  SiteTable     *stbl_ptr;
2246 
2247 #ifdef MASPAR_KERNEL
2248     MASPAR_FF1_VALIDATE_OP;
2249 #endif
2250 
2251     if (sitePtr == NULL) {
2252 	KernelErrorCode = KRERR_FTYPE_SITE;
2253 	return( KernelErrorCode );
2254     }
2255 
2256     if (!kr_symbolCheck( site_name ))
2257         return( KernelErrorCode );
2258     if ((stbl_ptr = krm_STableSymbolSearch( site_name )) == NULL){
2259 	/*   site name isn't defined */
2260 	KernelErrorCode = KRERR_UNDEF_SITE_NAME;
2261 	return( KernelErrorCode );
2262     }
2263 
2264     KernelErrorCode = KRERR_NO_ERROR;
2265     unitPtr->Ftype_entry = NULL;
2266     sitePtr->site_table  = stbl_ptr;
2267 
2268     NetModified = TRUE;
2269 
2270     return( KRERR_NO_ERROR );
2271 }
2272 
2273 
2274 /*****************************************************************************
2275   FUNCTION : krui_getSiteFuncName
2276 
2277   PURPOSE  :
2278   NOTES    :
2279 
2280   RETURNS  : Returns the name of the current unit/site function
2281   UPDATE   :
2282 ******************************************************************************/
2283 char  *krui_getSiteFuncName(void)
2284 {
2285     static char  site_func_name[FUNCTION_NAME_MAX_LEN];
2286 
2287     if (sitePtr == NULL){
2288         KernelErrorCode = KRERR_FTYPE_SITE;
2289         return( NULL );
2290     }
2291 
2292     strcpy( site_func_name,
2293 	    krf_getFuncName( (FunctionPtr) sitePtr->site_table->site_func ) );
2294 
2295     return( site_func_name );
2296 }
2297 
2298 
2299 /*****************************************************************************
2300   FUNCTION : krui_addSite
2301 
2302   PURPOSE  : Adds a site at the current unit. If the unit has already sites,
2303              this new site will be inserted above all other sites, i.e. the
2304 	     new created site will be the first site at this unit.
2305              If the unit has direct input links, i.e the unit has input links
2306              but no sites, the creation of sites is not permitted
2307 	     (krui_addSite will return an error code).
2308              If there exists already a site with the given name, the creation
2309 	     of the new site is prohibited and krui_addSite returns an error
2310 	     code.
2311              krui_addSite has no effect on the current site. To change the
2312 	     current site to this new site, call krui_setFirstSite().
2313              The unit's FType will be deleted.
2314   NOTES    : The number of sites per unit is nearly unlimited (2^32).
2315 
2316   RETURNS  : Returns error code if
2317              - memory allocation fails or
2318              - unit has direct input links or
2319              - site name isn't defined or
2320              - site with the given name exists already at this unit
2321              0 otherwise.
2322   UPDATE   :
2323 ******************************************************************************/
2324 krui_err  krui_addSite(char *site_name)
2325 {
2326     FlagWord    flags;
2327     struct Site       *site_ptr,
2328     *site_ptr1;
2329     struct SiteTable  *stbl_ptr;
2330 
2331 #ifdef MASPAR_KERNEL
2332     MASPAR_FF1_VALIDATE_OP;
2333 #endif
2334 
2335     KernelErrorCode = KRERR_NO_ERROR;
2336     if ( (stbl_ptr = krm_STableSymbolSearch( site_name )) == NULL)
2337         {                       /*  site name isn't defined */
2338             KernelErrorCode = KRERR_UNDEF_SITE_NAME;
2339             return( KernelErrorCode );
2340         }
2341 
2342     flags = unitPtr->flags & UFLAG_INPUT_PAT;
2343 
2344     switch (flags){
2345     case UFLAG_NO_INP :
2346 	/*  Unit has no inputs  */
2347 	if ((site_ptr = kr_createDefaultSite() ) == NULL)
2348 	    return( KernelErrorCode );
2349 
2350 	unitPtr->sites = site_ptr; /*  Connect site    */
2351 	unitPtr->flags |= UFLAG_SITES; /*  Set site flag   */
2352 	unitPtr->Ftype_entry = NULL; /*  Delete Ftype    */
2353 
2354 	break;
2355 
2356     case UFLAG_SITES :
2357 	/*  Unit has already sites  */
2358 	if (kr_searchUnitSite( unitPtr, stbl_ptr ) != NULL){
2359 	    /* there exists already a site with this name at this unit */
2360 	    KernelErrorCode = KRERR_DUPLICATED_SITE;
2361 	    return( KernelErrorCode );
2362 	}
2363 
2364 	if ( (site_ptr = kr_createDefaultSite() ) == NULL)
2365 	    return( KernelErrorCode );
2366 
2367 	site_ptr1 = unitPtr->sites;
2368 	unitPtr->sites = site_ptr; /*  Connect site    */
2369 	site_ptr->next = site_ptr1;
2370 	unitPtr->Ftype_entry = NULL; /*  Delete Ftype    */
2371 
2372 	break;
2373 
2374     case UFLAG_DLINKS :
2375 	/*  Unit has direct input links and can't have sites */
2376 	KernelErrorCode = KRERR_CREATE_SITE;
2377 	return( KernelErrorCode );
2378 
2379     default :
2380 	KernelErrorCode = KRERR_CREATE_SITE;
2381 	return( KernelErrorCode );
2382     }
2383 
2384     site_ptr->site_table = stbl_ptr;
2385 
2386     NetModified = TRUE;
2387     return( KernelErrorCode );
2388 }
2389 
2390 
2391 /*****************************************************************************
2392   FUNCTION : krui_deleteSite
2393 
2394   PURPOSE  : Removes the current site at the current unit and removes all
2395              links from predecessor units to this site.
2396              krui_setFirstSite (krui_setNextSite) must be called at least once
2397              before using this function.
2398              The current site will be set to the next available site, if no more
2399              sites available, krui_deleteSite returns 0 otherwise 1.
2400              Returns an error code if ther was a problem.
2401              The unit's FType will be set to 0, i.e. the unit's functionality
2402              type will be deleted.
2403 
2404   NOTES    : To delete all sites at a unit:
2405                if ( krui_setFirstSite() )
2406                    while ( krui_deleteSite() > 0) { }
2407 
2408   RETURNS  :
2409   UPDATE   :
2410 ******************************************************************************/
2411 bool  krui_deleteSite(void)
2412 {
2413     struct Site   *next_site_ptr;
2414     struct Unit   *unit_ptr;
2415 
2416 #ifdef MASPAR_KERNEL
2417     MASPAR_FF1_VALIDATE_OP;
2418 #endif
2419 
2420     unit_ptr = unitPtr;
2421 
2422     if ( UNIT_HAS_SITES( unit_ptr ) && (unit_ptr->sites != NULL) &&
2423 	 (sitePtr != NULL) ){
2424 	/*  Unit has sites  */
2425 	NetModified = TRUE;
2426 
2427 	next_site_ptr = sitePtr->next;
2428 
2429 	krm_releaseAllLinks( sitePtr->links ); /*   Remove links    */
2430 	krm_releaseSite( sitePtr ); /*      Remove site     */
2431 
2432 	if (prevSitePtr == NULL){
2433 	    /*  This site is the first site at the current unit */
2434 
2435 	    if (next_site_ptr == NULL){
2436 		/*  Unit has only this site */
2437 		unit_ptr->sites = NULL; /*  Clear site pointer  */
2438 		unit_ptr->flags &= (~UFLAG_INPUT_PAT); /* Clear input flags */
2439 		sitePtr     = NULL; /*  No more sites available  */
2440 		prevSitePtr = NULL;
2441 	    } else {
2442 		/*  It is the first site at the unit but not the only one   */
2443 		unit_ptr->sites  = next_site_ptr; /*  Connect the other sites */
2444 		sitePtr = next_site_ptr;
2445 	    }
2446 	} else {
2447 	    /*  This is not the first site at the unit  */
2448 	    prevSitePtr->next = next_site_ptr; /*  Connect the previous site
2449 						   with the next site  */
2450 	    sitePtr = next_site_ptr;
2451 	}
2452 
2453 	unit_ptr->Ftype_entry = NULL; /*  Delete unit's Ftype */
2454     }
2455 
2456     if (sitePtr != NULL)
2457         return( TRUE );         /*  Returns TRUE if more sites available  */
2458     else
2459         return( FALSE );
2460 }
2461 
2462 
2463 /*############################################################################
2464 
2465 GROUP: Link Functions
2466 
2467 ############################################################################*/
2468 
2469 
2470 /*****************************************************************************
2471   FUNCTION : krui_getFirstPredUnit
2472 
2473   PURPOSE  :
2474   NOTES    : If a predecessor unit exists, the current link is set to the link
2475              between the two units.
2476 
2477   RETURNS  : Returns the no. of first predecessor unit of the current unit/site
2478              and the connection strenght.
2479              Returns 0 if no predecessor unit available, i.e. if the current
2480 	     unit and/or site has no inputs.
2481   UPDATE   :
2482 ******************************************************************************/
2483 int  krui_getFirstPredUnit(FlintType *strength)
2484 {
2485   float dummy1,dummy2,dummy3;
2486 
2487 
2488     if KERNEL_STANDARD  {
2489         return(kr_getPredecessorUnit(FIRST, strength ,&dummy1,&dummy2,&dummy3));
2490     } else {
2491 
2492 #ifdef MASPAR_KERNEL
2493         return( krff_getPredecessorUnit( FIRST, strength ) );
2494 #else
2495         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2496         return( KernelErrorCode );
2497 #endif
2498 
2499     }
2500 }
2501 
2502 
2503 /*****************************************************************************
2504   FUNCTION : krui_getFirstPredUnitAndData
2505 
2506   PURPOSE  :
2507   NOTES    : If a predecessor unit exists, the current link is set to the link
2508              between the two units.
2509 
2510   RETURNS  : Returns the no. of first predecessor unit of the current unit/site
2511              and the connection strenght.
2512              Returns 0 if no predecessor unit available, i.e. if the current
2513 	     unit and/or site has no inputs.
2514   UPDATE   :
2515 ******************************************************************************/
2516 int  krui_getFirstPredUnitAndData(FlintType *strength,float *val_a,
2517 				  float *val_b, float *val_c)
2518 {
2519     if KERNEL_STANDARD  {
2520         return( kr_getPredecessorUnit( FIRST, strength ,val_a ,val_b ,val_c ) );
2521     } else {
2522 
2523 #ifdef MASPAR_KERNEL
2524         return( krff_getPredecessorUnit( FIRST, strength ) );
2525 #else
2526         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2527         return( KernelErrorCode );
2528 #endif
2529 
2530     }
2531 }
2532 
2533 
2534 /*****************************************************************************
2535   FUNCTION : krui_getNextPredUnit
2536 
2537   PURPOSE  : Returns the number of the next logical predecessor unit in a TDNN
2538   NOTES    : If another predecessor unit exists, the current link is set to
2539              the link between the two units.
2540 
2541 
2542   RETURNS  : Returns the no. of the next predecessor unit of the current
2543              unit/site and the connection strenght.
2544              Returns 0 if no more predecessor units exists.
2545   UPDATE   :
2546 ******************************************************************************/
2547 int  krui_getNextPredUnit(FlintType *strength)
2548 {
2549     float dummy1,dummy2,dummy3;
2550 
2551     if KERNEL_STANDARD  {
2552         return(kr_getPredecessorUnit(NEXT, strength ,&dummy1,&dummy2,&dummy3));
2553     } else {
2554 
2555 #ifdef MASPAR_KERNEL
2556         return( krff_getPredecessorUnit( NEXT, strength ) );
2557 #else
2558         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2559         return( KernelErrorCode );
2560 #endif
2561 
2562     }
2563 }
2564 
2565 
2566 /*****************************************************************************
2567   FUNCTION : krui_getNextPredUnitAndData
2568 
2569   PURPOSE  : Returns the number of the next logical predecessor unit in a TDNN
2570   NOTES    : If another predecessor unit exists, the current link is set to
2571              the link between the two units.
2572 
2573 
2574   RETURNS  : Returns the no. of the next predecessor unit of the current
2575              unit/site and the connection strenght.
2576              Returns 0 if no more predecessor units exists.
2577   UPDATE   :
2578 ******************************************************************************/
2579 int  krui_getNextPredUnitAndData(FlintType *strength,float *val_a,
2580 				 float *val_b, float *val_c)
2581 {
2582 
2583     if KERNEL_STANDARD  {
2584         return(kr_getPredecessorUnit( NEXT, strength, val_a, val_b, val_c ) );
2585     } else {
2586 
2587 #ifdef MASPAR_KERNEL
2588         return( krff_getPredecessorUnit( NEXT, strength ) );
2589 #else
2590         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2591         return( KernelErrorCode );
2592 #endif
2593 
2594     }
2595 }
2596 
2597 
2598 /*****************************************************************************
2599   FUNCTION : krui_getCurrentPredUnit
2600 
2601   PURPOSE  :
2602   NOTES    :
2603 
2604   RETURNS  : Returns the no. of the current predecessor unit (of the current
2605              unit/site) and the connection strenght.
2606              Returns 0 if no predecessor unit available, i.e. if the current
2607 	     unit and/or site has no inputs
2608   UPDATE   :
2609 ******************************************************************************/
2610 int  krui_getCurrentPredUnit(FlintType *strength)
2611 {
2612     float dummy1,dummy2,dummy3;
2613 
2614     if KERNEL_STANDARD  {
2615         return(kr_getPredecessorUnit(CURRENT, strength, &dummy1, &dummy2,
2616 				     &dummy3 ) );
2617     } else {
2618 
2619 #ifdef MASPAR_KERNEL
2620         return( krff_getPredecessorUnit( CURRENT, strength ) );
2621 #else
2622         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2623         return( KernelErrorCode );
2624 #endif
2625 
2626     }
2627 }
2628 
2629 
2630 /*****************************************************************************
2631   FUNCTION : krui_getFirstSuccUnit
2632 
2633   PURPOSE  :
2634   NOTES    : This function is slow (Units are backward chained only).
2635   IMPORTANT: If a successor unit exists, the current unit and site will be
2636              set to this successor unit and the attached site.
2637 
2638   RETURNS  : Returns the no. of the first successor unit of the unit
2639              <source_unit_no> and the connection strenght.
2640              Returns (negative) error code if unit doesn't exist.
2641              Returns 0 if no successor unit available, i.e. if the given unit
2642              has no output connection.
2643   UPDATE   :
2644 ******************************************************************************/
2645 int  krui_getFirstSuccUnit(int source_unit_no, FlintType *weight)
2646 {
2647 
2648     if KERNEL_STANDARD  {
2649         return( kr_getSuccessorUnit( FIRST, source_unit_no, weight ) );
2650     } else {
2651 
2652 #ifdef MASPAR_KERNEL
2653         return( krff_getSuccessorUnit( FIRST, source_unit_no, weight ) );
2654 #else
2655         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2656         return( KernelErrorCode );
2657 #endif
2658 
2659     }
2660 }
2661 
2662 
2663 /*****************************************************************************
2664   FUNCTION : krui_getNextSuccUnit
2665 
2666   PURPOSE  :
2667   NOTES    : This function is slow  (Units are backward chained only)
2668   IMPORTANT: If a successor unit exists, the current unit and site will be
2669              set to this successor unit and the attached site.
2670 
2671   RETURNS  : Returns the no. of the next successor unit and the connection
2672              strenght.
2673   UPDATE   :
2674 ******************************************************************************/
2675 int  krui_getNextSuccUnit(FlintType *weight)
2676 {
2677 
2678     if KERNEL_STANDARD  {
2679         return( kr_getSuccessorUnit( NEXT, 0, weight ) );
2680     } else {
2681 
2682 #ifdef MASPAR_KERNEL
2683         return( krff_getSuccessorUnit( NEXT, 0, weight ) );
2684 #else
2685         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2686         return( KernelErrorCode );
2687 #endif
2688 
2689     }
2690 }
2691 
2692 
2693 /*****************************************************************************
2694   FUNCTION : krui_areConnected
2695 
2696   PURPOSE  : True if there exists a connection between source unit
2697              <source_unit_no> and target unit <target_unit_no>, otherwise false.
2698   NOTES    : This function is slow (Units are backward chained only).
2699   RETURNS  :
2700   UPDATE   :
2701 ******************************************************************************/
2702 bool  krui_areConnected(int sourceNo, int targetNo)
2703 {
2704     register struct Link *link_ptr ;
2705     register struct Unit *s_unit_ptr, *t_unit_ptr ;
2706     register struct Site *site_ptr ;
2707 
2708     s_unit_ptr = kr_getUnitPtr (sourceNo) ;
2709     t_unit_ptr = kr_getUnitPtr (targetNo) ;
2710 
2711     if( UNIT_HAS_DIRECT_INPUTS (t_unit_ptr)){
2712         for (link_ptr = (struct Link *) t_unit_ptr->sites;
2713              link_ptr != NULL; link_ptr = link_ptr->next)
2714             if (link_ptr->to == s_unit_ptr)
2715 		return (TRUE) ;
2716     }else if( UNIT_HAS_SITES (t_unit_ptr)){
2717 	for (site_ptr = t_unit_ptr->sites; site_ptr != NULL ;
2718 	     site_ptr = site_ptr->next)
2719 	    for (link_ptr = site_ptr->links; link_ptr != NULL ;
2720 		 link_ptr = link_ptr->next)
2721 		if (link_ptr->to == s_unit_ptr)
2722 		    return (TRUE) ;
2723     }
2724 
2725     return (FALSE) ;
2726 }
2727 
2728 
2729 /*****************************************************************************
2730   FUNCTION : krui_areConnectedWeight
2731 
2732   PURPOSE  : True if there exists a connection between source unit
2733              <source_unit_no> and target unit <target_unit_no>, otherwise
2734 	     false. If there exist a connection between these units,
2735 	     krui_areConnectedWeight returns the connection strength also.
2736              Returns FALSE if unit doesn't exist.
2737   NOTES    : This function is slow (Units are backward chained only).
2738   IMPORTANT: If there exist a connection, the current unit and site will be
2739              set to the target unit/site.
2740   RETURNS  :
2741   UPDATE   :
2742 ******************************************************************************/
2743 bool  krui_areConnectedWeight(int source_unit_no, int target_unit_no,
2744 			      FlintType *weight)
2745 {
2746     if KERNEL_STANDARD  {
2747         return( kr_areConnected( source_unit_no, target_unit_no, weight ) );
2748     } else {
2749 
2750 #ifdef MASPAR_KERNEL
2751         return( krff_areConnected( source_unit_no, target_unit_no, weight ) );
2752 #else
2753         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2754         return( FALSE );
2755 #endif
2756 
2757     }
2758 }
2759 
2760 
2761 /*****************************************************************************
2762   FUNCTION : krui_isConnected
2763 
2764   PURPOSE  : True if there exists a connection between source unit
2765              <source_unit_no> and the current unit/site, otherwise false.
2766   NOTES    : If there exists a connection between the two units, the current
2767              link is set to the link between the two units. (alter the link
2768 	     weight with krui_setLinkWeight)
2769 
2770   RETURNS  :
2771   UPDATE   :
2772 ******************************************************************************/
2773 bool  krui_isConnected(int source_unit_no)
2774 {
2775     FlintType  weight;
2776 
2777     if KERNEL_STANDARD  {
2778         return( kr_isConnected( source_unit_no, &weight ) );
2779     } else {
2780 
2781 #ifdef MASPAR_KERNEL
2782         return( krff_isConnected( source_unit_no, &weight ) );
2783 #else
2784         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2785         return( FALSE );
2786 #endif
2787 
2788     }
2789 }
2790 
2791 
2792 /*****************************************************************************
2793   FUNCTION : krui_getLinkWeight
2794 
2795   PURPOSE  :
2796   NOTES    :
2797 
2798   RETURNS  : Returns the link weight of the current link.
2799   UPDATE   :
2800 ******************************************************************************/
2801 FlintType  krui_getLinkWeight(void)
2802 {
2803 
2804     if KERNEL_STANDARD  {
2805         return( kr_getLinkWeight() );
2806     } else {
2807 
2808 #ifdef MASPAR_KERNEL
2809         return( krff_getLinkWeight() );
2810 #else
2811         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2812         return( 0.0 );
2813 #endif
2814 
2815     }
2816 }
2817 
2818 /*****************************************************************************
2819   FUNCTION : krui_setLinkWeight
2820 
2821   PURPOSE  : Sets the link weight of the current link
2822   NOTES    :
2823 
2824   RETURNS  :
2825   UPDATE   :
2826 ******************************************************************************/
2827 void  krui_setLinkWeight(FlintTypeParam weight)
2828 {
2829 
2830     if KERNEL_STANDARD  {
2831         kr_setLinkWeight( weight );
2832     } else {
2833 
2834 #ifdef MASPAR_KERNEL
2835         krff_setLinkWeight( weight );
2836 #else
2837         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2838 #endif
2839 
2840     }
2841 }
2842 
2843 
2844 /*****************************************************************************
2845   FUNCTION : krui_createLink
2846 
2847   PURPOSE  : Creates a link between source unit and the current unit/site.
2848   NOTES    : krui_createLink DO NOT set the current link.
2849              If you want to create a link and its unknown if there exists
2850 	     already a connection between the two units, use krui_createLink
2851 	     and test the return code, instead of the sequence
2852 	     krui_isConnected and krui_createLink.
2853   RETURNS  : Returns an error code:
2854              - if memory allocation fails
2855              - if source unit doesn't exist or
2856              - if there exists already a connection between current unit/site
2857 	       and the source unit
2858              0 otherwise.
2859 
2860   UPDATE   :
2861 ******************************************************************************/
2862 krui_err  krui_createLink(int source_unit_no, FlintTypeParam weight)
2863 {
2864 
2865     if KERNEL_STANDARD  {
2866         return( kr_createLink( source_unit_no, weight ) );
2867     } else {
2868 
2869 #ifdef MASPAR_KERNEL
2870         return( krff_createLink( source_unit_no, weight ) );
2871 #else
2872         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2873         return( KernelErrorCode );
2874 #endif
2875 
2876     }
2877 }
2878 
2879 
2880 /*****************************************************************************
2881   FUNCTION : krui_createLinkWithAdditionalParameters
2882 
2883   PURPOSE  : Creates a link between source unit and the current unit/site.
2884   NOTES    : krui_createLink DO NOT set the current link.
2885              If you want to create a link and its unknown if there exists
2886 	     already a connection between the two units, use krui_createLink
2887 	     and test the return code, instead of the sequence
2888 	     krui_isConnected and krui_createLink.
2889   RETURNS  : Returns pointer to new unit.
2890 
2891   UPDATE   : 13.05.96 <Juergen Gatter>
2892 ******************************************************************************/
2893 struct Link*  krui_createLinkWithAdditionalParameters(int source_unit_no,
2894 						      FlintTypeParam weight,
2895 						      float val_a, float val_b,
2896 						      float val_c)
2897 {
2898 
2899     if KERNEL_STANDARD  {
2900         return( kr_createLinkWithAdditionalParameters(source_unit_no, weight,
2901 						      val_a, val_b, val_c ) );
2902     } else {
2903 
2904 #ifdef MASPAR_KERNEL
2905         KernelErrorCode=krff_createLink( source_unit_no, weight )
2906         return( NULL );
2907 #else
2908         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
2909         return( NULL );
2910 #endif
2911 
2912     }
2913 }
2914 
2915 
2916 /*****************************************************************************
2917   FUNCTION : krui_deleteLink
2918 
2919   PURPOSE  : Deletes the current link.
2920   NOTES    : To delete a link between the current unit/site and the source unit
2921              <source_unit_no>, call krui_isConnected( source_unit_no ) and
2922              krui_deleteLink().
2923 
2924   RETURNS  :
2925   UPDATE   :
2926 ******************************************************************************/
2927 krui_err  krui_deleteLink(void)
2928 {
2929 
2930 #ifdef MASPAR_KERNEL
2931     MASPAR_FF1_VALIDATE_OP;
2932 #endif
2933 
2934     return( kr_deleteLink() );
2935 }
2936 
2937 
2938 /*****************************************************************************
2939   FUNCTION : krui_deleteAllInputLinks
2940 
2941   PURPOSE  : Deletes all input links at current unit/site.
2942   NOTES    :
2943 
2944   RETURNS  :
2945   UPDATE   :
2946 ******************************************************************************/
2947 krui_err  krui_deleteAllInputLinks(void)
2948 {
2949 
2950 #ifdef MASPAR_KERNEL
2951     MASPAR_FF1_VALIDATE_OP;
2952 #endif
2953 
2954     return( kr_deleteAllLinks( INPUTS ) );
2955 }
2956 
2957 
2958 /*****************************************************************************
2959   FUNCTION : krui_deleteAllOutputLinks
2960 
2961   PURPOSE  : Deletes all output links at current unit.
2962   NOTES    : This function is slow.
2963 
2964   RETURNS  :
2965   UPDATE   :
2966 ******************************************************************************/
2967 krui_err  krui_deleteAllOutputLinks(void)
2968 {
2969 
2970 #ifdef MASPAR_KERNEL
2971     MASPAR_FF1_VALIDATE_OP;
2972 #endif
2973 
2974     return( kr_deleteAllLinks( OUTPUTS ) );
2975 }
2976 
2977 
2978 /*****************************************************************************
2979   FUNCTION : krui_jogWeights
2980 
2981   PURPOSE  : Add uniform distributed random values to connection weights.
2982              <minus> must be less then <plus>.
2983   NOTES    :
2984 
2985   RETURNS  :
2986   UPDATE   :
2987 ******************************************************************************/
2988 void  krui_jogWeights(FlintTypeParam minus, FlintTypeParam plus)
2989 {
2990 
2991     if (minus >= plus)  {
2992         KernelErrorCode = KRERR_PARAMETERS;
2993         return;
2994     }
2995 
2996     if KERNEL_STANDARD  {
2997         kr_jogWeights( minus, plus );
2998     } else {
2999 
3000 #ifdef MASPAR_KERNEL
3001         krff_jogWeights( minus, plus );
3002 #else
3003         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
3004 #endif
3005 
3006     }
3007 }
3008 
3009 
3010 /*****************************************************************************
3011   FUNCTION : krui_jogCorrWeights
3012 
3013   PURPOSE  : Add uniform distributed random values to connection weights of
3014              highly correlated, non-special hidden units.
3015              <minus> must be less then <plus>.
3016 	     The two hidden units with maximum positive or negative correlation
3017 	     with an absolute value higher then mincorr are searched. The
3018 	     incoming weights of one of these units are jogged.
3019   NOTES    :
3020 
3021   RETURNS  :
3022   UPDATE   :
3023 ******************************************************************************/
3024 krui_err  krui_jogCorrWeights(FlintTypeParam minus, FlintTypeParam plus,
3025 			      FlintTypeParam mincorr)
3026 {
3027     krui_err res = KRERR_NO_ERROR;
3028 
3029     if (minus >= plus)  {
3030         KernelErrorCode = KRERR_PARAMETERS;
3031         return KernelErrorCode;
3032     }
3033 
3034     if KERNEL_STANDARD  {
3035         res = kr_jogCorrWeights( minus, plus, mincorr );
3036     } else {
3037 
3038 #ifdef MASPAR_KERNEL
3039         krff_jogCorrWeights( minus, plus, mincorr );
3040 #else
3041         KernelErrorCode = KRERR_NO_MASPAR_KERNEL;
3042 #endif
3043 
3044     }
3045     return res;
3046 }
3047 
3048 
3049 /*###########################################################################
3050 
3051 GROUP: Functions for network propagation
3052 
3053 ############################################################################*/
3054 
3055 
3056 /*****************************************************************************
3057   FUNCTION : krui_getVariance
3058 
3059   PURPOSE  :
3060   NOTES    :
3061 
3062   RETURNS  : Variance
3063 
3064 ******************************************************************************/
3065 float krui_getVariance (void)
3066 {
3067     register struct Unit   *unit_ptr;
3068     int   pattern_no=0, o, noOfOutputUnits, size, noOfPatternPairs, sub_pat_no;
3069     Patterns  out_pat;
3070     register float *OutputUnitSumVariance, *OutputUnitVariance,Variance=0;
3071 
3072     noOfOutputUnits=krui_getNoOfOutputUnits();
3073     noOfPatternPairs=kr_np_pattern( PATTERN_GET_NUMBER,0, 0 );
3074     OutputUnitVariance = (float *)calloc(noOfOutputUnits,sizeof (float));
3075     OutputUnitSumVariance = (float *)calloc(noOfOutputUnits,sizeof (float));
3076 
3077     KernelErrorCode = KRERR_NO_ERROR;
3078 
3079     KernelErrorCode = kr_initSubPatternOrder(0,kr_np_pattern(PATTERN_GET_NUMBER,
3080 							     0, 0) - 1);
3081     if(KernelErrorCode != KRERR_NO_ERROR) {
3082 	free (OutputUnitSumVariance);
3083 	free (OutputUnitVariance);
3084 	return (KernelErrorCode);
3085     }
3086     while(kr_getSubPatternByOrder(&pattern_no,&sub_pat_no)){
3087 	out_pat = kr_getSubPatData(pattern_no,sub_pat_no,OUTPUT,&size);
3088 	if(out_pat == NULL){
3089 	    KernelErrorCode = KRERR_NP_NO_SUCH_PATTERN;
3090 	    free (OutputUnitSumVariance);
3091 	    free (OutputUnitVariance);
3092 	    return(-1);
3093 	}
3094 	out_pat += size;
3095 	o=0;
3096 	FOR_ALL_UNITS( unit_ptr )
3097 	    if (IS_OUTPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))  {
3098 		--out_pat;
3099 		OutputUnitVariance[o] += (*out_pat) * (*out_pat);
3100 		OutputUnitSumVariance [o] += *out_pat;
3101 		o++;
3102 	    }
3103     }
3104     o=0;
3105     FOR_ALL_UNITS( unit_ptr )
3106 	if (IS_OUTPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))  {
3107 	    Variance += (OutputUnitVariance[o]/noOfPatternPairs)-
3108 		pow(OutputUnitSumVariance[o]/noOfPatternPairs,2) ;
3109 	    o++;
3110 	}
3111     free (OutputUnitSumVariance);
3112     free (OutputUnitVariance);
3113     return(Variance);
3114 }
3115 
3116 
3117 /*****************************************************************************
3118   FUNCTION : krui_countLinks
3119 
3120   PURPOSE  :
3121   NOTES    :
3122 
3123   RETURNS  : Number of Parameters
3124   UPDATE   :
3125 ******************************************************************************/
3126 int krui_countLinks(void)
3127 {
3128   register struct Unit   *unit_ptr;
3129   register struct Link   *link_ptr;
3130   register int i=0;
3131 
3132   FOR_ALL_UNITS( unit_ptr )
3133     if ((IS_OUTPUT_UNIT(unit_ptr) || IS_HIDDEN_UNIT(unit_ptr))) {
3134       i++;
3135       FOR_ALL_LINKS (unit_ptr,link_ptr)
3136         i ++;
3137     }
3138   return i;
3139 }
3140 
3141 
3142 /*****************************************************************************
3143   FUNCTION : krui_updateSingleUnit
3144 
3145   PURPOSE  : Updates a single unit.
3146   NOTES    : Updates also frozen Units.
3147 
3148   RETURNS  : Returns error code if unit doesn't exist, 0 otherwise.
3149   UPDATE   :
3150 ******************************************************************************/
3151 krui_err   krui_updateSingleUnit(int unit_no)
3152 {
3153     register struct Unit   *unit_ptr;
3154 
3155 
3156 #ifdef MASPAR_KERNEL
3157     MASPAR_FF1_VALIDATE_OP;
3158 #endif
3159 
3160     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
3161         return( KernelErrorCode );
3162 
3163     if (unit_ptr->out_func == NULL)
3164         /*  Identity Function   */
3165         unit_ptr->Out.output = unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
3166     else{
3167 	unit_ptr->act = (*unit_ptr->act_func) (unit_ptr);
3168 	unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
3169     }
3170 
3171     return( KRERR_NO_ERROR );
3172 }
3173 
3174 
3175 /*****************************************************************************
3176   FUNCTION : krui_getUpdateFunc
3177 
3178   PURPOSE  : Returns the current update function. The default update function is
3179              SerialOrder() (see also kr_def.h).
3180   NOTES    :
3181 
3182   RETURNS  :
3183   UPDATE   :
3184 ******************************************************************************/
3185 char  *krui_getUpdateFunc(void)
3186 {
3187     static char  updateFunc[FUNCTION_NAME_MAX_LEN];
3188 
3189     strcpy( updateFunc, krf_getCurrentNetworkFunc( UPDATE_FUNC ) );
3190     return( updateFunc );
3191 }
3192 
3193 
3194 /*****************************************************************************
3195   FUNCTION : krui_setRemapFunc
3196 
3197   PURPOSE  : Changes the current pattern remap function.
3198   NOTES    :
3199 
3200   RETURNS  : Returns error code if remap function is invalid.
3201   UPDATE   :
3202 ******************************************************************************/
3203 krui_err krui_setRemapFunc(char *name, float *params)
3204 {
3205     return( kr_npui_setRemapFunction(name, params) );
3206 }
3207 
3208 
3209 /*****************************************************************************
3210   FUNCTION : krui_setUpdateFunc
3211 
3212   PURPOSE  : Changes the current update function.
3213   NOTES    :
3214 
3215   RETURNS  : Returns error code if update function is invalid.
3216   UPDATE   :
3217 ******************************************************************************/
3218 krui_err   krui_setUpdateFunc(char *update_func)
3219 {
3220 
3221     return( krf_setCurrentNetworkFunc( update_func, UPDATE_FUNC ) );
3222 }
3223 
3224 
3225 
3226 /*****************************************************************************
3227   FUNCTION : krui_updateNet
3228 
3229   PURPOSE  : Updates the network according to update function:
3230   NOTES    : The network should be feedforward in topological mode,
3231              otherwise function will return a warning message.
3232 
3233              See also krui_setSeedNo for initializing the pseudo
3234              random generator.
3235 
3236   RETURNS  : Returns error code if an error occured, 0 othrwise.
3237   UPDATE   :
3238 ******************************************************************************/
3239 krui_err  krui_updateNet(float *parameterInArray, int NoOfInParams)
3240 {
3241 
3242     return( kr_callNetworkFunction( UPDATE_FUNC, parameterInArray, NoOfInParams,
3243                                    NULL, NULL, 0, 0 ) );
3244 }
3245 
3246 
3247 /*############################################################################
3248 
3249 GROUP: Initialisation Functions
3250 
3251 ############################################################################*/
3252 
3253 
3254 /*****************************************************************************
3255   FUNCTION : krui_getInitialisationFunc
3256 
3257   PURPOSE  :
3258   NOTES    :
3259 
3260   RETURNS  : Returns the current initialisation function. The default
3261              initialisation function is RandomizeWeights (see also kr_def.h).
3262   UPDATE   :
3263 ******************************************************************************/
3264 char  *krui_getInitialisationFunc(void)
3265 {
3266 
3267     return( krf_getCurrentNetworkFunc( INIT_FUNC ) );
3268 }
3269 
3270 
3271 /*****************************************************************************
3272   FUNCTION : krui_setInitialisationFunc
3273 
3274   PURPOSE  : Changes the current learning function.  Returns error code if learning
3275     function is invalid.
3276   NOTES    :
3277 
3278   RETURNS  :
3279   UPDATE   :
3280 ******************************************************************************/
3281 krui_err   krui_setInitialisationFunc(char *initialisation_func)
3282 {
3283 
3284     return( krf_setCurrentNetworkFunc( initialisation_func, INIT_FUNC ) );
3285 }
3286 
3287 
3288 /*****************************************************************************
3289   FUNCTION : krui_initializeNet
3290 
3291   PURPOSE  : Initializes the network
3292   NOTES    :
3293 
3294   RETURNS  :
3295   UPDATE   :
3296 ******************************************************************************/
3297 krui_err  krui_initializeNet(float *parameterInArray, int NoOfInParams)
3298 {
3299 
3300     return( kr_callNetworkFunction( INIT_FUNC, parameterInArray, NoOfInParams,
3301                                    NULL, NULL, 0, 0 ) );
3302 }
3303 
3304 
3305 /*############################################################################
3306 
3307 GROUP: Learning Functions
3308 
3309 #############################################################################*/
3310 
3311 
3312 /*****************************************************************************
3313   FUNCTION : krui_getLearnFunc
3314 
3315   PURPOSE  : Returns the current learning function. The default learning
3316              function is Backpropagation (see also kr_def.h).
3317   NOTES    :
3318 
3319   RETURNS  :
3320   UPDATE   :
3321 ******************************************************************************/
3322 char  *krui_getLearnFunc(void)
3323 {
3324     static char  learnFunc[FUNCTION_NAME_MAX_LEN];
3325 
3326     strcpy( learnFunc, krf_getCurrentNetworkFunc( LEARN_FUNC ) );
3327 
3328     return( learnFunc );
3329 }
3330 
3331 
3332 /*****************************************************************************
3333   FUNCTION : krui_setLearnFunc
3334 
3335   PURPOSE  : hanges the current learning function.
3336   NOTES    :
3337 
3338   RETURNS  : Returns error code if learning function is invalid
3339   UPDATE   :
3340 ******************************************************************************/
3341 krui_err   krui_setLearnFunc(char *learning_func)
3342 {
3343 
3344     return( krf_setCurrentNetworkFunc( learning_func, LEARN_FUNC ) );
3345 }
3346 
3347 
3348 /*****************************************************************************
3349   FUNCTION : krui_checkPruning
3350 
3351   PURPOSE  : checks if pruning is enabled
3352   NOTES    :
3353 
3354   RETURNS  : TRUE or FALSE
3355   UPDATE   :
3356 ******************************************************************************/
3357 int krui_checkPruning ()
3358 {
3359 
3360     return (!strcmp (krf_getCurrentNetworkFunc (LEARN_FUNC),
3361                      "PruningFeedForward"));
3362 
3363 }
3364 
3365 
3366 /*****************************************************************************
3367   FUNCTION : krui_trainNetwork
3368 
3369   PURPOSE  :  Learn all pattern pairs using current learning method.
3370               parameterInArray contains the learning parameter(s).
3371 	      NoOfInParams stores the number of learning parameters.
3372               parameterOutArray returns the results from the learning function.
3373               this array is a static array defined in the learning function.
3374               *NoOfOutParams points to a integer value that contains the number
3375               of output parameters from the current learning function.
3376   NOTES    :  Patterns must be loaded before calling this function.
3377   REMEMBER :  The backpropagation learning function takes the learning
3378               parameter from parameterInArray[ 0 ]. parameterOutArray[ 0 ]
3379               returns the current net error.
3380 
3381 
3382   RETURNS  : Returns an error code if memory allocation has failed or if
3383              the parameters are invalid.
3384   UPDATE   :
3385 ******************************************************************************/
3386 krui_err krui_trainNetwork(NetLearnParameters *parameters)
3387 {
3388     register int i;
3389     krui_err error;
3390     float parameterInArray[NO_OF_LEARN_PARAMS];
3391     float *parameterOutArray;
3392 
3393 
3394     parameters->noOfErrors = 0;
3395     /* This must be done for Type double => float */
3396     for (i = 0 ; i < parameters->noOfParameters ; i++)
3397         parameterInArray[i] = (float) parameters->parameter[i];
3398 
3399 
3400     noOfStoredErrors =0;
3401     for(i = 0 , dotraining = TRUE , error = KRERR_NO_ERROR;
3402         dotraining && i < parameters->noOfEpochs && error == KRERR_NO_ERROR;
3403         i++){
3404 
3405         error = kr_callNetworkFunction( LEARN_FUNC,
3406                             parameterInArray, parameters->noOfParameters,
3407                             &parameterOutArray, &parameters->noOfResults,
3408                             parameters->firstPattern,
3409                             parameters->lastPattern);
3410         if (( parameters->noOfEpochs < NO_OF_STORED_ERRORS) ||
3411             (((i+1)%((parameters->noOfEpochs / NO_OF_STORED_ERRORS)+1)) == 0)){
3412             storedLearnErrors[noOfStoredErrors] =
3413                 parameters->learnErrors[parameters->noOfErrors] =
3414                     (double) parameterOutArray[0];
3415             storedAtEpoch[noOfStoredErrors] =
3416                 parameters->atEpoch[parameters->noOfErrors] = i;
3417             noOfStoredErrors++;
3418             parameters->noOfErrors++;
3419         }
3420 
3421     }
3422     storedLearnErrors[noOfStoredErrors] =
3423         parameters->learnErrors[parameters->noOfErrors] =
3424             (double) parameterOutArray[0];
3425     storedAtEpoch[noOfStoredErrors++] =
3426         parameters->atEpoch[parameters->noOfErrors++] = i;
3427     parameters->netError = (double) parameterOutArray[0];
3428     if( dotraining ){
3429         parameters->lastEpoch = parameters->noOfEpochs;
3430         parameters->interrupted = FALSE;
3431     }else{
3432         parameters->lastEpoch = i;
3433         parameters->interrupted = TRUE;
3434     }
3435 
3436     /* This must be done for Type float => double */
3437     for (i = 0 ; i < parameters->noOfResults ; i++)
3438         parameters->result[i] = (double) parameterOutArray[i];
3439 
3440     return(error);
3441 }
3442 
3443 
3444 /*****************************************************************************
3445   FUNCTION : krui_getNetworkErrorArray
3446 
3447   PURPOSE  : Returns the current errorArray
3448   NOTES    : Returns pointer to static Arrays
3449 
3450   RETURNS  :
3451   UPDATE   :
3452 ******************************************************************************/
3453 krui_err krui_getNetworkErrorArray(double **learnErrors,int **atEpoch,
3454 				   int *noOfErrors)
3455 {
3456     *learnErrors = &storedLearnErrors[0];
3457     *atEpoch = &storedAtEpoch[0];
3458     *noOfErrors = noOfStoredErrors;
3459     return(KRERR_NO_ERROR);
3460 }
3461 
3462 
3463 /*****************************************************************************
3464   FUNCTION : krui_stopTraining
3465 
3466   PURPOSE  : Stop the current trainNetwork training
3467   NOTES    :
3468 
3469   RETURNS  :
3470   UPDATE   :
3471 ******************************************************************************/
3472 krui_err krui_stopTraining(void)
3473 {
3474     dotraining = FALSE;
3475     return(KRERR_NO_ERROR);
3476 }
3477 
3478 
3479 /*****************************************************************************
3480   FUNCTION : krui_learnAllPatterns
3481 
3482   PURPOSE  :  Learn all pattern pairs using current learning method.
3483               parameterInArray contains the learning parameter(s).
3484 	      NoOfInParams stores the number of learning parameters.
3485               parameterOutArray returns the results from the learning function.
3486               this array is a static array defined in the learning function.
3487               *NoOfOutParams points to a integer value that contains the number
3488               of output parameters from the current learning function.
3489   NOTES    :  Patterns must be loaded before calling this function.
3490   REMEMBER :  The backpropagation learning function takes the learning
3491               parameter from parameterInArray[ 0 ]. parameterOutArray[ 0 ]
3492               returns the current net error.
3493 
3494 
3495   RETURNS  : Returns an error code if memory allocation has failed or if
3496              the parameters are invalid.
3497   UPDATE   :
3498 ******************************************************************************/
3499 krui_err   krui_learnAllPatterns(float *parameterInArray, int NoOfInParams
3500                                , float **parameterOutArray, int *NoOfOutParams)
3501 /*  REMEMBER:  parameterOutArray[ 0 ] returns the current net error
3502                parameterInArray[ 0 ] contains the 1st learning parameter
3503 */
3504 {
3505 
3506     /*  learn all patterns  */
3507     return( kr_callNetworkFunction( LEARN_FUNC,
3508 				    parameterInArray, NoOfInParams,
3509 				    parameterOutArray, NoOfOutParams,
3510 				    0,kr_np_pattern(PATTERN_GET_NUMBER,0,0)-1));
3511 }
3512 
3513 
3514 /*****************************************************************************
3515   FUNCTION : krui_testAllPatterns
3516 
3517   PURPOSE  :  Test all pattern pairs using current learning method.
3518               parameterInArray contains the learning parameter(s).
3519 	      NoOfInParams stores the number of learning parameters.
3520               parameterOutArray returns the results from the learning function.
3521               this array is a static array defined in the learning function.
3522               *NoOfOutParams points to a integer value that contains the number
3523               of output parameters from the current learning function.
3524   NOTES    :  Patterns must be loaded before calling this function.
3525 
3526               direct copy of krui_learnAllPatterns!!!  joe
3527 
3528   REMEMBER :  The backpropagation learning function takes the learning
3529               parameter from parameterInArray[ 0 ]. parameterOutArray[ 0 ]
3530               returns the current net error.
3531 
3532 
3533   RETURNS  : Returns an error code if memory allocation has failed or if
3534              the parameters are invalid.
3535   UPDATE   : 19.02.95
3536 ******************************************************************************/
3537 krui_err   krui_testAllPatterns(float *parameterInArray, int NoOfInParams,
3538                                 float **parameterOutArray, int *NoOfOutParams)
3539 /*  REMEMBER:  parameterOutArray[ 0 ] returns the current net error
3540                parameterInArray[ 0 ] contains the 1st learning parameter
3541 */
3542 {
3543 
3544     /*  test all patterns  */
3545     return( kr_callNetworkFunction( TEST_FUNC,
3546                                    parameterInArray, NoOfInParams,
3547                                    parameterOutArray, NoOfOutParams,
3548 				   0, kr_np_pattern(PATTERN_GET_NUMBER,0,0)-1));
3549 }
3550 
3551 
3552 /*****************************************************************************
3553   FUNCTION : krui_learnSinglePattern
3554 
3555   PURPOSE  : Same as krui_learnAllPatterns( ... ) but learns only the current
3556              pattern pair.
3557   NOTES    : Patterns must be loaded before calling this function.
3558 
3559   RETURNS  :
3560   UPDATE   :
3561 ******************************************************************************/
3562 krui_err   krui_learnSinglePattern(int pattern_no, float *parameterInArray,
3563 				   int NoOfInParams, float **parameterOutArray,
3564 				   int *NoOfOutParams)
3565 {
3566 
3567     KernelErrorCode = KRERR_NO_ERROR;
3568     return( kr_callNetworkFunction( LEARN_FUNC,
3569                                    parameterInArray, NoOfInParams,
3570                                    parameterOutArray, NoOfOutParams,
3571                                    pattern_no - 1, pattern_no - 1 ) );
3572 }
3573 
3574 
3575 /*****************************************************************************
3576   FUNCTION : krui_testSinglePattern
3577 
3578   PURPOSE  : Same as krui_learnAllPatterns( ... ) but learns only the current
3579              pattern pair.
3580   NOTES    : Patterns must be loaded before calling this function.
3581 
3582   RETURNS  :
3583   UPDATE   :
3584 ******************************************************************************/
3585 krui_err   krui_testSinglePattern(int pattern_no, float *parameterInArray,
3586 				  int NoOfInParams, float **parameterOutArray,
3587 				  int *NoOfOutParams)
3588 {
3589 
3590     KernelErrorCode = KRERR_NO_ERROR;
3591     return( kr_callNetworkFunction( TEST_FUNC,
3592                                    parameterInArray, NoOfInParams,
3593                                    parameterOutArray, NoOfOutParams,
3594                                    pattern_no - 1, pattern_no - 1 ) );
3595 }
3596 
3597 
3598 /*****************************************************************************
3599   FUNCTION : krui_learnAllPatternsFF
3600 
3601   PURPOSE  :  Learn all pattern pairs using current feed forward
3602               learning method.
3603               parameterInArray contains the learning parameter(s).
3604 	      NoOfInParams stores the number of learning parameters.
3605               parameterOutArray returns the results from the learning function.
3606               this array is a static array defined in the learning function.
3607               *NoOfOutParams points to a integer value that contains the number
3608               of output parameters from the current learning function.
3609   NOTES    :  Patterns must be loaded before calling this function.
3610   REMEMBER :  The backpropagation learning function takes the learning
3611               parameter from parameterInArray[ 0 ]. parameterOutArray[ 0 ]
3612               returns the current net error.
3613 
3614 
3615   RETURNS  : Returns an error code if memory allocation has failed or if
3616              the parameters are invalid.
3617   UPDATE   :
3618 ******************************************************************************/
3619 krui_err krui_learnAllPatternsFF (float *parameterInArray, int NoOfInParams,
3620                                   float **parameterOutArray, int *NoOfOutParams)
3621 {
3622 
3623   return(kr_callNetworkFunction(FF_LEARN_FUNC | LEARN_FUNC, parameterInArray,
3624 				NoOfInParams, parameterOutArray, NoOfOutParams,
3625 				0, kr_np_pattern(PATTERN_GET_NUMBER, 0, 0)-1));
3626 
3627 }
3628 
3629 
3630 /*****************************************************************************
3631   FUNCTION : krui_learnSinglePatternFF
3632 
3633   PURPOSE  : Same as krui_learnAllPatternsFF ( ... ) but learns only
3634              the current pattern pair.
3635   NOTES    : Patterns must be loaded before calling this function.
3636 
3637   RETURNS  :
3638   UPDATE   :
3639 ******************************************************************************/
3640 krui_err krui_learnSinglePatternFF (int pattern_no, float *parameterInArray,
3641                                     int NoOfInParams, float **parameterOutArray,
3642                                     int *NoOfOutParams)
3643 {
3644 
3645   KernelErrorCode = KRERR_NO_ERROR;
3646   return (kr_callNetworkFunction (FF_LEARN_FUNC | LEARN_FUNC, parameterInArray,
3647 				  NoOfInParams, parameterOutArray,
3648 				  NoOfOutParams, pattern_no-1, pattern_no-1));
3649 
3650 }
3651 
3652 
3653 /*############################################################################
3654 
3655 GROUP: Pruning Functions
3656 
3657 ############################################################################*/
3658 
3659 
3660 /*****************************************************************************
3661   FUNCTION : krui_getPrunFunc
3662 
3663   PURPOSE  : returns the current pruning function
3664   NOTES    :
3665 
3666   RETURNS  :
3667   UPDATE   :
3668 ******************************************************************************/
3669 char *krui_getPrunFunc (void)
3670 {
3671 
3672     static char prunFunc [FUNCTION_NAME_MAX_LEN];
3673 
3674     strcpy (prunFunc, krf_getCurrentNetworkFunc (PRUNING_FUNC));
3675     return (prunFunc);
3676 
3677 }
3678 
3679 
3680 /*****************************************************************************
3681   FUNCTION : krui_setPrunFunc
3682 
3683   PURPOSE  : changes the current pruning function
3684   NOTES    :
3685 
3686   RETURNS  : returns error code if pruning function is invalid
3687   UPDATE   :
3688 ******************************************************************************/
3689 krui_err krui_setPrunFunc (char *pruning_func)
3690 {
3691 
3692     return (krf_setCurrentNetworkFunc (pruning_func, PRUNING_FUNC));
3693 }
3694 
3695 
3696 /*############################################################################
3697 
3698 GROUP: FF-Learning Functions
3699 
3700 #############################################################################*/
3701 
3702 
3703 /*****************************************************************************
3704   FUNCTION : krui_getFFLearnFunc
3705 
3706   PURPOSE  : returns the current FF-learning function
3707   NOTES    :
3708 
3709   RETURNS  :
3710   UPDATE   :
3711 ******************************************************************************/
3712 char *krui_getFFLearnFunc (void)
3713 {
3714 
3715     static char FFLearnFunc [FUNCTION_NAME_MAX_LEN];
3716 
3717     strcpy (FFLearnFunc, krf_getCurrentNetworkFunc(FF_LEARN_FUNC | LEARN_FUNC));
3718     return (FFLearnFunc);
3719 
3720 }
3721 
3722 
3723 /*****************************************************************************
3724   FUNCTION : krui_setFFLearnFunc
3725 
3726   PURPOSE  : changes the current FF-learning function
3727   NOTES    :
3728 
3729   RETURNS  : returns error code if pruning function is invalid
3730   UPDATE   :
3731 ******************************************************************************/
3732 krui_err krui_setFFLearnFunc (char *FF_learning_func)
3733 {
3734 
3735     return (krf_setCurrentNetworkFunc(FF_learning_func,
3736 				      FF_LEARN_FUNC | LEARN_FUNC));
3737 }
3738 
3739 
3740 /*############################################################################
3741 
3742 GROUP: Pattern Management
3743 
3744 ############################################################################*/
3745 
3746 /*****************************************************************************
3747   FUNCTION : krui_setClassDistribution
3748 
3749   PURPOSE  : Sets the class distribution in the current pattern.
3750   NOTES    : Patterns must be loaded before calling this function.
3751 
3752   RETURNS  : Returns kernel error code
3753   UPDATE   :
3754 ******************************************************************************/
3755 krui_err krui_setClassDistribution(unsigned int *classDist)
3756 {
3757 
3758     return(kr_npui_setClassDistribution(classDist));
3759 }
3760 
3761 
3762 /*****************************************************************************
3763   FUNCTION : krui_setClassInfo
3764 
3765   PURPOSE  : Sets the class name in the current pattern.
3766   NOTES    :
3767 
3768   RETURNS  : Returns kernel error code
3769   UPDATE   :
3770 ******************************************************************************/
3771 krui_err krui_setClassInfo(char *name)
3772 {
3773     printf("Kernel debug: new pattern class : %s \n",name);
3774     return(kr_npui_setClass(name));
3775 }
3776 
3777 
3778 /*****************************************************************************
3779   FUNCTION : krui_useClassDistribution
3780 
3781   PURPOSE  : Toggles the use of the user defined distribution of patterns
3782              (TRUE) as compared to the distribution in the pattern file
3783   NOTES    :
3784 
3785   RETURNS  : kernel error code
3786   UPDATE   :
3787 ******************************************************************************/
3788 krui_err  krui_useClassDistribution(bool use_it)
3789 {
3790 
3791     return( kr_npui_useChunk(use_it) );
3792 }
3793 
3794 /*****************************************************************************
3795   FUNCTION : krui_setPatternNo
3796 
3797   PURPOSE  : Sets the current pattern.
3798   NOTES    : Patterns must be loaded before calling this function.
3799 
3800   RETURNS  : Returns a error code if pattern number is invalid.
3801   UPDATE   :
3802 ******************************************************************************/
3803 krui_err  krui_setPatternNo(int pattern_no)
3804 {
3805 
3806     return( kr_np_pattern( PATTERN_SET, 0, pattern_no ) );
3807 }
3808 
3809 /*****************************************************************************
3810   FUNCTION : krui_getPatternNo
3811 
3812   PURPOSE  : Returns the current pattern number.
3813   NOTES    :
3814 
3815   RETURNS  :
3816   UPDATE   :
3817 ******************************************************************************/
3818 krui_err  krui_getPatternNo(void)
3819 {
3820 
3821     return( kr_np_pattern( PATTERN_GET, 0, 0 ) );
3822 }
3823 
3824 /*****************************************************************************
3825   FUNCTION : krui_deletePattern
3826 
3827   PURPOSE  :delete the current pattern pair
3828   NOTES    :
3829 
3830   RETURNS  :
3831   UPDATE   :
3832 ******************************************************************************/
3833 krui_err  krui_deletePattern(void)
3834 {
3835 
3836     return( kr_np_pattern( PATTERN_DELETE, 0 , 0 ) );
3837 }
3838 
3839 
3840 /*****************************************************************************
3841   FUNCTION : krui_modifyPattern
3842 
3843   PURPOSE  : modify the current pattern pair
3844   NOTES    :
3845 
3846   RETURNS  :
3847   UPDATE   :
3848 ******************************************************************************/
3849 krui_err  krui_modifyPattern(void)
3850 {
3851 
3852     return( kr_np_pattern( PATTERN_MODIFY, 0 , 0 ) );
3853 }
3854 
3855 
3856 /*****************************************************************************
3857   FUNCTION : krui_showPattern
3858 
3859   PURPOSE  : According to the mode krui_showPattern stores the current
3860              Pattern into the units activation (and/or output) values.
3861              The modes are:
3862                - OUTPUT_NOTHING
3863                   store input pattern into input units activations
3864                - OUTPUT_ACT
3865                   store input pattern into input units activations and
3866                   store output pattern into output units activations
3867                - OUTPUT_OUT
3868                   store input pattern into input units activations,
3869                   store output pattern into output units activations and
3870                   update output units output
3871 
3872   NOTES    : See include file glob_typ.h for mode constants.
3873 
3874   RETURNS  :
3875   UPDATE   :
3876 ******************************************************************************/
3877 krui_err  krui_showPattern(int mode)
3878 {
3879 
3880     return( kr_np_pattern( PATTERN_SHOW, mode, 0 ) );
3881 }
3882 
3883 
3884 /*****************************************************************************
3885   FUNCTION : krui_allocNewPatternSet
3886 
3887   PURPOSE  : Allocate a new empty pattern set
3888   NOTES    :
3889 
3890   RETURNS  : Returns the number of the allcated pattern set;
3891              Returns error code if an error occured
3892   UPDATE   :
3893 ******************************************************************************/
3894 krui_err  krui_allocNewPatternSet(int *set_no)
3895 {
3896 
3897     KernelErrorCode = kr_npui_allocNewPatternSet(set_no);
3898     return KernelErrorCode;
3899 }
3900 
3901 
3902 /*****************************************************************************
3903   FUNCTION : krui_newPattern
3904 
3905   PURPOSE  : Creates a new pattern pair.
3906              A pattern pair can be created by modifying the activation
3907              value of the input/output units.
3908   NOTES    : krui_newPattern switches pattern shuffeling off.
3909              For shuffeling the new pattern pairs call
3910                  krui_newPattern(...)
3911                  krui_shufflePattern( TRUE )
3912 
3913   RETURNS  : Returns error code if memory is insufficent or no. of
3914              input/output units is incompatible, 0 otherwise.
3915   UPDATE   :
3916 ******************************************************************************/
3917 krui_err  krui_newPattern(void)
3918 {
3919 
3920     return( kr_np_pattern( PATTERN_NEW, 0, 0 ) );
3921 }
3922 
3923 
3924 /*****************************************************************************
3925   FUNCTION : krui_getNoOfPatterns
3926 
3927   PURPOSE  : Returns the no. of available pattern pairs.
3928   NOTES    :
3929 
3930   RETURNS  :
3931   UPDATE   :
3932 ******************************************************************************/
3933 int  krui_getNoOfPatterns(void)
3934 {
3935     int number;
3936     number = kr_np_pattern( PATTERN_GET_NUMBER, 0, 0 );
3937     return (number >= 0) ? number : 0;
3938 }
3939 
3940 
3941 /*****************************************************************************
3942   FUNCTION : krui_getTotalNoOfSubPatterns
3943 
3944   PURPOSE  : Returns the total no. of available subpattern pairs.
3945   NOTES    :
3946 
3947   RETURNS  :
3948   UPDATE   :
3949 ******************************************************************************/
3950 int  krui_getTotalNoOfSubPatterns(void)
3951 {
3952     int number;
3953     number = kr_np_pattern( SUBPATTERN_GET_NUMBER, 0, 0 );
3954     return (number >= 0) ? number : 0;
3955 }
3956 
3957 
3958 /*****************************************************************************
3959   FUNCTION : krui_deleteAllPatterns
3960   PURPOSE  : [ Release previously defined patterns from memory.
3961               Call krui_releasePatterns() if you want to create totally
3962               new patterns with krui_newPattern(). ]
3963   NOTES    : This function is of no effect any longer since there exists
3964              the new function krui_deletePatSet (see below)
3965 
3966 
3967   RETURNS  :
3968   UPDATE   :
3969 ******************************************************************************/
3970 void  krui_deleteAllPatterns(void)
3971 {
3972 
3973     (void) kr_np_pattern( PATTERN_DELETE_ALL, 0, 0 );
3974 }
3975 
3976 
3977 /*****************************************************************************
3978   FUNCTION : krui_shufflePatterns
3979 
3980   PURPOSE  : Shuffle pattern pairs by using pseudo random generator.
3981              Shuffeling of patterns is used by krui_learnAllPatterns(...).
3982              krui_shufflePatterns( TRUE ) switches shuffeling of patterns
3983              on, krui_shufflePatterns( FALSE ) switches shuffeling of
3984              patterns off.
3985              The default presetting is krui_shufflePatterns( FALSE ).
3986   NOTES    : See also krui_setSeedNo( seed )
3987 
3988   RETURNS  :
3989   UPDATE   :
3990 ******************************************************************************/
3991 krui_err  krui_shufflePatterns(bool on_or_off)
3992 {
3993 
3994     if (on_or_off)
3995         return kr_np_pattern( PATTERN_SHUFFLE_ON, 0, 0 );
3996     else
3997         return kr_np_pattern( PATTERN_SHUFFLE_OFF, 0, 0 );
3998 
3999 }
4000 
4001 
4002 /*****************************************************************************
4003   FUNCTION : krui_shuffleSubPatterns
4004 
4005   PURPOSE  : Shuffle sub pattern pairs by using pseudo random generator.
4006              Shuffeling of patterns is used by krui_learnAllPatterns(...).
4007              krui_shuffleSubPatterns(TRUE) switches shuffeling of sub patterns
4008              on, krui_shuffleSubPatterns( FALSE ) switches shuffeling of
4009              sub patterns off.
4010              The default presetting is krui_shuffleSubPatterns( FALSE ).
4011   NOTES    : See also krui_setSeedNo( seed )
4012 
4013   RETURNS  :
4014   UPDATE   :
4015 ******************************************************************************/
4016 krui_err  krui_shuffleSubPatterns(bool on_or_off)
4017 {
4018 
4019     if (on_or_off)
4020         return kr_np_pattern( PATTERN_SUB_SHUFFLE_ON, 0, 0 );
4021     else
4022         return kr_np_pattern( PATTERN_SUB_SHUFFLE_OFF, 0, 0 );
4023 }
4024 
4025 
4026 /*****************************************************************************
4027   FUNCTION : krui_setCurrPatSet
4028 
4029   PURPOSE  : Choose the number of the current pattern set.
4030              <number> starts from 0.
4031   RETURNS  :
4032   NOTES    :
4033 
4034   UPDATE   :
4035 ******************************************************************************/
4036 krui_err  krui_setCurrPatSet(int number)
4037 {
4038 
4039     return kr_npui_setCurrPatSet(number);
4040 }
4041 
4042 
4043 /*****************************************************************************
4044   FUNCTION : krui_deletePatSet
4045 
4046   PURPOSE  : Delete all patterns of pattern set with number <number>
4047              The ordering of the remaining pattern sets is reorganized by
4048              decrementing the pattern set numbers which are higher than
4049              <number> by 1. For example: there exist the pattern sets 0, 1, 2
4050              and 3. After deleting pattern set 1 the pattern sets 2 and 3 are
4051              renamed to 1 and 2.
4052   RETURNS  :
4053   NOTES    :
4054 
4055   UPDATE   :
4056 ******************************************************************************/
4057 krui_err  krui_deletePatSet(int number)
4058 {
4059 
4060     return kr_npui_deletePatSet(number);
4061 }
4062 
4063 
4064 /*****************************************************************************
4065   FUNCTION : krui_GetPatInfo
4066 
4067   PURPOSE  : Get all available information concerning the current pattern set
4068              and the current pattern.
4069   RETURNS  :
4070   NOTES    :
4071 
4072   UPDATE   :
4073 ******************************************************************************/
4074 krui_err  krui_GetPatInfo(pattern_set_info *set_info,
4075 			  pattern_descriptor *pat_info)
4076 {
4077 
4078     return kr_npui_GetPatInfo(set_info, pat_info);
4079 }
4080 
4081 
4082 /*****************************************************************************
4083   FUNCTION : krui_DefShowSubPat
4084 
4085   PURPOSE  : Define the sub pattern to be shown with next call to
4086              krui_showPattern
4087   RETURNS  :
4088   NOTES    :
4089 
4090   UPDATE   :
4091 ******************************************************************************/
4092 krui_err  krui_DefShowSubPat(int *insize, int *outsize, int *inpos, int *outpos)
4093 {
4094 
4095     return kr_npui_DefShowSubPat(insize, outsize, inpos, outpos);
4096 }
4097 
4098 
4099 /*****************************************************************************
4100   FUNCTION : krui_DefTrainSubPat
4101 
4102   PURPOSE  : Define how sub patterns should be generated during training
4103   RETURNS  :
4104   NOTES    :
4105 
4106   UPDATE   :
4107 ******************************************************************************/
4108 krui_err  krui_DefTrainSubPat(int *insize, int *outsize,
4109                               int *instep, int *outstep, int *max_n_pos)
4110 {
4111 
4112     return kr_npui_DefTrainSubPat(insize, outsize, instep, outstep, max_n_pos);
4113 }
4114 
4115 
4116 /*****************************************************************************
4117   FUNCTION : krui_AlignSubPat
4118 
4119   PURPOSE  : Align the given sub pattern position (<inpos> and <outpos>)
4120              to a valid position which fits the defined sub pattern training
4121              scheme (krui_DefTrainSubPat).
4122 
4123   RETURNS  : kernel error code
4124              <inpos> and <outpos> returns the aligned position
4125              <no> returns the resulting ordering position of the sub pattern
4126   NOTES    :
4127 
4128   UPDATE   :
4129 ******************************************************************************/
4130 krui_err krui_AlignSubPat(int *inpos, int *outpos, int *no)
4131 {
4132 
4133     return kr_npui_AlignSubPat(inpos, outpos, no);
4134 }
4135 
4136 
4137 /*****************************************************************************
4138   FUNCTION : krui_GetShapeOfSubPattern
4139 
4140   PURPOSE  : Get shape of sub pattern <n_pos> using current set,
4141              current pattern and current train scheme (defined with
4142              krui_DefTrainSubPat)
4143   RETURNS  :
4144   NOTES    :
4145 
4146   UPDATE   :
4147 ******************************************************************************/
4148 krui_err  krui_GetShapeOfSubPattern(int *insize, int *outsize,
4149                                     int *inpos, int *outpos, int n_pos)
4150 {
4151 
4152     return kr_npui_GetShapeOfSubPat(insize, outsize, inpos, outpos, n_pos);
4153 }
4154 
4155 
4156 /*############################################################################
4157 
4158 GROUP: I/O Functions
4159 
4160 ############################################################################*/
4161 
4162 
4163 /*****************************************************************************
4164   FUNCTION : krui_saveNet
4165 
4166   PURPOSE  : Save a network.
4167              If netname is a NULL pointer, the net will get the name "UNTITLED"
4168   NOTES    :
4169 
4170   RETURNS  :  Returns error code if an error occured, or 0 otherwise.
4171   UPDATE   :
4172 ******************************************************************************/
4173 krui_err  krui_saveNet(char *filename, char *netname)
4174 {
4175 
4176     return( krio_saveNet( filename, netname ) );
4177 }
4178 
4179 
4180 /*****************************************************************************
4181   FUNCTION : krui_loadNet
4182 
4183   PURPOSE  : Load a network file and create a network.
4184              Returns the name of the net or "UNTITLED" if unknown.
4185   NOTES    :
4186 
4187   RETURNS  : Returns error code if an error occured during
4188              loading/memory allocation, or 0 otherwise.
4189   UPDATE   :
4190 ******************************************************************************/
4191 krui_err  krui_loadNet(char *filename, char **netname)
4192 {
4193     char        *netfile_version; /*  isn't used now  */
4194 
4195     KernelErrorCode = KRERR_NO_ERROR;
4196 
4197     KernelErrorCode = krio_loadNet( filename, netname, &netfile_version );
4198     if (KernelErrorCode != KRERR_NO_ERROR)
4199         return( KernelErrorCode );
4200 
4201     kr_updateUnitOutputs();
4202 
4203     return( KernelErrorCode );
4204 }
4205 
4206 
4207 /*****************************************************************************
4208   FUNCTION : krui_loadNewPatterns
4209 
4210   PURPOSE  : Load file containing pattern pairs of new Style conventions.
4211   NOTES    :
4212 
4213   RETURNS  : Returns the number of the loaded pattern set;
4214              Returns error code if an error occured during
4215              loading/memory allocation, or 0 otherwise.
4216   UPDATE   :
4217 ******************************************************************************/
4218 krui_err  krui_loadNewPatterns(char *filename, int *set_no)
4219 {
4220 
4221     KernelErrorCode = kr_npui_loadNewPatterns(filename, set_no);
4222     return KernelErrorCode;
4223 }
4224 
4225 
4226 /*****************************************************************************
4227   FUNCTION : krui_saveNewPatterns
4228 
4229   PURPOSE  : Save pattern file with new style conventions
4230              The pattern set with number <number> is saved.
4231   NOTES    :
4232 
4233   RETURNS  :
4234   UPDATE   :
4235 ******************************************************************************/
4236 krui_err  krui_saveNewPatterns(char *filename, int set_no)
4237 {
4238 
4239     KernelErrorCode = kr_npui_saveNewPatterns(filename, set_no);
4240     return KernelErrorCode;
4241 }
4242 
4243 
4244 /*****************************************************************************
4245   FUNCTION : krui_saveResultParam
4246 
4247   PURPOSE  : Save the network result which depends on the loaded patterns.
4248              If create is false, the new file will be appended to an existing
4249              file. startpattern and endpattern determine the range of patterns
4250              to use. The input patterns and the teaching output patterns can
4251              be included.
4252   NOTES    : This is a new version of the old function krui_saveResult with
4253              added parameter passing for the update functions.
4254 
4255   RETURNS  :
4256   UPDATE   :
4257 ******************************************************************************/
4258 krui_err  krui_saveResultParam(char *filename, bool create,
4259                                int startpattern, int endpattern,
4260                                bool includeinput, bool includeoutput,
4261                                float *Update_param_array, int NoOfUpdateParam)
4262 {
4263 
4264     return( krio_saveResult(filename, create, startpattern, endpattern,
4265                             includeinput, includeoutput,
4266                             Update_param_array, NoOfUpdateParam));
4267 }
4268 
4269 
4270 /*############################################################################
4271 
4272 GROUP: Functions for memory management
4273 
4274 ############################################################################*/
4275 
4276 
4277 /*****************************************************************************
4278   FUNCTION : krui_allocateUnits
4279 
4280   PURPOSE  : Allocates a given number of units, additional units
4281              may allocated by calling this function again.
4282              This function is called automatically if the user
4283              construct more units than have been allocated before, but
4284              it is recommended to use this function if a large amount
4285              of units is needed (the UNIX System can manage system resources
4286              much better, if the amount of memory used for the network is
4287              approximately known before the network is created).
4288   NOTES    : If krui_create_unit has been called before using this
4289              function, at least <UNIT_BLOCK> numbers of units have been
4290              allocated.
4291              See "kr_def.h" for more information about memory allocation
4292              block sizes.
4293 
4294   RETURNS  : Returns error code if memory allocation fails, 0 otherwise.
4295   UPDATE   :
4296 ******************************************************************************/
4297 krui_err  krui_allocateUnits(int no_of_units)
4298 {
4299 
4300     return( krm_allocUnits( no_of_units ) );
4301 }
4302 
4303 
4304 /*****************************************************************************
4305   FUNCTION : krui_deleteNet
4306 
4307   PURPOSE  :  Delete network, names and unit types.
4308               Frees all memory used for the network.
4309   NOTES    : If krui_loadNet is called more then once,  krui_deleteNet will
4310              be called by krui_loadNet, because the kernel have to free the
4311              memory used for the old network.
4312              It is recommended (but not neccessary) to call krui_deleteNet
4313              before terminating the SNNS-Kernel.
4314 
4315   RETURNS  :
4316   UPDATE   :
4317 ******************************************************************************/
4318 void  krui_deleteNet(void)
4319 {
4320 
4321     krm_releaseMem();
4322 }
4323 
4324 
4325 /*############################################################################
4326 
4327 GROUP: Functions for reading/searching the symbol table
4328 
4329 ############################################################################*/
4330 
4331 
4332 /*****************************************************************************
4333   FUNCTION : krui_getFirstSymbolTableEntry
4334 
4335   PURPOSE  : Returns the first symbol/symbol type entry in the
4336              symbol table. Returns true if this entry is available,
4337              false otherwise.
4338   NOTES    :
4339 
4340   RETURNS  :
4341   UPDATE   :
4342 ******************************************************************************/
4343 bool  krui_getFirstSymbolTableEntry(char **symbol_name, int *symbol_type)
4344 {
4345     struct NameTable      *n_tbl;
4346 
4347     n_tbl = krm_getNTableFirstEntry();
4348 
4349     while ( (n_tbl != NULL) && ((int) n_tbl->sym_type == UNUSED_SYM) )
4350         n_tbl = krm_getNTableNextEntry();
4351 
4352     if (n_tbl == NULL) {
4353 	*symbol_name = NULL;
4354 	*symbol_type = 0;
4355 	return( FALSE );
4356     }
4357 
4358     *symbol_name = n_tbl->Entry.symbol;
4359     *symbol_type = (int) n_tbl->sym_type;
4360     return( TRUE );
4361 }
4362 
4363 
4364 /*****************************************************************************
4365   FUNCTION : krui_getNextSymbolTableEntry
4366 
4367   PURPOSE  : Returns the next symbol/symbol type entry in the
4368              symbol table. Returns true if another entry is available,
4369              false otherwise.
4370   NOTES    :
4371 
4372   RETURNS  :
4373   UPDATE   :
4374 ******************************************************************************/
4375 bool  krui_getNextSymbolTableEntry(char **symbol_name, int *symbol_type)
4376 {
4377     struct NameTable      *n_tbl;
4378 
4379     n_tbl = krm_getNTableNextEntry();
4380 
4381     while ( (n_tbl != NULL) && ((int) n_tbl->sym_type == UNUSED_SYM) )
4382         n_tbl = krm_getNTableNextEntry();
4383 
4384     if (n_tbl == NULL) {
4385 	*symbol_name = NULL;
4386 	*symbol_type = 0;
4387 	return( FALSE );
4388     }
4389 
4390     *symbol_name = n_tbl->Entry.symbol;
4391     *symbol_type = (int) n_tbl->sym_type;
4392     return( TRUE );
4393 }
4394 
4395 
4396 /*****************************************************************************
4397   FUNCTION : krui_symbolSearch
4398 
4399   PURPOSE  : Searches the symbol table for a given symbol and
4400              symbol type (unit name symbol, site name symbol,
4401              functionality unit name symbol)
4402   NOTES    :
4403 
4404   RETURNS  : Returns true, if the symbol exists.
4405   UPDATE   :
4406 ******************************************************************************/
4407 bool  krui_symbolSearch(char *symbol, int symbol_type)
4408 {
4409 
4410     return( krm_NTableSymbolSearch( symbol, symbol_type ) != NULL );
4411 }
4412 
4413 
4414 /*###########################################################################
4415 
4416 GROUP: Miscellanous
4417 
4418 ############################################################################*/
4419 
4420 
4421 /*****************************************************************************
4422   FUNCTION : krui_getVersion
4423 
4424   PURPOSE  : Returns the current Version of the SNNS-Kernel.
4425   NOTES    :
4426 
4427   RETURNS  :
4428   UPDATE   :
4429 ******************************************************************************/
4430 char  *krui_getVersion(void)
4431 {
4432     static char snns_version[128];
4433 
4434     strcpy( snns_version, SNNS_VERSION );
4435     strcat( snns_version, KERNEL_PATCH );
4436     return( snns_version );
4437 }
4438 
4439 
4440 /*****************************************************************************
4441   FUNCTION : krui_getNetInfo
4442 
4443   PURPOSE  : Returns miscellanous information about the current network.
4444   NOTES    :
4445 
4446   RETURNS  :
4447   UPDATE   :
4448 ******************************************************************************/
4449 void  krui_getNetInfo(int *no_of_sites, int *no_of_links,
4450 		      int *no_of_STable_entries, int *no_of_FTable_entries)
4451 {
4452     int   array_size,
4453     info_array[ 10 ];
4454 
4455     krm_getMemoryManagerInfo( &array_size, info_array );
4456 
4457     *no_of_sites          = info_array[ 0 ];
4458     *no_of_links          = info_array[ 1 ];
4459     *no_of_STable_entries = info_array[ 2 ];
4460     *no_of_FTable_entries = info_array[ 3 ];
4461 }
4462 
4463 
4464 /*****************************************************************************
4465   FUNCTION : krui_getMemoryManagerInfo
4466 
4467   PURPOSE  : Returns the number of ALLOCATED (not the number of USED) bytes
4468     per entry.
4469   NOTES    :
4470 
4471   RETURNS  :
4472   UPDATE   :
4473 ******************************************************************************/
4474 void  krui_getMemoryManagerInfo(int *unit_bytes, int *site_bytes,
4475 				int *link_bytes, int *NTable_bytes,
4476 				int *STable_bytes, int *FTable_bytes)
4477 {
4478     int   array_size,
4479     info_array[ 10 ];
4480 
4481     krm_getMemoryManagerInfo( &array_size, info_array );
4482 
4483     *unit_bytes   = info_array[ 4 ] * UNIT_SIZE;
4484     *site_bytes   = info_array[ 5 ] * SITE_SIZE;
4485     *link_bytes   = info_array[ 6 ] * LINK_SIZE;
4486     *NTable_bytes = info_array[ 7 ] * NTABLE_SIZE;
4487     *STable_bytes = info_array[ 8 ] * STABLE_SIZE;
4488     *FTable_bytes = info_array[ 9 ] * FTYPE_UNIT_SIZE;
4489 }
4490 
4491 
4492 /*****************************************************************************
4493   FUNCTION : krui_getUnitDefaults
4494 
4495   PURPOSE  : Returns Information about the unit default settings.
4496              For more information about default settings see
4497 	     krui_createDefaultUnit() and krui_createFTypeUnit( .. ).
4498   NOTES    :
4499 
4500   RETURNS  :
4501   UPDATE   :
4502 ******************************************************************************/
4503 void  krui_getUnitDefaults(FlintType *act, FlintType *bias, int *st,
4504 			   int *subnet_no, int *layer_no, char **act_func,
4505 			   char **out_func)
4506 {
4507     int ttflags;
4508 
4509     kr_getUnitDefaults( act, bias, &ttflags, subnet_no, layer_no,
4510                        act_func, out_func );
4511 
4512     *st = kr_flags2TType( ttflags );
4513 }
4514 
4515 
4516 /*****************************************************************************
4517   FUNCTION :  krui_setUnitDefaults
4518 
4519   PURPOSE  : Changes the unit default settings.
4520              For more information about default settings see
4521 	     krui_createDefaultUnit() and krui_createFTypeUnit( .. ).
4522   NOTES    :
4523 
4524   RETURNS  : Returns error code if
4525              - activation/output function is invalid
4526              - Topologic type is invalid
4527              0 otherwise.
4528   UPDATE   :
4529 ******************************************************************************/
4530 krui_err  krui_setUnitDefaults(FlintTypeParam act, FlintTypeParam bias,
4531 			       int st, int subnet_no, int layer_no,
4532 			       char *act_func, char *out_func)
4533 {
4534     int        ttflags;
4535 
4536     ttflags = kr_TType2Flags( st );
4537     if (KernelErrorCode != KRERR_NO_ERROR)
4538         return( KernelErrorCode );
4539 
4540     kr_setUnitDefaults( act, bias, ttflags, subnet_no, layer_no,
4541                        act_func, out_func );
4542     return( KernelErrorCode );
4543 }
4544 
4545 
4546 /*****************************************************************************
4547   FUNCTION : krui_resetNet
4548 
4549   PURPOSE  : Reset the network by changeing the unit activation
4550              to the initial activation value.
4551   NOTES    :
4552 
4553   RETURNS  :
4554   UPDATE   :
4555 ******************************************************************************/
4556 extern FlintType OUT_Custom_Python(FlintType act);
4557 
4558 void  krui_resetNet(void)
4559 {
4560     register int   i;
4561     register struct Unit   *unit_ptr;
4562 
4563     if ( (unit_array == NULL) || (NoOfUnits == 0) )
4564         return;
4565 
4566 
4567     for (i = MinUnitNo, unit_ptr = unit_array + MinUnitNo; i <= MaxUnitNo;
4568 	 i++, unit_ptr++)
4569         if UNIT_IN_USE( unit_ptr )  {
4570             /*  unit is in use  */
4571             unit_ptr->act = unit_ptr->i_act;
4572 
4573             if (unit_ptr->out_func == OUT_IDENTITY)
4574                 unit_ptr->Out.output = unit_ptr->act;
4575             else if(unit_ptr->out_func == OUT_Custom_Python)
4576 	    	unit_ptr->Out.output =
4577 			kr_PythonOutFunction(unit_ptr->python_out_func,
4578 				unit_ptr->act);
4579             else
4580                 /*  no identity output function: calculate unit's output also */
4581                 unit_ptr->Out.output = (*unit_ptr->out_func) (unit_ptr->act);
4582         }
4583 }
4584 
4585 
4586 /*****************************************************************************
4587   FUNCTION : krui_setSeedNo
4588 
4589   PURPOSE  : Initialize the pseudo random generator.
4590              0 as argument reinitializes the random generator.
4591   NOTES    :
4592 
4593   RETURNS  :
4594   UPDATE   :
4595 ******************************************************************************/
4596 void  krui_setSeedNo(long int seed)
4597 {
4598 
4599     if (seed != 0) {
4600 	randomSeedVal = seed;
4601         srand48( seed );
4602     } else {
4603         if (randomSeedVal == 0) {
4604             randomSeedVal = (long) time( (time_t *) 0);
4605             srand48( randomSeedVal );
4606         }
4607     }
4608 }
4609 
4610 
4611 /*****************************************************************************
4612   FUNCTION : krui_getNoOfInputUnits
4613 
4614   PURPOSE  :
4615   NOTES    :
4616 
4617   RETURNS  : Returns the no. of input units
4618   UPDATE   :
4619 ******************************************************************************/
4620 int  krui_getNoOfInputUnits(void)
4621 {
4622 
4623     return( kr_getNoOfUnits( INPUT ) + kr_getNoOfUnits( DUAL ) +
4624 	    kr_getNoOfUnits( SPECIAL_I ) + kr_getNoOfUnits( SPECIAL_D ) );
4625 }
4626 
4627 
4628 /*****************************************************************************
4629   FUNCTION : krui_getNoOfOutputUnits
4630 
4631   PURPOSE  :
4632   NOTES    :
4633 
4634   RETURNS  : returns the no. of output units
4635   UPDATE   :
4636 ******************************************************************************/
4637 int  krui_getNoOfOutputUnits(void)
4638 {
4639 
4640     return( kr_getNoOfUnits( OUTPUT ) + kr_getNoOfUnits( DUAL ) +
4641 	    kr_getNoOfUnits( SPECIAL_O ) + kr_getNoOfUnits( SPECIAL_D ) );
4642 }
4643 /*****************************************************************************
4644   FUNCTION : krui_getNoOfTTypeUnits
4645 
4646   PURPOSE  : returns the no. of units of the specified topologic type
4647              (i.e. Input, Hidden, Output or Special units)
4648   NOTES    :
4649 
4650   RETURNS  :
4651   UPDATE   :
4652 ******************************************************************************/
4653 int  krui_getNoOfTTypeUnits(int UnitTType)
4654 {
4655 
4656     return( kr_getNoOfUnits( UnitTType ) );
4657 }
4658 
4659 
4660 /*****************************************************************************
4661   FUNCTION : krui_getNoOfSpecialInputUnits
4662 
4663   PURPOSE  :
4664   NOTES    :
4665 
4666   RETURNS  : Returns the no. of special input units
4667   UPDATE   :
4668 ******************************************************************************/
4669 int  krui_getNoOfSpecialInputUnits(void)
4670 {
4671 
4672   return( kr_getNoOfSpecialUnits( INPUT ) + kr_getNoOfUnits( DUAL ) );
4673 }
4674 
4675 
4676 /*****************************************************************************
4677   FUNCTION : krui_getNoOfSpecialOutputUnits
4678 
4679   PURPOSE  :
4680   NOTES    :
4681 
4682   RETURNS  : returns the no. of special output units
4683   UPDATE   :
4684 ******************************************************************************/
4685 int  krui_getNoOfSpecialOutputUnits(void)
4686 {
4687 
4688   return( kr_getNoOfSpecialUnits( OUTPUT ) + kr_getNoOfUnits( DUAL ) );
4689 }
4690 
4691 
4692 /*****************************************************************************
4693   FUNCTION : krui_xyTransTable
4694 
4695   PURPOSE  : Get/modify the XY-Translation table
4696   NOTES    :
4697 
4698   RETURNS  :
4699   UPDATE   :
4700 ******************************************************************************/
4701 krui_err  krui_xyTransTable(int op, int *x, int *y, int z)
4702 {
4703 
4704     return(kr_xyTransTable(op,x,y,z));
4705 }
4706 
4707 /*****************************************************************************
4708   FUNCTION : krui_getUnitCenters
4709 
4710   PURPOSE  : Returns the 3D transform center of the specified unit and center number
4711   NOTES    :
4712 
4713   RETURNS  :
4714   UPDATE   :
4715 ******************************************************************************/
4716 krui_err  krui_getUnitCenters(int unit_no, int center_no,
4717 			      struct PositionVector **unit_center)
4718 {
4719     struct Unit   *unit_ptr;
4720 
4721     KernelErrorCode = KRERR_NO_ERROR;
4722 
4723     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
4724         return( KernelErrorCode );
4725 
4726     if ((center_no < 0) || (center_no >= NO_OF_UNIT_CENTER_POS))  {
4727         KernelErrorCode = KRERR_PARAMETERS;
4728         return( KRERR_PARAMETERS );
4729     }
4730 
4731     *unit_center = unit_ptr->unit_center_pos + center_no;
4732     return( KRERR_NO_ERROR );
4733 }
4734 
4735 
4736 /*****************************************************************************
4737   FUNCTION :  krui_setUnitCenters
4738 
4739   PURPOSE  : Sets the 3D transform center of the specified unit and center
4740              number
4741   NOTES    :
4742 
4743   RETURNS  :
4744   UPDATE   :
4745 ******************************************************************************/
4746 krui_err  krui_setUnitCenters(int unit_no, int center_no,
4747 			      struct PositionVector *unit_center)
4748 {
4749     struct Unit   *unit_ptr;
4750     struct PositionVector    *unit_posvec_ptr;
4751 
4752     KernelErrorCode = KRERR_NO_ERROR;
4753 
4754     if ((unit_ptr = kr_getUnitPtr( unit_no )) == NULL)
4755         return( KernelErrorCode );
4756 
4757     if ((center_no < 0) || (center_no >= NO_OF_UNIT_CENTER_POS))  {
4758         KernelErrorCode = KRERR_PARAMETERS;
4759         return( KRERR_PARAMETERS );
4760     }
4761 
4762     unit_posvec_ptr = unit_ptr->unit_center_pos + center_no;
4763 
4764     memcpy( (char *) unit_posvec_ptr, (char *) unit_center,
4765 	    sizeof( struct PositionVector ) );
4766 
4767     return( KRERR_NO_ERROR );
4768 }
4769 
4770 
4771 /*****************************************************************************
4772   FUNCTION : krui_topo_err_msg
4773 
4774   PURPOSE  : generate a message about an error found while doing a
4775              topologiacal sorting of the network units
4776   NOTES    :
4777 
4778   RETURNS  :
4779   UPDATE   :
4780 ******************************************************************************/
4781 static char  *krui_topo_err_msg(void)
4782 {
4783     char  *dest_unit_name,  *src_unit_name;
4784     static char  msg1[512];
4785     static char  msg2[512];
4786 
4787     /* Init */
4788     msg1[0] = '\0';
4789     msg2[0] = '\0';
4790 
4791     if (topo_msg.dest_error_unit > 0)
4792         dest_unit_name = krui_getUnitName( topo_msg.dest_error_unit );
4793 
4794     if (topo_msg.src_error_unit > 0)
4795         src_unit_name = krui_getUnitName( topo_msg.src_error_unit );
4796 
4797     if (topo_msg.dest_error_unit > 0)
4798         if (dest_unit_name == NULL)
4799             sprintf( msg1, "Unit #%d is the destination unit. ",
4800 		     topo_msg.dest_error_unit );
4801         else
4802             sprintf( msg1, "Unit #%d (%s) is the destination unit. ",
4803 		     topo_msg.dest_error_unit, dest_unit_name );
4804 
4805     if (topo_msg.src_error_unit > 0)
4806         if (src_unit_name == NULL)
4807             sprintf( msg2, "Unit #%d is the source unit. ",
4808 		     topo_msg.src_error_unit );
4809         else
4810             sprintf( msg2, "Unit #%d (%s) is the source unit. ",
4811 		     topo_msg.src_error_unit, src_unit_name );
4812 
4813     if (topo_msg.dest_error_unit == 0)
4814         return( msg2 );
4815 
4816     if (topo_msg.src_error_unit > 0)
4817         strcat( msg1, msg2 );
4818 
4819     return( msg1 );
4820 }
4821 
4822 
4823 /*****************************************************************************
4824   FUNCTION : krui_error
4825 
4826   PURPOSE  : Returns an error message, depending on the error code.
4827              If a function returns an error code use krui_error to
4828              get the message.
4829   NOTES    :
4830 
4831   RETURNS  :
4832   UPDATE   :
4833 ******************************************************************************/
4834 char  *krui_error(int error_code)
4835 {
4836     static char *err_message[] = {
4837         "Invalid error code",
4838         "Insufficient memory",
4839         "Invalid unit number",
4840         "Invalid unit output function",
4841         "Invalid unit activation function",
4842         "Invalid site function",
4843         "Creation of sites isn't permitted because unit has direct input links",
4844         "Creation of a link isn't permitted because there exists already a link between these units",
4845         "Memory allocation failed during critical operation. Have lost some pointers, but consistency of the network is guaranteed",
4846         "Ftype name isn't definite",
4847         /*10*/"Current Ftype entry isn't defined",
4848         "Invalid copy mode",
4849         "Current unit doesn't have sites",
4850         "Can't update unit because unit is frozen",
4851         "Redefinition of site name isn't permitted (site name already exists)",
4852         "Site name isn't defined",
4853         "This is not a 3D-Kernel",
4854         "This unit has already a site with this name",
4855         "Can't delete site table entry because site is in use",
4856         "Current Ftype site isn't defined",
4857         /*20*/"Ftype symbol isn't defined",
4858         "I/O error: ",
4859         "Creation of output file failed (line length limit exceeded)",
4860         "The network has not enough layers: ",
4861         "No Units defined",
4862         "Unexpected EOF",
4863         "Line length exceeded",
4864         "Incompatible file format",
4865         "Can't open file",
4866         "Syntax error",
4867         /*30*/"Memory allocation error #01",
4868         "Topologic type invalid",
4869         "Symbol pattern invalid (must match [A-Za-z][^|, ]*)",
4870         "Current unit doesn't have a site with this name",
4871         "No hidden units defined",
4872         "Network contains cycle(s): ",
4873         "Network contains dead unit(s): ",
4874         "Pattern file contains not the same no. of input units as the network",
4875         "Pattern file contains not the same no. of output units as the network",
4876         "No. of input units have changed",
4877         /*40*/"No. of output units have changed",
4878         "No input units defined",
4879         "No output units defined",
4880         "No patterns defined",
4881         "In-Core patterns incompatible with current network (remove In-Core patterns before loading a new network)",
4882         "Invalid pattern number",
4883         "Invalid learning function",
4884         "Invalid parameters",
4885         "Invalid update function",
4886         "Invalid initialisation function",
4887         /*50*/"Derivation function of the activation function doesn't exist",
4888         "Input unit(s) with input connection(s) to other units: ",
4889         "Output unit(s) with output connection(s) to other units: ",
4890         "Invalid topological sorting mode",
4891         "Learning function doesn't support sites",
4892         "Sites are not supported",
4893         "This isn't a MasPar Kernel",
4894         "Connection(s) between unit(s) in non-neighbour layers are not supported: ",
4895         "The network has too much layers: ",
4896         "The network layers aren't fully connected",
4897         /*60*/"This operation isn't allowed in the parallel kernel mode",
4898         "Change of network type isn't possible in parallel kernel mode",
4899         "No current link defined",
4900         "No current unit defined",
4901         "Current unit doesn't have any inputs",
4902         "Invalid parameter in topologic definition section",
4903         "Creation of link between these units isn't permitted",
4904         "MasPar don't respond",
4905         "This function isn't implemented yet",
4906         "Kernel isn't in parallel mode",
4907         /*70*/"MasPar ran out of memory",
4908         "MasPar communication error",
4909         "MasPar ran out of processors",
4910         "Missing default function (check function table)",
4911         "MasPar kernel doesn't support multiple unit output functions",
4912         "MasPar kernel doesn't support multiple unit activation functions",
4913         "The depth of the network doesn't fit to the learning function",
4914         "Wrong no of units in layer: ",
4915         "Unit is missing or not correctly connected: ",
4916         "Unit doesn't belong to a defined layer in the network: ",
4917         /*80*/"Unit has wrong activation function: ",
4918         "Unit has wrong output function: ",
4919         "Unexpected site function at unit: ",
4920         "Unit is not expected to have sites: ",
4921         "Unit is expected to have sites: ",
4922         "Site missing at unit: ",
4923         "Unexpected link: ",
4924         "Missing link(s) to unit: ",
4925         "Link ends at wrong site of destination unit: ",
4926         "This network is not fitting the required topology",
4927         /*90*/"Wrong beta parameter in unit bias value: ",
4928         "CC error: Topo_ptr_array is sorted in the wrong way", /*CC_ERROR1*/
4929         "CC error: There is no memory allocated", /*CC_ERROR2*/
4930         "CC error: Not enough memory to run Casscade", /*CC_ERROR3*/
4931         "Invalid error code", /*RCC_ERROR4*/
4932         "Invalid error code", /*RCC_ERROR5*/
4933         "CC error: Hidden layer is not fitting the required topology",
4934         "Invalid error code", /*RCC_ERROR7*/
4935         "Invalid error code", /*RCC_ERROR8*/
4936         "Invalid error code", /*RCC_ERROR9*/
4937         /*100*/ "Wrong update function",/*CC_ERROR10*/
4938         "Wrong init function",  /*CC_ERROR11*/
4939         "DLVQ error: There are empty classes",
4940         "DLVQ error: There exists a class lower than zero",
4941         "DLVQ error: Wrong no. of output units",
4942         "DLVQ error: This network is not fitting the required topology",
4943         "DLVQ error: There does not exist a unit for every class",
4944         "No more free pattern sets available",
4945         "No such pattern set defined",
4946         "No current pattern defined",
4947         /*110*/ "Specified sub pattern does not fit into pattern",
4948         "No such pattern available",
4949         "No current pattern set defined",
4950         "Pattern (sub pattern) does not fit the network",
4951         "No sub pattern shifting scheme defined",
4952         "Pattern contains no output information",
4953         "New pattern does not fit into existing set",
4954         "Paragon kernel not initialized",
4955         "Paragon kernel already initialized",
4956         "Sending a message fails",
4957         /*120*/ "Syntax error in received message",
4958         "Receive unknown command",
4959         "Less patterns then allocated nodes",
4960         "Weight update with global sum fails",
4961         "Learning function not parallelized",
4962         "Invalid error code", /* RPC-Call failed */
4963         "Invalid error code", /* RPC-Timeout */
4964         "Invalid error code", /* RPC: No Server defined */
4965         "Invalid error code", /* RPC: Cooperativ failed */
4966         "Invalid error code", /* RPC: No response from the slaves */
4967         /*130*/ "Algorithm needs patterns. Please press TEST first to check patterns.",
4968 	"RBF-DDA: First input parameter out of range 0<theta_pos<=1.",
4969 	"RBF-DDA: Second input parameter out of range 0<theta_neg<=1.",
4970 	"RBF-DDA: Third input parameter must be >=0.",
4971 	"RBF-DDA: More than one desired class in output pattern.",
4972 	"RBF-DDA: Input-hidden connection pointer problem.",
4973 	"RBF-DDA: Input-output shortcut connections are not allowed.",
4974 	"RBF-DDA: Activation function of input units must be Act_Identity.",
4975 	"RBF-DDA: Activation function of hidden units must be Act_RBF_Gaussian.",
4976 	"RBF-DDA: Activation function of output units must be Act_Identity.",
4977         /*140*/ "CC error : Invalid additional Parameters.",
4978         "Activation-functions have to be Act_Threshold.",
4979         "Learning function must be online Backpropagation",
4980 	"No learning possible with only one class",
4981 	"Invalid pattern remap function",
4982         "Patterns don't have class information",
4983 	"Illegal virtual class distribution",
4984 	"Patterns can not be normalized"
4985     };  /* 147 error messages */
4986 
4987     static char *ext_messages[] = {
4988         "SNNS-Kernel No Errors",
4989         "SNNS-Kernel Error: ",
4990         "SNNS-Kernel Network Topologic Error: "
4991         };
4992 
4993     int  NoOfMessages = (sizeof (err_message)) / (sizeof (err_message[0]));
4994     static char  mesg[512], aux[512];
4995 
4996 
4997     if (error_code == 0)        return( ext_messages[0] ); /*   No errors  */
4998 
4999     error_code = abs( error_code );
5000     if ( error_code >= NoOfMessages )  error_code = 0; /* invalid error code */
5001 
5002     switch (-error_code)
5003         {
5004           case KRERR_CYCLES:
5005           case KRERR_DEAD_UNITS:
5006           case KRERR_I_UNITS_CONNECT:
5007           case KRERR_O_UNITS_CONNECT:
5008           case KRERR_NOT_NEIGHBOUR_LAYER:
5009           case KRERR_ACT_FUNC:
5010           case KRERR_OUT_FUNC:
5011           case KRERR_SITE_FUNC:
5012           case KRERR_UNEXPECTED_SITES:
5013           case KRERR_UNEXPECTED_DIRECT_INPUTS:
5014           case KRERR_SITE_MISSING:
5015           case KRERR_UNEXPECTED_LINK:
5016           case KRERR_LINK_MISSING:
5017           case KRERR_LINK_TO_WRONG_SITE:
5018           case KRERR_PARAM_BETA:
5019           case KRERR_UNDETERMINED_UNIT:
5020 
5021             strcpy( mesg, ext_messages[2] );
5022             strcat( mesg, err_message[ error_code ] );
5023 
5024             switch (-error_code){
5025 	    case KRERR_CYCLES:
5026 		sprintf( aux, "%d cycle(s) in the network. ",
5027 			 topo_msg.no_of_cycles );
5028 		strcat( mesg, aux );
5029 		break;
5030 	    case KRERR_DEAD_UNITS:
5031 		sprintf( aux, "%d dead unit(s) in the network. ",
5032 			 topo_msg.no_of_dead_units );
5033 		strcat( mesg, aux );
5034 		break;
5035 
5036 	    default: break;
5037 	    }
5038 
5039             strcat( mesg, krui_topo_err_msg() );
5040             return( mesg );
5041 
5042 
5043           case KRERR_FEW_LAYERS:
5044           case KRERR_MUCH_LAYERS:
5045           case KRERR_NOT_FULLY_CONNECTED:
5046 	      strcpy( mesg, ext_messages[2] );
5047 	      strcat( mesg, err_message[ error_code ] );
5048 
5049 	      switch (-error_code){
5050 	      case KRERR_FEW_LAYERS:
5051 		  sprintf(aux, "Only %d layers found.", topo_msg.no_of_layers );
5052 		  break;
5053 	      case KRERR_MUCH_LAYERS:
5054 		  sprintf( aux, "%d layers found.", topo_msg.no_of_layers );
5055 		  break;
5056 
5057 	      default: break;
5058 	      }
5059 
5060 	      strcat( mesg, aux );
5061 	      return( mesg );
5062 
5063           case KRERR_NO_OF_UNITS_IN_LAYER:
5064 	      strcpy (mesg, ext_messages[2]);
5065 	      strcat (mesg, err_message [error_code]);
5066 	      sprintf (aux, "The name of the layer is: %s", topo_msg.name);
5067 	      strcat (mesg, aux);
5068 	      return (mesg);
5069 
5070           case KRERR_UNIT_MISSING:
5071 	      strcpy (mesg, ext_messages[2]);
5072 	      strcat (mesg, err_message [error_code]);
5073 	      sprintf (aux, "The missing unit is the %s unit.", topo_msg.name);
5074 	      strcat (mesg, aux);
5075 	      return (mesg);
5076 
5077 
5078 
5079           case KRERR_FILE_OPEN:
5080 	      lineno = 0;
5081 
5082           default:
5083 	      if (lineno != 0){               /*  file I/O error  */
5084 		  strcpy( mesg, ext_messages[1] );
5085 		  sprintf( aux, "Loading file failed at line %d : ", lineno );
5086 		  strcat( mesg, aux );
5087 		  strcat( mesg, err_message[ error_code ] );
5088 
5089 		  lineno = 0;
5090 		  return( mesg );
5091 	      } else {               /*  standard error  */
5092 		  strcpy( mesg, ext_messages[1] );
5093 		  strcat( mesg, err_message[ error_code ] );
5094 		  return( mesg );
5095 	      }
5096         }
5097 }
5098 
5099 
5100 /*****************************************************************************
5101   FUNCTION :  krui_NA_Error
5102 
5103   PURPOSE  : calculates the error for the network-analyzer tool
5104   NOTES    :
5105 
5106   RETURNS  : Returns the float value of the error
5107   UPDATE   :
5108 ******************************************************************************/
5109 float krui_NA_Error(int currentPattern, int error_unit, int error, bool ave)
5110 {
5111 
5112   return( kr_NA_Error(currentPattern, error_unit, error, ave) );
5113 }
5114 
5115 
5116 /*############################################################################
5117 
5118   Functions for the external kernels
5119 
5120 ########################################################################### */
5121 
5122 
5123 /*****************************************************************************
5124   FUNCTION : krui_setSpecialNetworkType
5125 
5126   PURPOSE  : Sets the topologic type of the current network.
5127              Returns an error if the topologic type of the current network
5128              doesn't fit to this type.
5129              Topologic types are:
5130                - NET_TYPE_GENERAL
5131                  general purpose network type with no limitations
5132                - NET_TYPE_FF1
5133                  feedforward network with fully connected units in
5134                  neighbour layers
5135   NOTES    :
5136 
5137   RETURNS  :
5138   UPDATE   :
5139 ******************************************************************************/
5140 krui_err  krui_setSpecialNetworkType(int net_type)
5141 {
5142 
5143     (void) kr_setSpecialNetworkType( net_type );
5144     return( KernelErrorCode );
5145 }
5146 
5147 
5148 /*****************************************************************************
5149   FUNCTION :  krui_getSpecialNetworkType
5150 
5151   PURPOSE  :
5152   NOTES    :
5153 
5154   RETURNS  : Returns the special topologic type of the current network, if set.
5155   UPDATE   :
5156 ******************************************************************************/
5157 int  krui_getSpecialNetworkType(void)
5158 {
5159 
5160     return( kr_getSpecialNetworkType() );
5161 }
5162 
5163 
5164 /*****************************************************************************
5165   FUNCTION : krui_initInversion
5166 
5167   PURPOSE  : initialize net for inversion algorithm
5168   NOTES    :
5169   UPDATE   : 06.02.92
5170 ******************************************************************************/
5171 int krui_initInversion(void)
5172 {
5173 
5174     return( kr_initInversion() );
5175 }
5176 
5177 
5178 /*****************************************************************************
5179   FUNCTION : krui_inv_forwardPass
5180 
5181   PURPOSE  : topological forward propagation of the inversion algorithm
5182   NOTES    :
5183   UPDATE   : 29.01.92
5184 ******************************************************************************/
5185 void  krui_inv_forwardPass(struct UnitList *inputs)
5186 {
5187 
5188     kr_inv_forwardPass(inputs);
5189 }
5190 
5191 
5192 /*****************************************************************************
5193   FUNCTION : krui_inv_backwardPass
5194 
5195   PURPOSE  : Backward error propagation (topological)
5196   NOTES    :
5197   UPDATE   : 04.02.92
5198 *****************************************************************************/
5199 double krui_inv_backwardPass(float learn, float delta_max, int *err_units,
5200                              float ratio, struct UnitList *inputs,
5201                              struct UnitList *outputs)
5202 {
5203 
5204     return(kr_inv_backwardPass(learn,delta_max,err_units,
5205                                ratio,inputs,outputs) ) ;
5206 }
5207 
5208 
5209 /*###########################################################################
5210 
5211   Functions for the MasPar kernel
5212 
5213 ########################################################################### */
5214 
5215 
5216 #ifdef MASPAR_KERNEL
5217 /*****************************************************************************
5218   FUNCTION : krui_MasPar
5219 
5220   PURPOSE  : Connects and disconnects the MasPar.
5221              The mode switches are:  MASPAR_CONNECT and MASPAR_DISCONNECT.
5222   NOTES    :
5223 
5224   RETURNS  :
5225   UPDATE   :
5226 ******************************************************************************/
5227 krui_err  krui_MasPar(int mode )
5228 {
5229 
5230   return( kr_initMasPar( mode ) );
5231 }
5232 
5233 
5234 /*****************************************************************************
5235   FUNCTION : krui_getMasParStatus
5236 
5237   PURPOSE  : Returns the status of the MasPar.
5238   NOTES    :
5239 
5240   RETURNS  :
5241   UPDATE   :
5242 ******************************************************************************/
5243 krui_err  krui_getMasParStatus(void)
5244 {
5245 
5246   return( kr_getMasParStatus() );
5247 }
5248 
5249 
5250 /*****************************************************************************
5251   FUNCTION : krui_MasParBenchmark
5252 
5253   PURPOSE  : Perform benchmark tests
5254   NOTES    :
5255 
5256   RETURNS  :
5257   UPDATE   :
5258 ******************************************************************************/
5259 krui_err  krui_MasParBenchmark(int func_type,int cycles,float  *result )
5260 {
5261     float  parameterInArray[NO_OF_LEARN_PARAMS];
5262     float  *parameterOutArray;
5263     int  NoOfOutParams;
5264 
5265 
5266     parameterInArray[0] = (float) cycles;
5267     (void) kr_callNetworkFunction( func_type | BENCH_FUNC,
5268 				   parameterInArray, 1, &parameterOutArray,
5269 				   &NoOfOutParams, 0, 0 );
5270 
5271     *result = parameterOutArray[0];
5272     return( KernelErrorCode );
5273 }
5274 
5275 
5276 #endif
5277 
5278 
5279 /*****************************************************************************
5280   FUNCTION :  krui_kohonen_SetExtraParameter
5281 
5282   PURPOSE  :
5283   NOTES    :
5284 
5285   RETURNS  :
5286   UPDATE   :
5287 ******************************************************************************/
5288 void krui_kohonen_SetExtraParameter(int x)
5289 {
5290 
5291     kohonen_SetExtraParameter(x);
5292 }
5293 
5294 
5295 /*****************************************************************************
5296   FUNCTION :  krui_spanning_tree
5297 
5298   PURPOSE  :
5299   NOTES    :
5300 
5301   RETURNS  :
5302   UPDATE   :
5303 ******************************************************************************/
5304 void krui_spanning_tree(void)
5305 {
5306 
5307     spanning_tree();
5308 }
5309 
5310 
5311 /*****************************************************************************
5312   FUNCTION :  krui_cc_updatePosOfSpecialUnits
5313 
5314   PURPOSE  :
5315   NOTES    :
5316 
5317   RETURNS  :
5318   UPDATE   :
5319 ******************************************************************************/
5320 void krui_cc_updatePosOfSpecialUnits(void)
5321 {
5322 
5323     cc_updatePosOfSpecialUnits();
5324 }
5325 
5326 
5327 /*****************************************************************************
5328   FUNCTION :  krui_cc_deleteAllSpecialUnits
5329   PURPOSE  :
5330   NOTES    :
5331 
5332   RETURNS  :
5333   UPDATE   :
5334 ******************************************************************************/
5335 krui_err krui_cc_deleteAllSpecialUnits(void)
5336 {
5337 
5338     return(cc_deleteAllSpecialUnits());
5339 }
5340 
5341 
5342 /*****************************************************************************
5343   FUNCTION :  krui_getErrorCode
5344   PURPOSE  :
5345   NOTES    :
5346 
5347   RETURNS  :
5348   UPDATE   :
5349 ******************************************************************************/
5350 int krui_getErrorCode(void)
5351 {
5352 
5353     return(krui_error_code);
5354 }
5355 
5356 
5357 /*****************************************************************************
5358   FUNCTION :  krui_setErrorHandler
5359   PURPOSE  :
5360   NOTES    :
5361 
5362   RETURNS  :
5363   UPDATE   :
5364 ******************************************************************************/
5365 krui_err krui_setErrorHandler(void(* error_Handler )(int))
5366 {
5367 
5368     krui_errorHandler = error_Handler;
5369     return(0);
5370 }
5371 
5372 /*****************************************************************************
5373   FUNCTION :   krui_execHandler
5374   PURPOSE  :
5375   NOTES    :
5376 
5377   RETURNS  :
5378   UPDATE   :
5379 ******************************************************************************/
5380 void krui_execHandler(int error_code)
5381 {
5382 
5383     if(krui_errorHandler != NULL)  ((*krui_errorHandler) (error_code));
5384 }
5385