mancpato_PuntosRNA/PuntosPDE.pde
/* 
    Perceptrón simple
    
    Programa de ejemplo de Redes Neuronales Artificiales.
    Clasificador lineal simple.
    
    Miguel Angel Norzagaray Cosío
    UABCS/DSC
*/

/// Neuronas por capa
int  N = 2;     // entradas x[i]
int  H = 4;     // capa oculta
int  K = 3;     // salidas y[i]

int MAX_PUNTOS = 45;

float Alfa = 0.1;  // Tasa de aprendizaje

float[] x;      // Coordenadas de cada punto
float[] y;      // Pertenencia a cada clase

Punto[] Puntos = new Punto[MAX_PUNTOS];
Punto Clase1 = new Punto(100,300,1);
Punto Clase2 = new Punto(300,300,2);
Punto Clase3 = new Punto(300,100,3);

int RojosOk, VerdesOk, AzulesOk;

int[] ClaseCorrecta;

RNA Cerebro;

void setup()
{
  size(400,400);
  textSize(16);
  
  Cerebro = new RNA(N, H, K, Alfa);
  x = new float[N];
  y = new float[K];
  ClaseCorrecta = new int[3];
  
  for ( int i=0 ; i<Puntos.length ; i++ )
    Puntos[i] = new Punto(0, 0);
  
  println("Red neuronal para clasificar puntos");
  println("Programa de ejemplo para la asignatura RNA");
  println("DASC/UABCS, manc");
}

void draw()
{
  background(200);
  noFill();
  strokeWeight(3);
  stroke(255, 0, 0); ellipse(100,300,180,180);
  stroke(0, 255, 0); ellipse(300,300,180,180);
  stroke(0, 0, 255); ellipse(300,100,180,180);
  
  // Puntos para entrenamiento, generados cada época
  int DisTrain = 60;
  for ( int i=0 ; i<Puntos.length ; i += 3 ) {
    Puntos[i].x = 100+random(-DisTrain,DisTrain); 
    Puntos[i].y = 300+random(-DisTrain,DisTrain);
    Puntos[i+1].x = 300+random(-DisTrain,DisTrain); 
    Puntos[i+1].y = 300+random(-DisTrain,DisTrain);
    Puntos[i+2].x = 300+random(-DisTrain,DisTrain); 
    Puntos[i+2].y = 100+random(-DisTrain,DisTrain);
  }
  
  RojosOk = VerdesOk = AzulesOk = 0;
  for ( Punto p : Puntos ) {
      x[0] = p.x/width;
      x[1] = p.y/width;
      p.Pintar();
      
      ClaseCorrecta[0] = 0;
      ClaseCorrecta[1] = 0;
      ClaseCorrecta[2] = 0;
      if ( dist(p.x,p.y,Clase1.x,Clase1.y)<DisTrain ) //<>//
          ClaseCorrecta[0] = 1;
      else if ( dist(p.x,p.y,Clase2.x,Clase2.y)<DisTrain )
          ClaseCorrecta[1] = 1;
      else if ( dist(p.x,p.y,Clase3.x,Clase3.y)<DisTrain )
          ClaseCorrecta[2] = 1;
          
      Cerebro.Entrenar(x, ClaseCorrecta);
      
      p.Tipo = DeterminarTipo();
      p.Pintar();
  }
  
  fill(255, 0, 0);
  float MaxTasaRojos = 100*float(3*RojosOk)/MAX_PUNTOS;
  text(str(MaxTasaRojos)+"%",25,210);
  fill(50, 200, 50);
  float MaxTasaVerdes = 100*float(3*VerdesOk)/MAX_PUNTOS;
  text(str(MaxTasaVerdes)+"%",180,220);
  fill(0, 0, 255); 
  float MaxTasaAzules = 100*float(3*AzulesOk)/MAX_PUNTOS;
  text(str(MaxTasaAzules)+"%",180,20);
  
  if ( MaxTasaRojos>90 && MaxTasaVerdes>90 && MaxTasaAzules>90 )
      println("Perfecto en frame "+frameCount);
  //delay(250);

  //if ( frameCount%100 == 0 )
  //  noLoop();
}

int DeterminarTipo()
{
  int Tipo=0;
  if ( y[0] == 1 && y[1] == 0 && y[2] == 0 ) {
    Tipo = 1;
    RojosOk++;
  } else if ( y[0] == 0 && y[1] == 1 && y[2] == 0 ) {
    Tipo = 2;
    VerdesOk++;
  } else if ( y[0] == 0 && y[1] == 0 && y[2] == 1 ) {
    Tipo = 3;
    AzulesOk++;
  } else
    Tipo = 0;
  return Tipo;
}

void mousePressed()
{
  print(frameCount+" ");
  noLoop();
}

void mouseReleased()
{
  loop();
}

void keyPressed() 
{
  if ( key == 'p'  ||  key == 'p' ) {
    Cerebro.MostrarPesos();
    noLoop();
  }
}
