extras; samples: Fixed warnings
[sdk] / samples / eC / neural / neurons.ec
1 import "ecere"
2
3 struct Synapse
4 {
5    double weight;
6    Neuron * dendron;
7    Neuron * axon;
8 };
9
10 enum NeuronState
11 {
12    CLEARED,
13    ACTIVATED,
14    PROPAGATED,
15    TAUGHT
16 };
17
18 struct SynapsePtr
19 {
20    Synapse * ptr; // TOFIX: Support pointers in generic types
21 };
22
23 static double Sigmoid(double x)
24 {
25    return 1 / (1 + exp(-x));
26 }
27
28 static double SigmoidDerivative(double x)
29 {
30    return x * (1 - x);
31 }
32
33 double GetRandDouble(double lo, double hi)
34 {
35    return GetRandom((int)(lo * 1000000000), (int)(hi * 1000000000)) / 1000000000.0;
36 }
37
38 struct Neuron
39 {
40    double bias;
41    Array<Synapse> axons;
42    Array<SynapsePtr> dendrons;
43    double activation;
44    double error;
45    NeuronState state;
46
47    void Init()
48    {
49       axons = { };
50       dendrons = { };
51    }
52
53    void Unactivate()
54    {
55       int c;
56       for(c = 0; c<dendrons.size; c++)
57       {
58          Synapse * synapse = dendrons[c].ptr;
59          if(synapse->dendron->state != CLEARED)
60             synapse->dendron->Unactivate();
61       }
62       state = CLEARED;
63    }
64
65    void Activate()
66    {
67       if(dendrons.size)
68       {
69          int c;
70          activation = bias;
71          for(c = 0; c<dendrons.size; c++)
72          {
73             Synapse * synapse = dendrons[c].ptr;
74             if(synapse->dendron->state != ACTIVATED)
75                synapse->dendron->Activate();
76             activation += synapse->dendron->activation * synapse->weight;
77          }
78          activation = Sigmoid(activation);
79       }
80       state = ACTIVATED;
81    }
82
83    void BackPropagate()
84    {
85       int c;
86       if(axons.size)
87       {
88          error = 0;
89          for(c = 0; c<axons.size; c++)
90          {
91             Synapse * synapse = &axons[c];
92             if(synapse->axon->state != PROPAGATED)
93                synapse->axon->BackPropagate();
94             error += synapse->axon->error * synapse->weight;
95          }
96       }
97       error *= SigmoidDerivative(activation);
98       state = PROPAGATED;
99    }
100
101    void Teach(double learnRate)
102    {
103       int c;
104       if(dendrons.size)
105       {
106          for(c = 0; c<dendrons.size; c++)
107          {
108             Synapse * synapse = dendrons[c].ptr;
109             if(state != TAUGHT)
110                synapse->dendron->Teach(learnRate);
111             synapse->weight += learnRate * error * synapse->dendron->activation;
112          }
113          bias += learnRate * error;
114       }
115       state = TAUGHT;
116    }
117 };
118
119 int Neuron_Winner(Neuron * neurons, int count)
120 {
121    double bestActivation = -MAXDOUBLE;
122    int c, best;
123    for(c = 0; c<count; c++)
124    {
125       if(neurons[c].activation > bestActivation)
126       {
127          best = c;
128          bestActivation = neurons[c].activation;
129       }
130    }
131    return best;
132 }