/*
   C advanced code transfer function for Neuron Network
   File : model0Lev.c
  
   Ce code a été crée automatiquement par le module NEURO CODE à partir d'un
   modèle neuronal développé avec un outil de la 

                            Suite NEURO ONE

   Le présent code source généré par le progiciel NEURO CODE est protégé tant 
   par les dispositions nationales qu'internationales en matière de droits de 
   la propriété intellectuelle, dont les droits sont détenus, à titre 
   exclusif, par la société NETRAL.
   L'utilisation et la modification de ce code source est soumise à un contrat
   de licence d'utilisation.

   La contrefaçon est un délit pénal puni de 2 ans d'emprisonnement et de 
   150.000 Euros d'amende.

   Le modèle du présent code source a fait l'objet d'un dépôt auprès de 
   l'Agence pour la Protection des Programmes sous le numéro : 
   
   IDDN.FR.001.500018.00.S.P.1999.000.20700

   NETRAL ne peut en aucun cas être tenu pour responsable des conséquences de
   l'utilisation de ce code.

   Lisez attentivement le fichier "licfr.txt" joint à ce fichier pour
   connaitre vos droits et obligations concernant l'usage de ce code.
   Pour obtenir une licence ou tout renseignement complémentaire,
   adressez vous à :

               NETRAL
               14, rue Verdi
               9213 Issy-les-Moulineaux
               tel : (33) 146 387 512
               email: info@netral.com


   Date     : 25/10/2005
   Time     : 17:30:55
   User     : Jean_Luc_PLOIX
   Computer : SOPHRONE
   Counter  : 2
  
   NetworkName : model0
   FileName : D:\Program Files\Netral\Data\Exemples\Modeles\Static.NML
*/

  #include <stdio.h>
  #include <stdlib.h>
  #include <math.h>
  #include <ctype.h>
  #include <string.h>

  #include "readfile.h"
  #include "model0tfr.h"
  #include "model0grd.h"
  #include "model0lev.h"
    /* Please check name of included header files */

  real model0matrix[model0MATRIXES];
  static long weightlevinitialized = 0;

  long model0getwlinit()
  {
    return weightlevinitialized;
  }

  void model0setwlinit(long value)
  {
    weightlevinitialized = value;
    model0setwinit(value);
  }
  
  void model0transferlev(real *inputs, real *outputs, real *leverage)
  /*Module   : model0lev
  Method     : model0transferlev
  Visibility : Public
  Arguments  : inputs: real* -> les entrées
               outputs: real* -> les sorties calculées
               leverage: real* -> les leviers calculés
  Description: Effectue un transfert par le réseau avec calcul du gradient, puis
    calcule les leviers.*/
  {
    model0transferlevW(model0weights, model0matrix, inputs, outputs, leverage);
  }

  void model0transferlevW(real *weights, real *zmat, real *inputs, real *outputs, real *leverage)
  /*Module   : model0lev
  Method     : model0transferlevW
  Visibility : Public
  Arguments  : weights: real* -> les poids courants
               zmat: real* -> la matrice (ZtZ)inv
               inputs: real* -> les entrées
               outputs: real* -> les sorties calculées
               leverage: real* -> les leviers calculés
  Description: Effectue un transfert par le réseau avec calcul du gradient, puis
    calcule les leviers.*/
  {
    real gradient[model0SYNAPSES];
    real iniback[model0OUTPUTS];
    real X;
    long i, j;

    if (!weightlevinitialized)    
      model0loadwl(NULL);

    for (i=0; i < model0SYNAPSES; gradient[i++] = 0);
    for (i=0; i < model0OUTPUTS; iniback[i++] = 0);
    for (i=0; i < model0OUTPUTS; leverage[i++] = 0);
    iniback[0] = 1;

    model0transfergradient(weights, inputs, outputs, gradient, iniback);
    for (i=0; i < model0SYNAPSES; i++)
    {
      X = 0;
      for (j=0; j < model0SYNAPSES; j++)
        X += zmat[mindex(i,j)] * gradient[j];
      leverage[0] += X * gradient[i];
    }
  }

  long model0loadwl(char* filename)
  /* Loading weights and dispersion matrix from ASCII file */
  {
    FILE *file;
    char buffer[BUFFERSIZE];
    char bufname[BUFFERSIZE];
    char* tok;
    long n;
    long ok = 0;
    long okl = 0;
    long cumul = 0;
    long start = 0;

    if (filename)
      strncpy(bufname, filename, BUFFERSIZE-1);
    else
      strcat(strcpy(bufname, MODEL), "w.txt");
    file = fopen(bufname, "r");
    if (file)
    {
      while ((!feof(file)) && (!ok))
      {
        if (fgets(buffer, BUFFERSIZE-1, file) && (buffer[0] != ';') && (buffer[0] != '\n') && (!strncmp(buffer, WEIGHTS, strlen(WEIGHTS))))
        {
          if (fgets(buffer, BUFFERSIZE-1, file))
          {
            tok = strtok(buffer, "=");
            if (!strcmp(tok, COUNT))
            {
              tok = strtok(NULL, "=");
              if ((tok) && (!isalpha(tok[0])))
              {
                n = atoi(supbackline(tok));
                ok = (n == model0SYNAPSES);
              }
            }
          }
        }
      }
      if (ok)
      {
        while (!feof(file) && (cumul < model0SYNAPSES))
        {
          if (fgets(buffer, BUFFERSIZE-1, file) && (buffer[0] != ';') && (buffer[0] != '\n'))
          {
            if (!isalpha(buffer[0]))
            {
              start = 1;
              model0setweight(cumul, atof(supbackline(buffer)));
            }
          }
          if (start) cumul++;
        }
        fclose(file);
        if (cumul == model0SYNAPSES)
        {
          model0setwinit(1);
          return 0;
        }
        else
          return 3;
      }
      while ((!feof(file)) && (!okl))
      {
        if (fgets(buffer, BUFFERSIZE-1, file) && (buffer[0] != ';') && (buffer[0] != '\n') && (!strncmp(buffer, DISPERSION, strlen(WEIGHTS))))
        {
          if (fgets(buffer, BUFFERSIZE-1, file))
          {
            tok = strtok(buffer, "=");
            if (!strcmp(tok, COUNT))
            {
              tok = strtok(NULL, "=");
              if ((tok) && (!isalpha(tok[0])))
              {
                n = atoi(supbackline(tok));
                ok = (n == model0MATRIXES);
              }
            }
          }
        }
      }
      if (okl)
      {
        while (!feof(file) && (cumul < model0MATRIXES))
        {
          if (fgets(buffer, BUFFERSIZE-1, file) && (buffer[0] != ';') && (buffer[0] != '\n'))
          {
            if (!isalpha(buffer[0]))
            {
              start = 1;
              model0matrix[cumul] = atof(supbackline(buffer));
            }
          }
          if (start) cumul++;
        }
        fclose(file);
        if (cumul == model0SYNAPSES)
        {
          weightlevinitialized = 1;
          return 0;
        }
        else
          return 5;
      }
      else if (!ok)
        return 2;
      else
        return 4;
    }
    else
      return 1;
  }

  long model0savewl(char* filename, char* comment)
  {
    FILE *file;
    char bufname[BUFFERSIZE];
    long i;

    if (filename)
      strncpy(bufname, filename, BUFFERSIZE-1);
    else
      strcat(strcpy(bufname, MODEL), "w.txt");
    file = fopen(bufname, "w");
    if (file)
    {
      if ((comment) && (comment[0]))
        fprintf(file, "%s\n", comment);
      fprintf(file, "%s\n", WEIGHTS);
      fprintf(file, "%s=%ld\n", COUNT, model0SYNAPSES);
      for (i=0; i < model0SYNAPSES; i++)
        fprintf(file, "%20.16E\n", model0weights[i]);
      fprintf(file, "%s\n", DISPERSION);
      fprintf(file, "%s=%ld\n", COUNT, model0MATRIXES);
      for (i=0; i < model0MATRIXES; i++)
        fprintf(file, "%20.16E\n", model0matrix[i]);
      fclose(file);
      return 0;
    }
    else
      return 1;
  }



NETRAL - Neuro Code 6