/* Uczenie pejedynczego neuronu
 * Neutrinka 
*/

#include <stdio.h>
struct neuron {
    float x[1000];
    float w[1000];
    float y;
    float D;
};

struct neuron neu;

int main(void) {
    int i, ii;
    char c;
    float ni;
    float e = 0;
    int max = 10;
    
    /* losowanie wag */
    neu.w[0] = 2;
    neu.w[1] = 1;
    
    /* wspulczynnik uczenia ni
    *  im mniejszy tym wolniej sie uczy.. ale dokladniej :)
    */
    
    ni = 1.0/100000.0;
	
    do {
	/* sumaryczny blad sieci zerowany */
	e = 0;

	/* co 10 przebiegow sprawdzaj blad sumaryczny */
	for( ii = 0; ii < 10; ii++) {
	    for( i = 0; i < max; i++ )
		neu.x[i] = rand()%100;	// losowanie wejsc :)
	
	    /* zerowane wyjscie i oczekiwana odpowiedz */
	    neu.y = 0;
	    neu.D = 0;

	    /* Nauczyciel mowi, ze... Funkcja uczaca jest rowna... tyle i tyle
	    + - dla wielu neuronow tez :)
	    Tutaj zmieniasz sobie funkcje na inne :) */	
	    
	    for( i = 0; i < max; i++ )
		neu.D += neu.x[i];
	
	    /* obliczanie odpowiedzi sieci */
	    for( i = 0; i < max; i++ )
		neu.y += ( neu.x[i] * neu.w[i] );

	    printf( "(Y=%f)\n", neu.y );
	
	    printf( "Ale.. Nauczyciel mowi ze Y = %f\n", neu.D );

	    /* poprawki */
    	    for( i = 0; i < max; i++ )
		neu.w[i] = neu.w[i] + ( (0.5 * ni * (neu.D-neu.y) * neu.x[i]) );
	
	    printf( "w[0] = %f, w[1] = %f\n", neu.w[0], neu.w[1]);
	
	    /* blad sumaryczny */
	    e += 0.5 * (neu.D-neu.y)*(neu.D-neu.y);
	}
	printf("Blad sieci = %f\n", e);
    }
    /* az nie bedzie mniejszy blad niz chcemy */
    while( e > 0.1 );
    
    return 0;
}
