fuzzy is set of structures and functions written to enable easier
manipulation with fuzzy sets in programming language C.
5) Each characteristic value, except finite number of characteristics of
objects in input fuzzy set, v(i) can be presented v(i)=f(i)(sum(w(i,j)*v(j)),j=1,...,i-1).
f(i)' is vector of derivations of f(i). f(i)'=df(i)/d(sum(w(i,j)*v(j)),j=1,...,i-1).
f(i)' is presented as vector of real numbers calculated for the moment
of observation with dimension=number_of_all_characteristics_in_the_fuzzy_system.
For characteristics observed as input f(i)'=0.0.
6) BP algorithm changes value of influence of one characteristic to
another by calculating dOutput_error/dW(i,j) in fuzzy_batchBP and adding
to F_w(i,j) (called also D_w(i,j)) in order to calculate SUM(dOutput_error/dW(i,j))
throught all time slices inside the period (time between calling adapting_fuzzy_influence())
used in adapting_fuzzy_influence().
For fuzzy_batchBP, fuzzyBP and fuzzy_BP_through_time following sintax
is used:
I) 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;
______________________}
consists informations about fuzzy_(batch)BP(_through_time) for a particular
system (enables us to deal with several systems at time).
a) **f_s presents vector f_s[o]. Vector f_s consists pointers on first
objects from input fuzzy set, than from other fuzzy sets with respect to
propagation of their influence, and at the end objects from output fuzzy
set (if input and output fuzzy sets are the same one and there is no sets
or objects between them, than consists only pointer on one fuzzy set's
objects - it means no duplication) whose characteristic-influence is described
over matrix W.
b) dimension presents number of characteristics in the system. It is
automatically calculated.
c) o is total number of objects in the system.
d) nout is the number of output characteristics in the system (characteristics
whose output we compare and they must be at the end of f_s).
e) counter counts time slices (for use in fuzzy_BP_through_time). It
is automatically set up and calculated.
f) Wpast presents time dimension of W for use in fuzzy_BP_through_time
(in other cases it is 0) (for example Wpast=3 means *(W+0) presents actual
influences, *(W+1) influence from previous time slice on actuall one and
*(W+2) from two slice ago on actual one).
g) **W is pointer to vectors of characteristic influences: *(W+0) in
actuall 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. Except in fuzzy_BP_through_time only *(W+0) exists
and points on vector (*(W+0))[dimension,dimension] with elements (*(W+0))(i,j)
presenting influence of j-th characteristic in the system on i-th one.
(*(W+0))(i,j)=0.0 for all i
h) **BPm is pointer to vector of pointers to BPmemory fpr particular time
slice. It is for internall use and is calculated automatically.
i) **x is pointer to vector of pointers on vector of characteristic
values per particular time slice. It is for internall use and is calculated
automatically.
j) *D_w is pointer to vector of weight corrections. It is calculated
automatically.
II) expected_output[nout] is vector of expected output characteristics
values respectly (their objects are in order as they are in f_s vector,
while characteristics are in order as they are inside objects).
III) S[o] is vector f'(i)(t) present derivation of function presents
all characteristics influence on present characteristic with respect to
sum of all characteristics influence. It should be calculated and presented
as real number each time before calling fuzzy_(batch)BP(_through_time).
IV) 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.
Functions inside library "fuzzy" are:
1) 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! */
2) 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 */
3) 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. */
4) 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. */
5) 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)). */
6) 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! */
7) 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
*/
8) 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. */
9) 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. */
Projects and compiling:
Function math.c (math.h) from ANSI library must be included if the library
is a part of a project.
UNIX: during compilation option "-lm" must be used!
EXAMPLE of using functions
#include <stdio.h>
#include "fuzzy1.h"
main()
{
char name1[8]={'A',' ','1',' ','2',' ','3',' '}, name2[8]={'B','
','1',' ','2',' ','4',' '}, name3[10]={'C',' ','1',' ','2',' ','3',' ','4','
'}, name4[6]={'1',' ','2',' ','4',' '}, name5[2]={'D',' '}, name6[2]={'E','
'}, name7[8]={'1',' ','2',' ','3',' ','4',' '}, *n;
float membership1[3]={0.3,0.7,0.2}, membership2[3]={0.4,0.3,0.6},
membership3[4]={0.1,0.8,0.2,0.1};
int membership4[4]={0,1,0,1};
int counter;
fuzzy_object *s1, *s2, *s3,*s4, *s5, *s6, *s7, *s8, *s11, *s12,
*s13, *s14, *s15, *s16, *s17;
crisp_set *c1, *c2, *c3, *c4;
s1=set_fill(3,name1,membership1);
s2=set_fill(3,name2,membership2);
s3=set_fill(4,name3,membership3);
s4=fAND(s1,s2);
s5=fuzzy_OR(s2,s3);
c4=fill_crisp_set(3,name4,membership4);
s7=crisp_set2fuzzy(c4,name5);
s8=crisp2fuzzy(name6,4,name7,membership4);
s11=fuzzy_algebraic_product(s1,s2);
s12=fuzzy_bounded_product(s1,s2);
s13=fuzzy_algebraic_sum(s1,s2);
s14=fuzzy_bounded_sum(s1,s2);
s15=fuzzy_absolute_difference(s1,s2);
s16=fuzzy_convex_combination(s1,s2,0.3);
s17=fuzzy_convex_set_combination(s1,s2,s3);
c1=fuzzy2crisp(s4,0.5);
c2=fuzzy2crisp(s2,0.33);
c3=make_inverse(c2);
s6=inversing(s5);
printf("\n s1");
set_read(s1,name3,membership2);
printf("\n set name is %c%c",name3[0],(name3[1]));
for(counter=1; counter<=s1->number_of_characteristics; counter++)
printf("\n characteristic name is %c%c; membership is %f",name3[2*counter],name3[2*counter+1],
membership2[counter-1]);
printf("\n s2");
printf("\n set name is %c%c",*(s2->m.name),*(s2->m.name+1));
for(s2->actuall=s2->first; s2->actuall!=0; s2->actuall=s2->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s2->actuall->name),*(s2->actuall->name+1),
s2->actuall->membership);
printf("\n s3");
printf("\n set name is %c%c",*(s3->m.name),*(s3->m.name+1));
for(s3->actuall=s3->first; s3->actuall!=0; s3->actuall=s3->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s3->actuall->name),*(s3->actuall->name+1),
s3->actuall->membership);
printf("\n s4");
printf("\n set name is %c%c%c%c%c%c%c%c",*(s4->m.name),*(s4->m.name+1),*(s4->m.name+2),*(s4->m.name+3),*(s4->m.name+4),*(s4->m.name+5),*(s4->m.name+6),*(s4->m.name+7));
for(s4->actuall=s4->first; s4->actuall!=0; s4->actuall=s4->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s4->actuall->name),*(s4->actuall->name+1),
s4->actuall->membership);
n=fuzzy2crisp_defuzzyfication(s4);
printf("\n-->Characteristic %c%c has the highest membership",*(n),*(n+1));
n=fuzzy_object _defuzzyfication(s4);
printf("\n-->The highest membership have characteristics:");
do
{ printf(" %c%c;",*(n),*(n+1));
n+=2;
}
while(*n!='#');
printf("\n s5");
printf("\n set name is %c%c%c%c%c%c%c",*(s5->m.name),*(s5->m.name+1),*(s5->m.name+2),*(s5->m.name+3),*(s5->m.name+4),*(s5->m.name+5),*(s5->m.name+6));
for(s5->actuall=s5->first; s5->actuall!=0; s5->actuall=s5->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s5->actuall->name),*(s5->actuall->name+1),
s5->actuall->membership);
printf("\n s6");
printf("\n set name is %c%c%c%c%c%c%c",*(s6->m.name),*(s6->m.name+1),*(s6->m.name+2),*(s6->m.name+3),*(s6->m.name+4),*(s6->m.name+5),*(s6->m.name+6));
for(s6->actuall=s6->first; s6->actuall!=0; s6->actuall=s6->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s6->actuall->name),*(s6->actuall->name+1),
s6->actuall->membership);
printf("\n s7");
printf("\n set name is %c%c",*(s7->m.name),*(s7->m.name+1));
for(s7->actuall=s7->first; s7->actuall!=0; s7->actuall=s7->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s7->actuall->name),*(s7->actuall->name+1),
s7->actuall->membership);
printf("\n s8");
printf("\n set name is %c%c",*(s8->m.name),*(s8->m.name+1));
for(s8->actuall=s8->first; s8->actuall!=0; s8->actuall=s8->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s8->actuall->name),*(s8->actuall->name+1),
s8->actuall->membership);
printf("\n s11");
printf("\n set name is %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",*(s11->m.name),*(s11->m.name+1),*(s11->m.name+2),*(s11->m.name+3),*(s11->m.name+4),*(s11->m.name+5),*(s11->m.name+6),*(s11->m.name+7),*(s11->m.name+8),*(s11->m.name+9),*(s11->m.name+10),*(s11->m.name+11),*(s11->m.name+12),*(s11->m.name+13),*(s11->m.name+14),*(s11->m.name+15),*(s11->m.name+16),*(s11->m.name+17),*(s11->m.name+18),*(s11->m.name+19),*(s11->m.name+20),*(s11->m.name+21));
for(s11->actuall=s11->first; s11->actuall!=0; s11->actuall=s11->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s11->actuall->name),*(s11->actuall->name+1),
s11->actuall->membership);
printf("\n s12");
printf("\n set name is %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",*(s12->m.name),*(s12->m.name+1),*(s12->m.name+2),*(s12->m.name+3),*(s12->m.name+4),*(s12->m.name+5),*(s12->m.name+6),*(s12->m.name+7),*(s12->m.name+8),*(s12->m.name+9),*(s12->m.name+10),*(s12->m.name+11),*(s12->m.name+12),*(s12->m.name+13),*(s12->m.name+14),*(s12->m.name+15),*(s12->m.name+16),*(s12->m.name+17),*(s12->m.name+18),*(s12->m.name+19));
for(s12->actuall=s12->first; s12->actuall!=0; s12->actuall=s12->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s12->actuall->name),*(s12->actuall->name+1),
s12->actuall->membership);
printf("\n s13");
printf("\n set name is %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",*(s13->m.name),*(s13->m.name+1),*(s13->m.name+2),*(s13->m.name+3),*(s13->m.name+4),*(s13->m.name+5),*(s13->m.name+6),*(s13->m.name+7),*(s13->m.name+8),*(s13->m.name+9),*(s13->m.name+10),*(s13->m.name+11),*(s13->m.name+12),*(s13->m.name+13),*(s13->m.name+14),*(s13->m.name+15),*(s13->m.name+16),*(s13->m.name+17));
for(s13->actuall=s13->first; s13->actuall!=0; s13->actuall=s13->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s13->actuall->name),*(s13->actuall->name+1),
s13->actuall->membership);
printf("\n s14");
printf("\n set name is %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",*(s14->m.name),*(s14->m.name+1),*(s14->m.name+2),*(s14->m.name+3),*(s14->m.name+4),*(s14->m.name+5),*(s14->m.name+6),*(s14->m.name+7),*(s14->m.name+8),*(s14->m.name+9),*(s14->m.name+10),*(s14->m.name+11),*(s14->m.name+12),*(s14->m.name+13),*(s14->m.name+14),*(s14->m.name+15));
for(s14->actuall=s14->first; s14->actuall!=0; s14->actuall=s14->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s14->actuall->name),*(s14->actuall->name+1),
s14->actuall->membership);
printf("\n s15");
printf("\n set name is %c%c%c%c%c%c",*(s15->m.name),*(s15->m.name+1),*(s15->m.name+2),*(s15->m.name+3),*(s15->m.name+4),*(s15->m.name+5));
for(s15->actuall=s15->first; s15->actuall!=0; s15->actuall=s15->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s15->actuall->name),*(s15->actuall->name+1),
s15->actuall->membership);
printf("\n s16");
printf("\n set name is %c%c%c%c%c%c%c",*(s16->m.name),*(s16->m.name+1),*(s16->m.name+2),*(s16->m.name+3),*(s16->m.name+4),*(s16->m.name+5),*(s16->m.name+6));
for(s16->actuall=s16->first; s16->actuall!=0; s16->actuall=s16->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s16->actuall->name),*(s16->actuall->name+1),
s16->actuall->membership);
printf("\n s17");
printf("\n set name is %c%c%c%c%c%c%c",*(s17->m.name),*(s17->m.name+1),*(s17->m.name+2),*(s17->m.name+3),*(s17->m.name+4),*(s17->m.name+5),*(s17->m.name+6));
for(s17->actuall=s17->first; s17->actuall!=0; s17->actuall=s17->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s17->actuall->name),*(s17->actuall->name+1),
s17->actuall->membership);
printf("\n\n c1");
for(counter=0; counter<c1->number_of_subsets; counter++)
printf("\n subset name is %c%c; membership is %d",*(c1->name+counter*2),*(c1->name+counter*2+1),
*(c1->memberships+counter));
printf("\n c2");
for(counter=0; counter<c2->number_of_subsets; counter++)
printf("\n subset name is %c%c; membership is %d",*(c2->name+counter*2),*(c2->name+counter*2+1),
*(c2->memberships+counter));
printf("\n c3");
for(counter=0; counter<c3->number_of_subsets; counter++)
printf("\n subset name is %c%c; membership is %d",*(c3->name+counter*2),*(c3->name+counter*2+1),
*(c3->memberships+counter));
printf("\n c4");
for(counter=0; counter<c4->number_of_subsets; counter++)
printf("\n subset name is %c%c; membership is %d",*(c4->name+counter*2),*(c4->name+counter*2+1),
*(c4->memberships+counter));
fill_set(s2,name1,membership1);
printf("\n New s2");
printf("\n set name is %c%c",*(s2->m.name),*(s2->m.name+1));
for(s2->actuall=s2->first; s2->actuall!=0; s2->actuall=s2->actuall->follow)
printf("\n characteristic name is %c%c; membership is %f",*(s2->actuall->name),*(s2->actuall->name+1),
s2->actuall->membership);
printf("\n Set s3 has");
if(fset_equall_set(s3,s4)==F) printf("n't");
printf(" the same characteristics as s4 !");
printf("\n Sets s3 and s4 are");
if(f_equall(s3,s4)==F) printf("n't");
printf(" identical !");
printf("\n Sets s3 and s4 are");
if(f_equall_epsilon(s3,s4,0.3)==F) printf("n't");
printf(" identical inside noise of 0.3!");
printf("\n Set s3 is subset of s4 with %f",fsubsethood(s3,s4));
printf("\n Set s4 is subset of s3 with %f",fsubsethood(s4,s3));
printf("\n Divergence between s3 and s4 is %f",divergence(s4,s3));
printf("\n Entropy (De Luce & Termini) of s3 is %f",entropy_DeLuceTermini(s3));
printf("\n Entropy (over divergence) of s3 is %f",entropy_using_divergence(s3));
printf("\n Sum of memberships of all characteristics of s3 is");
if(fuzzy_check_sum(s3,0.001)==F) printf("n't");
printf(" equall 1.0+/-0.001");
printf("\n Each membership of s3 is");
if(fuzzy_check_membership(s3)==F) printf("n't");
printf(" element of R[0,1]");
switch(fuzzy_object _check(s3,0.001))
{
case Y: printf("\n Sum of memberships of all characteristics
of s3 is 1.0 +/- 0.001, and each membership is from R[0,1]");
break;
case S: printf("\n Sum of memberships of all characteristics
of s3 is >1.001 or <0.999, while each membership is from R[0,1]");
break;
case M: printf("\n Sum of memberships of all characteristics
of s3 is1.0 +/- 0.001, while there is membership out of interval R[0,1]");
break;
case ALL: printf("\n Sum of memberships of all characteristics
of s3 is>1.001 or <0.999, and there is membership out of interval R[0,1]");
break;
};
delete_fuzzy_object (s1);
delete_fuzzy_object (s2);
delete_fuzzy_object (s3);
delete_fuzzy_object (s4);
delete_fuzzy_object (s5);
delete_fuzzy_object (s6);
delete_fuzzy_object (s7);
delete_crisp_set(c1);
delete_crisp_set(c2);
delete_crisp_set(c3);
delete_crisp_set(c4);
}
Read it
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: Igor Dekovich
ph: (-61) (2) 4225 2673
mobile: (-61) 042 189 69 84
e-mail: idekovich@yahoo.com
Auckland, 4/4/1995
revised 22/11/1995