/* This library is for use only in education and research. It is not for commercial use! Written permission from author is necessary for commercial use or for inclusion as a part of project or program or another library! Programs, projects, libraries or anything consists this library or its part MUST NOT be sold without author permission! Author: Dekovich Igor, ph: (-61) (2) 4225 2673, mobile: (-61) 042 189 69 84 e-mail: idekovich@yahoo.com */ #ifndef _FUZZY_H #define _FUZZY_H #include#include #include #include #ifdef __cplusplus extern "C"{ #endif #ifndef TEST_MALLOC #define TEST_MALLOC 0 #endif #ifndef UINT_MAX #define UINT_MAX 65535 #endif /* testmalloc and testfree are introduced to enable easier analysis of a problem with memory allocation occur */ /* enable (by defining TEST_MALLOC (before calling fuzzy library, for example "#define TEST_MALLOC 1") different than 0) printing history of all malloc allocations and freeding of memory */ /* all malloc calls should be replaced with testmalloc ones (instead of "malloc(XXX)" should be written "testmalloc(XXX)") */ /* all free calls should be replaced with testfree ones (instead of "free(XXX)" should be written "testfree(XXX)") */ void *testmalloc(size_t nrbytes); void testfree(char *p); /* definiranje struktura fuzzy skupa i njegovih klasa preko linearnih lista */ typedef union mux { char *name; float notes; } mux; typedef struct characteristic { char *name; float membership; struct characteristic *ahead, *follow; struct fuzzy_object *set; } characteristic, *link_characteristic; typedef struct fuzzy_object { union mux m; int number_of_characteristics; struct characteristic *first, *actual, *last; } fuzzy_object, *link_set; typedef struct fuzzy_set { char *name; int number_of_objects; struct fuzzy_object **objects; } fuzzy_set; enum Bool {F=0,T=1}; enum check_type {Y=0,S=1,M=2,ALL=3}; typedef struct crisp_set{ int number_of_subsets; char *name; enum Bool *memberships; } crisp_set; /* void exit_handling(int number, int location) prints message and then exits execution of program; "int number" describes what caused exit and chooses message. */ void exit_handling(int number, int location); /* "T"* MA"T"(int number_of_elements) where "T" means type and can be 'C'=char, 'D'=double, 'F'=float, 'I'=int, 'L'=long, 'S'=short, 'Si'=signed, 'U'=unsigned, 'Cl'=characteristic, 'FO'=fuzzy_object, 'FS'=fuzzy_set, 'CS'=crisp_set, 'EB'=enum Bool, 'ECT'= enum check_type, 'TS'=time_slice or any of previous letters with (one or more, up to 3) prefix 'p' =pointer on */ /* Returns pointer to space to be reserved (allocated)!*/ /* It deals with memory allocation (testmalloc) request for number_of_elements locations of type "T". In the case there is no available memory request is being repeated up to 101 times and if there is still lack of free memory unsucessfull end of process is caused (exit(1)). */ char* MAC(long int number_of_elements); int* MAI(long int number_of_elements); float* MAF(long int number_of_elements); double* MAD(long int number_of_elements); long* MAL(long int number_of_elements); short* MAS(long int number_of_elements); signed* MASi(long int number_of_elements); unsigned int* MAU(long int number_of_elements); characteristic* MACl(long int number_of_elements); fuzzy_object* MAFO(long int number_of_elements); fuzzy_set* MAFS(long int number_of_elements); crisp_set* MACS(long int number_of_elements); enum Bool* MAEB(long int number_of_elements); enum check_type* MAECT(long int number_of_elements); char** MApC(long int number_of_elements); int** MApI(long int number_of_elements); float** MApF(long int number_of_elements); double** MApD(long int number_of_elements); long** MApL(long int number_of_elements); short** MApS(long int number_of_elements); signed** MApSi(long int number_of_elements); unsigned int** MApU(long int number_of_elements); characteristic** MApCl(long int number_of_elements); fuzzy_object** MApFO(long int number_of_elements); fuzzy_set** MApFS(long int number_of_elements); crisp_set** MApCS(long int number_of_elements); enum Bool** MApEB(long int number_of_elements); enum check_type** MApECT(long int number_of_elements); char*** MAppC(long int number_of_elements); int*** MAppI(long int number_of_elements); float*** MAppF(long int number_of_elements); double*** MAppD(long int number_of_elements); long*** MAppL(long int number_of_elements); short*** MAppS(long int number_of_elements); signed*** MAppSi(long int number_of_elements); unsigned int*** MAppU(long int number_of_elements); characteristic*** MAppCl(long int number_of_elements); fuzzy_object*** MAppFO(long int number_of_elements); fuzzy_set*** MAppFS(long int number_of_elements); crisp_set*** MAppCS(long int number_of_elements); enum Bool*** MAppEB(long int number_of_elements); enum check_type*** MAppECT(long int number_of_elements); char**** MApppC(long int number_of_elements); int**** MApppI(long int number_of_elements); float**** MApppF(long int number_of_elements); double**** MApppD(long int number_of_elements); long**** MApppL(long int number_of_elements); short**** MApppS(long int number_of_elements); signed**** MApppSi(long int number_of_elements); unsigned int**** MApppU(long int number_of_elements); characteristic**** MApppCl(long int number_of_elements); fuzzy_object**** MApppFO(long int number_of_elements); fuzzy_set**** MApppFS(long int number_of_elements); crisp_set**** MApppCS(long int number_of_elements); enum Bool**** MApppEB(long int number_of_elements); enum check_type**** MApppECT(long int number_of_elements); /* *read_name() u~itaje skup karaktera koji sadr`i slova, brojeve, znakove interpunkcije; a unutar char vektora su ti skupovi odijeljeni ili jednim od prvih 40 ASCII znakova ili izme|u 59 i 63 ili 127 ASCII znakom */ char *read_name(char *read_in, char *read_from); /* *set_fill() je funkcija za u~itavanje fuzzy objekta preko pohranjivanja u polje pomo}u funkcije *characteristic_fill() */ characteristic *characteristic_fill(characteristic *link, fuzzy_object *head1, char *names, float *memberships); fuzzy_object *set_fill(int nmbr_characteristics, char *names, float *memberships); /* *fuzzy_set_fill() je funkcija za u~itavanje fuzzy skupa preko pohranjivanja u polje pomo}u funkcije *set_fill() */ fuzzy_set *fuzzy_set_fill(int nmbr_objects, char* f_set_name, char **names, float **memberships, int *nmbr_characteristics); /* delete_fuzzy_object() je funkcija za brisanje pohranjenog fuzzy objekta */ void delete_fuzzy_object(fuzzy_object *head); /* delete_fuzzy_set() je funkcija za brisanje pohranjenog fuzzy seta */ void delete_fuzzy_set(fuzzy_set *head); /* set_read() puni vektore names[] i memberships[] (must point to the reserved large enough location) imenima fuzzy objecta i klasa sljedno, te vrijednostima ~lanstva u pojedinoj klasi sljedno; iz zadanog fuzzy objecta */ /* ALL VECTORS M U S T BE P R E V I O U S L Y D I M E N S I O N E D */ void set_read(fuzzy_object *head, char *names, float *memberships); /* fuzzy_set_read() puni vektore names[] i memberships[] (must point to the reserved large enough location) of each fuzzy object pointed by **names and **memberships imenima fuzzy objecta i klasa sljedno, te vrijednostima ~lanstva u pojedinoj klasi sljedno; fill address pointed by *f_set_name (enough space must be booked, Maximum enough is 100*sizeof(char)); iz zadanog fuzzy skupa */ /* ALL VECTORS M U S T BE P R E V I O U S L Y D I M E N S I O N E D */ void fuzzy_set_read(fuzzy_set *head, char **names, float **memberships, char *f_set_name); /* fill_set() puni fuzzy object iz vektora names[] i memberships[] */ void fill_set(fuzzy_object *head, char *names, float *memberships); /* fill_fuzzy_set() fills existing fuzzy set (with the same number of objects) with new values for objects names and characteristics names and memberships */ void fill_fuzzy_set(fuzzy_set *head, char **names, float **memberships); /* fill_fuzzy_object_memberships() fills only membership values of (characteristics of) existing fuzzy object from vector *memberships */ void fill_fuzzy_object_memberships(fuzzy_object *head, float *memberships); /* fill_fuzzy_set_memberships() fills only membership values of (characteristics of objects of) existing fuzzy set from vectors *memberships for each fuzzy object pointed by **memberships */ void fill_fuzzy_set_memberships(fuzzy_set *head, float **memberships); /* fuzzy_object_check() je funkcija koja provjerava da li je suma svih funkcija ~lanstva = 1+border, te da li su sve funkcije ~lanstva izmedu 0 i 1 ; vra}a vrijednosti: Y=0 - sve je u redu, S=1 - suma nije u redu, M=2 - jedna ili vi{e funkcija ~lanstva nije u redu, ALL=3 - nije u redu suma, te jedna ili vi{e funkcija ~lanstva nije u redu ; ulazna veli~ina je dozvoljeno odstupanje sume od 1 uslijed floating point ra~unanja */ /* pomo}ne funkcije su fuzzy_check_sum() koja vra}a T=1 ako je suma izmedu 1-border i 1+border, a F=0 ako nije; te fuzzy_check_membership() koja vra~a T=1 ako je svaka vrijednost funkcije ~lanstva izmedu 0 i 1, a F=0 ako nije */ enum Bool fuzzy_check_sum(fuzzy_object *head, float border); enum Bool fuzzy_check_membership(fuzzy_object *head); enum check_type fuzzy_object_check(fuzzy_object *head, float border); /* fuzzy_object_normalisation() vr{i normalizaciju vrijednosti ~lanstva */ void fuzzy_object_normalisation(fuzzy_object *head); /* *fill_crisp_set() puni crisp_set iz zadanih number_of_subsets koji kazuje koliko crisp_set ima podskupova, *name koji sadrzava pointer na podrucje u kojem je zapisan vektor imena (identicno kao kod *set_fill, samo sto nema imena crisp skupa), *memberships koji sadrzi pointer na podrucje gdje zapisan vektor pripadnosti subset-a crisp_set-u (0 ili 1) */ crisp_set *fill_crisp_set(int number_of_subsets, char *name, int *memberships); /* delete_crisp_set() je funkcija za brisanje pohranjenog crisp skupa */ void delete_crisp_set(crisp_set *head); /* *crisp2fuzzy(number_of_subsets, *name, *crisp_subsets) pretvara crisp skup s number_of_subsets podskupova, na kojih ukazuje *crisp_subsets i na cija imena nakon imena skupa ukazuje *name, u fuzzy */ fuzzy_object*crisp2fuzzy(char *fuzzy_object_name, int number_of_subsets, char *name, int *crisp_subsets); /* *crisp_set2fuzzy je jednaka *crisp2fuzzy samo sto je crisp skup zadan preko strukture crisp_set */ fuzzy_object *crisp_set2fuzzy(crisp_set *crisp, char *name); /* fuzzy2crisp() je suprotna od crisp2fuzzy, a vraca strukturu crisp_set koja sadrzi number_of_subsets = broj characteristic-a fuzzy set-a, te pointere *memberships i *name usmjerava na podrucje memorije koje rezervira i puni imenima characteristic-a slijedno (u *name)(oprez - ne puni s imenom fuzzy set-a), te vrijednostima clanstva (u *memberships); ako je vrijednost clanstva pojedine characteristic-e < border tada vrijednost clanstva crisp subset-a poprima vrijednost 0, dok u ostalim slucajevima poprima vrijednost 1 */ crisp_set *fuzzy2crisp(fuzzy_object *head, float border); /* fuzzy2crisp_defuzzyfication() vra}a pointer na po~etnu adresu vektora(char) s imenom klase s maksimalnom vrijednosti (ako ima vi{e klasa s tom istom vrijednosti pamti se ime prve po redu) */ char *fuzzy2crisp_defuzzyfication(fuzzy_object *head); /* *fuzzy_object_defuzzyfication() je sli~na fuzzy2crisp_defuzzyfication; s tim {to vra}a pointer na po~etnu adresu vektora(char) s imenima klasa s maksimalnom vrijednosti (ako ima vi{e klasa s tom istom vrijednosti) */ char *fuzzy_object_defuzzyfication(fuzzy_object *head); /* check_name(*name1,*name2) vra}a T=1 ako su name1 i name2 ista imena, ina~e vra}a F=0 */ enum Bool check_name(char *name1, char *name2); /* *fuzzy_AND() vra}a pointer na novi skup nastao kao presjek postoje}ih. Rezultat presjeka dvaju fuzzy skupova ne zadovoljava uvjet da je suma ~lanstava svih klasa 1. Uz pretostavku da zadani fuzzy skupovi predstavljaju distribuciju fuzzy varijable, te da je distribucija dobivena kao grafi~ki presjek zadanih distribucija dobrog oblika *fAND() vra}a kao razultat normaliziran fuzzy skup, vr{e}i normalizaciju dobivenog presjeka, u svakom slu~aju osim kada je presjek prazan skup */ fuzzy_object *fuzzy_AND(fuzzy_object *head1, fuzzy_object *head2); fuzzy_object *fAND(fuzzy_object *head1, fuzzy_object *head2); /* *fuzzy_OR() vra}a pointer na novi skup nastao kao unija postoje}ih. Rezultat unije dvaju fuzzy skupova ne zadovoljava uvjet da je suma ~lanstava svih klasa 1. Uz pretostavku da zadani fuzzy skupovi predstavljaju distribuciju fuzzy varijable, te da je distribucija dobivena kao grafi~ka unija zadanih distribucija dobrog oblika *fOR() vra}a kao razultat normaliziran fuzzy skup, vr{e}i normalizaciju dobivene unije, u svakom slu~aju osim kada je unija prazan skup, a to je samo kada su oba ulazna skupa prazni skupovi */ fuzzy_object *fuzzy_OR(fuzzy_object *head1, fuzzy_object *head2); fuzzy_object *fOR(fuzzy_object*head1, fuzzy_object*head2); /* *fuzzy_algebraic_product() vra}a pointer na novi skup nastao kao algebarski produkt postoje}ih. Rezultat algebarskog produkta dvaju fuzzy skupova je novi fuzzy skup s clanstvom kao produktom clanstava zadanih dvaju fuzzy skupova. Vrijedi *fuzzy_algebraic_product(A,B) is subset of *fuzzy_AND(A,B). */ fuzzy_object *fuzzy_algebraic_product(fuzzy_object *head1, fuzzy_object *head2); /* *fuzzy_bounded_product() vra}a pointer na novi skup nastao kao granicni produkt postoje}ih. Rezultat granicnog produkta dvaju fuzzy skupova je novi fuzzy skup s clanstvom = Max[0.0 , suma clanstava zadanih dvaju fuzzy skupova - 1.0]. Vrijedi *fuzzy_bounded_product(A,B) is subset of *fuzzy_algebraic_product(A,B). */ fuzzy_object *fuzzy_bounded_product(fuzzy_object *head1, fuzzy_object *head2); /* *fuzzy_algebraic_sum() vra}a pointer na novi skup nastao kao algebarska suma postoje}ih. Rezultat algebarske sume dvaju fuzzy skupova je novi fuzzy skup s clanstvom kao sumom clanstava zadanih dvaju fuzzy skupova umanjenim za njihov umnozak. Vrijedi *fuzzy_OR(A,B) is subset of *fuzzy_algebraic_sum(A,B). */ fuzzy_object *fuzzy_algebraic_sum(fuzzy_object *head1, fuzzy_object *head2); /* *fuzzy_bounded_sum() vra}a pointer na novi skup nastao kao granicna suma postoje}ih. Rezultat granicne sume dvaju fuzzy skupova je novi fuzzy skup s clanstvom = min[1.0 , suma clanstava zadanih dvaju fuzzy skupova]. Vrijedi *fuzzy_algebraic_sum(A,B) is subset of *fuzzy_bounded_sum(A,B). */ fuzzy_object *fuzzy_bounded_sum(fuzzy_object *head1, fuzzy_object *head2); /* *fuzzy_absolute_difference() vra}a pointer na novi skup nastao kao absolutna razlika postoje}ih (C=|A-B|). Rezultat absolutne razlike dvaju fuzzy skupova je novi fuzzy skup s clanstvom kao absolutna razlika clanstava zadanih dvaju fuzzy skupova( m(C)=|m(A)-m(B)| ). */ fuzzy_object *fuzzy_absolute_difference(fuzzy_object *head1, fuzzy_object *head2); /* *fuzzy_convex_combination() vra}a pointer na novi skup nastao kao konveksna kombinacija postoje}ih( C=(A,B,l)=l*A+(1-l)*B). Rezultat konveksne kombinacije dvaju fuzzy skupova s faktorom l je novi fuzzy skup s clanstvom kao sumom clanstva prvog fuzzy skupa pomnozenog s l i drugog fuzzy skupa pomnozenog s komplementom od l. Faktor l (u funkciji oznacen kao lambda) je realan broj iz intervala [0.0 , 1.0]. */ fuzzy_object *fuzzy_convex_combination(fuzzy_object *head1, fuzzy_object *head2, float lambda); /* *fuzzy_convex_set_combination() vra}a pointer na novi skup nastao kao konveksna kombinacija postoje}ih( C=(A,B,C)=C*A+(1-C)*B). Za razliku od *fuzzy_convex_combination() sada je l->C fuzzy skup. Rezultat konveksne kombinacije dvaju fuzzy skupova s fuzzy skupom l je novi fuzzy skup s clanstvom kao sumom clanstva prvog fuzzy skupa pomnozenog s clanstvom treceg fuzzy skupa i drugog fuzzy skupa pomnozenog s komplementom od clanstva treceg fuzzy skupa. */ fuzzy_object *fuzzy_convex_set_combination(fuzzy_object *head1, fuzzy_object *head2, fuzzy_object *head3); /* fset_equall() vra}a T ako fuzzy skupovi na koje ukazuju pointeri imaju iste klase s istim nazivima (ne ispituju se vrijednosti ~lanstva, a redoslijed klasa nije bitan), a F ako nemaju */ enum Bool fset_equall_set(fuzzy_object *head1, fuzzy_object *head2); /* f_equall() vra}a T ako su fuzzy skupovi na koje ukazuju pointeri jednaki (isti nazivi klasa i vrijednosti ~lanstva, a redoslijed klasa nije bitan), a F ako nisu */ enum Bool f_equall(fuzzy_object *head1, fuzzy_object *head2); /* f_equall_epsilon() vra}a T ako fuzzy skupovi na koje ukazuju pointeri imaju iste nazive klasa, a vrijednosti ~lanstva istoimenih klasa se razlikuju za manje ili jednako epsilon, dok redoslijed klasa nije bitan, ina~e vra}a F */ enum Bool f_equall_epsilon(fuzzy_object *head1, fuzzy_object *head2, float epsilon); /* f_sum_membership() daje sumu svih vrijednosti ~lanstva fuzzy skupa */ float f_sum_membership(fuzzy_object *head); /* fsubsethood() vra}a vrijednost koja pokazuje koliko je 1. fuzzy skup podskup 2. po formuli S(A,B)=((~lanstva(fuzzy_AND(A,B)))/(~lanstva(A)) . Podskupnost A u B se mo`e promatrati i kao mjera uvjetovanja B od strane A. */ float fsubsethood(fuzzy_object *head1, fuzzy_object *head2); /* divergence() racuna divergenciju dvaju fuzzy skupova po formuli (16) iz Magisterija */ double divergence(fuzzy_object *head1, fuzzy_object *head2); /* entropy_DeLuceTermini() racuna entropiju fuzzy skupa po formuli ((17) iz Magisterija) De Luce i Terminia analogno informacijskoj teoretskoj entropiji */ double entropy_DeLuceTermini(fuzzy_object *head); /* crisp_set *make_inverse() pravi inverzni crisp_set od zadanog crisp_set-a */ crisp_set *make_inverse(crisp_set *head); /* *inversing() pravi inverzni fuzzy_object od zadanog fuzzy_object-a */ fuzzy_object *inversing(fuzzy_object *head); /* entropy_using_divergence() racuna entropiju fuzzy skupa preko divergencije po formuli (20) iz Magisterija */ double entropy_using_divergence(fuzzy_object *head); /* fuzzy_integral_Sugeno returnes value of Sugeno's fuzzy integral for given number_of_evaluation_items of items stored in items[number_of_evaluation_items][2], where *(*(items+i)+j) is (j=0 ==> value; j=1 ==> confidence of that item evaluation (method)) for (i-1)-th item; lambda is Sugeno's lambda defined: g(A+B)=g(A)+g(B)+lambda*g(A)*g(B), where (A+B) means A union B, lambda>-1 and lambda<>0 */ /* lambda must satisfy lambda+1=product_over_all_items(1+lambda*item's_(evaluation_method)_confidence), lambda>-1, lambda<>0 */ /* confidences of item evaluation (method) must satisfy (Sugeno's) fuzzy measure properties */ /* values (stored in items) must satisfy the properties of fuzzy measure */ float fuzzy_integral_Sugeno(int number_of_evaluation_items, float lambda, float **items); extern float max_lambda; /* maximal value to be checked in calculating_lambda() and calculating_positive_lambda() (if the function doesn't changes signum from initial point (setup later as lambda) through check points (defined later with step) until the end than it is assumed that there is no solution for lambda) */ /* if all values could happen to be very close to 0.0 end could required to be increased (in the case of 27 values of 0.01 end should be 1000) */ /* lambda is defined through Sugeno's fuzzy measure and must be >-1 and <>0 */ /* lambda is calculated to make true lambda + 1 = product_over_all_confidences(1 + lambda * confidence) , where "=" means equal within an error < epsilon */ /* confidences must preserve the properties of fuzzy measure */ float calculating_lambda(float *confidences, int number_of_confidences); /* lambda is defined through Sugeno's fuzzy measure and must be >-1 and <>0 */ /* lambda is calculated to make true lambda + 1 = product_over_all_confidences(1 + lambda * confidence) , where "=" means equal within an error < epsilon */ /* lambda is forced to be positive */ /* confidences must preserve the properties of fuzzy measure */ float calculating_positive_lambda(float *confidences, int number_of_confidences); /* struct time_slice consists informations about fuzzy_BP_through_time for a particular system (enables us to deal with several systems at time). "f_s" points to fuzzy system, "dimension" presents number of characteristics in the system, "o" is total number of objects in the system, "nout" is the number of output characteristics (characteristics whose output we compare and they must be at the end of f_s), "counter" counts time slices,"Wpast" presents time dimension of W (for example Wpast=3 means *(W+0) presents actual influences, *(W+1) influence from previous time slice on actual one and *(W+2) from two slice ago on actual one), "W" is pointer to vectors of characteristic influences: *(W+0) in actual time, *(W+1) from previous time slice on actual time slice, ... , *(W+i) from i-1 time slice on actual one, ... , *(W+Wpast-1) from Wpast-2 time slice on actual one; "BPm" is pointer to vector of pointers to BPmemory fir particular time slice, "x" is pointer to vector of pointers on vector of characteristic values per particular time slice, "D_w" is pointer to vector of weight corrections. */ typedef struct time_slice { fuzzy_object **f_s; int dimension; int o; int nout; int counter; int Wpast; float **W; float **BPm; float **x; float *D_w; } time_slice; time_slice* MATS(long int number_of_elements); time_slice** MApTS(long int number_of_elements); time_slice*** MAppTS(long int number_of_elements); time_slice**** MApppTS(long int number_of_elements); /* time_slice *setup_fuzzy_batchBP(fuzzy_object *f_s[], int o, int nout, float *W) forms time_slice for given system and reserve memory area for saving F_w(i,j) for each weight. After all patterns are presented new weight(i,j) = weight(i,j) - learning_rate * F_w(i,j). It is to be called only once for each fuzzy_batchBackpropagation algorithm applying (only for batchBP but not BP) and it must be called before first time calling of fuzzy_batchBP! */ time_slice *setup_fuzzy_batchBP(fuzzy_object *f_s[], int o, int nout, float *W); /* void delete_fuzzy_batchBP(time_slice *T) delete time_slice for given system and free memory area reserved for saving F_w(i,j) for each weight. It should be run when we finish with backpropagation algorithm based learning of the neural network */ void delete_fuzzy_batchBP(time_slice *T); /* void fuzzy_system_run(time_slice *T) calculates one (iteration of) propagation of system input through system variables (over weights) to system output */ void fuzzy_system_run(time_slice *T); /* void fuzzy_system_run_selected(time_slice *T, int n) is similar to fuzzy_system_run() with the difference that 'n' presents first object whose characteristics are calculated over influences of previous objects. For example (let o=4) n=3 means T->f_s+2 (third object) and T->f_s+3 (forth object) characteristics will be calculated over influences of previous objects. */ void fuzzy_system_run_selected(time_slice *T, int n); /* void fuzzy_system_run_layers(time_slice *T, int v) is similar to fuzzy_system_run_selected() with the difference that 'v' presents number of state variables and characteristics are calculated over influences of previous levels (first level are input and state variables for the actual interval, second layer are state variables for the next interval, while third layer is output). It means output (of the next interval) is calculated only over the state variables of the next interval. */ void fuzzy_system_run_layers(time_slice *T, int v); /* void fuzzy_batchBP(time_slice *T, float *expected_output, float *S) calculates influence corrections after each input-output observing. Influences between characteristics can be calculated for each time slice before calling function fuzzy_batchBP() and stored in vector (matrix) pointed by *(T->W) (influence from characteristic i to characteristic j is stored in location *(*(T->W)+(i-1)*T->dimension+(j-1)). It must be called after each input-output is observed. */ void fuzzy_batchBP(time_slice *T, float *expected_output, float *S); /* void fuzzy_batchBP_adapting_influences(time_slice *T, float correction_weight) is function, that is to be run after whole set of system observing, that corrects all influents according T->D_w. Note T->D_w is at the end reset to 0.0 so new circle of observing (the same system) can start. correction_weight is constant of correcting of influences. It should be small and made as large as possible up to 1.0, until error starts to diverge. */ void fuzzy_batchBP_adapting_influences(time_slice *T, float correction_weight); /* void fuzzy_BP(fuzzy_object *f_s[],int o, int nout, float *expected_output, float *W, float *S, float correction_weight) changes influence (forward) between characteristics according to BackPropagation algorithm (Werbos " Propagation throught time", Proceedings of the IEEE, Vol. 78, No. 10, October 1990). Other BP variations can be used simple changing function "void fuzzy_batchBP_adapting_influences" whose main expression can be viewed as New w(i,j) = w(i,j) - correction_weight * (dE/dw(i,j)). */ void fuzzy_BP(fuzzy_object *f_s[], int o, int nout, float *expected_output, float *W, float *S, float correction_weight); /* time_slice *start_fuzzy_BP_through_time(fuzzy_object *f_s[], int o, int nout, float **W, int Wpast) reserve memory area for saving time_slice data for the system. After all patterns are presented new weight(i,j) = weight(i,j) - learning_rate * F_w(i,j). It is to be called only once for each fuzzy_BP_through_time algorithm applying and it must be called before first time calling of fuzzy_BP_through_time! */ time_slice *start_fuzzy_BP_through_time(fuzzy_object *f_s[], int o, int nout, float **W, int Wpast); /* void delete_fuzzy_batchBP_through_time(time_slice *T) free memory area reserved for saving time_slice. It should be run when we finish with backpropagation through time algorithm based learning of the neural network */ void delete_fuzzy_batchBP_through_time(time_slice *T); /* void fuzzy_BP_through_time(time_slice *T, float *expected_output, float *S) calculates influence corrections after each input-output observing. It must be called after each input-output is observed. */ void fuzzy_BP_through_time(time_slice *T, float *expected_output, float *S); /* void fuzzy_BP_through_time_adapting_influences(time_slice *T, float correction_weight) is function, that is to be run after whole set of system observing, that corrects all influents according T->D_w. Note T->D_w is at the end reset to 0.0 so new circle of observing (the same system) can start. correction_weight is constant of correcting of influences. It should be small and made as large as possible up to 1.0, until error starts to diverge. */ void fuzzy_BP_through_time_adapting_influences(time_slice *T, float correction_weight); /* float Gauss(float m, float s, float x) calculates value of Gauss function (m=average value, s=distorsion) for (input value) x */ float Gauss(float m, float s, float x); #ifdef __cplusplus } #endif #endif /* All comments on this library are welcome. Feel free to contact author if there is anything you would like or you need to be added or anything you suggest to change. This library is for use only in education and research. It is not for commercial use! Written permission from author is necessary for commercial use or for inclusion as a part of project or program or another library! Programs, projects, libraries or anything consists this library or its part MUST NOT be sold without author permission! Author: Dekovich Igor, ph: (-61) (2) 4225 2673, mobile: (-61) 042 189 69 84 e-mail: idekovich@yahoo.com */ /* Split 1994 & Auckland 1995 */ /* Auckland 4/4/1995 */ /* last revision 20/10/1997 */