// 
// File name: RecognitionNet.h
//
// Discription: Base classes
//
// Programmer: Vladimir P. Stasevich (SV)
//
// History: 
//    Created 12.02.2000 (SV)
//

#include <math.h>
#pragma hdrstop

#include "neuro.h"
#include "RecognitionNet.h"

TImageSituation imgOut[JAMMINGSITUATION + 1] = 
{
   {{ 0.5, -0.5, -0.5, -0.5, -0.5}},
   {{-0.5,  0.5, -0.5, -0.5, -0.5}},
   {{-0.5, -0.5,  0.5, -0.5, -0.5}},
   {{-0.5, -0.5, -0.5,  0.5, -0.5}},
   {{-0.5, -0.5, -0.5, -0.5,  0.5}},
};

TRecognitionNet::TRecognitionNet() : NetBP()
{
}

TRecognitionNet::TRecognitionNet
( 
   unsigned numbInputs,
   unsigned numbMiddleNeurons,
   unsigned numbOutNeurons
) : NetBP( RECOGNNUMLAYS, numbInputs, numbMiddleNeurons, numbOutNeurons )
{
   name[0] = '\0';
}

TRecognitionNet::~TRecognitionNet( )
{
   name[0] = '\0';
}

TRecognitionNet::LoadFromFile
(
   const char *fileName
)
{
   if( NetBP::LoadFromFile( fileName ) )
      return 1;

   strcpy( name, fileName );

   return 0;
}

TRecognitionNet::SaveToFile
(
   const char *fileName
)
{
   if( NetBP::SaveToFile( fileName ) )
      return 1;

   strcpy( name, fileName );

   return 0;
}

void TRecognitionNet::Learn
( 
   TForces&    forces, 
   TSituation  situation 
)
{
   float inp[3];
   float out[5];

   inp[0] = forces.Fx;
   inp[1] = forces.Fz;
   inp[2] = forces.My;

   out[0] = imgOut[situation].x[0];
   out[1] = imgOut[situation].x[1];
   out[2] = imgOut[situation].x[2];
   out[3] = imgOut[situation].x[3];
   out[4] = imgOut[situation].x[4];
   
   NetBP::Cycle( inp, out );
}

TSituation TRecognitionNet::Recognize()
{
   TSituation  situation;
   LayerBP    *layer;
   unsigned    rL, numbImgs;
   float       out[5], sum[5], min;
   int         numbMin;
   
   NetBP::Propagate();
   layer = NetBP::GetLayer( rang - 1 );

      // Находим выходы
   for( rL = 0; rL < 5; rL++ )
      out[rL] = layer->neurons[rL].axon;

      // Вычисляем расстояния в векторном смысле
   for( numbImgs = 0; numbImgs < JAMMINGSITUATION + 1; numbImgs++ )
   {
      sum[numbImgs] = 0;

      for( rL = 0; rL < 5; rL++ )
         sum[numbImgs] += (imgOut[numbImgs].x[rL]-out[rL])*
                          (imgOut[numbImgs].x[rL]-out[rL]);

      sum[numbImgs] = sqrt( sum[numbImgs] );
   }

   numbMin = -1;
   min     = 1000000000;

   for( numbImgs = 0; numbImgs < JAMMINGSITUATION+1; numbImgs++ )
   {
      if( sum[numbImgs] < min )
      {
         numbMin = numbImgs;
         min     = sum[numbImgs];
      }
   }

   switch( numbMin )
   {
      case 0:
         situation = NOTOUCHSITUATION;
         break;
         
      case 1:
         situation = ONEPOINTSITUATION;
         break;
         
      case 2:
         situation = TWOPOINTSITUATION;
         break;
         
      case 3:
         situation = JAMMINGSITUATION;
         break;
         
      case 4:
         situation = NOTOUCHSITUATION;
         break;
   }

   return situation;
}

