// @(#)root/tmva $Id$
// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Kai Voss

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : MethodCFMlpANN_utils                                                  *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Reference for the original FORTRAN version "mlpl3.F":                          *
 *      Authors  : J. Proriol and contributions from ALEPH-Clermont-Fd            *
 *                 Team members                                                   *
 *      Copyright: Laboratoire Physique Corpusculaire                             *
 *                 Universite de Blaise Pascal, IN2P3/CNRS                        *
 * Description:                                                                   *
 *      Utility routine, obtained via f2c from original mlpl3.F FORTRAN routine   *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Xavier Prudent  <prudent@lapp.in2p3.fr>  - LAPP, France                   *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *      Kai Voss        <Kai.Voss@cern.ch>       - U. of Victoria, Canada         *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         *
 *      U. of Victoria, Canada                                                    *
 *      MPI-K Heidelberg, Germany                                                 *
 *      LAPP, Annecy, France                                                      *
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

#ifndef ROOT_TMVA_MethodCFMlpANN_Utils
#define ROOT_TMVA_MethodCFMlpANN_Utils

#ifndef ROOT_TMVA_MethodCFMlpANN_def
#include "TMVA/MethodCFMlpANN_def.h"
#endif
#ifndef ROOT_TMVA_MsgLogger
#include "TMVA/MsgLogger.h"
#endif

#ifndef ROOT_Rtypes
#include "Rtypes.h"
#endif

#include <cstdlib>
//////////////////////////////////////////////////////////////////////////
//                                                                      //
// MethodCFMlpANN_Utils                                                 //
//                                                                      //
// Implementation of Clermond-Ferrand artificial neural network         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

namespace TMVA {

   class MethodCFMlpANN_Utils {

   public:

      MethodCFMlpANN_Utils();
      virtual ~MethodCFMlpANN_Utils();

   protected:

      void Train_nn( Double_t *tin2, Double_t *tout2, Int_t *ntrain, 
                     Int_t *ntest, Int_t *nvar2, Int_t *nlayer, 
                     Int_t *nodes, Int_t *ncycle );
      
      void Entree_new( Int_t *, char *, Int_t *ntrain, Int_t *ntest, 
                       Int_t *numlayer, Int_t *nodes, Int_t *numcycle, 
                       Int_t );

      virtual Int_t DataInterface( Double_t*, Double_t*, Int_t*, Int_t*, Int_t*, Int_t*,
                                   Double_t*, Int_t*, Int_t* ) = 0;
  
      Double_t Fdecroi(Int_t *i__);
      Double_t Sen3a(void);

      void  Wini      ();
      void  En_avant  (Int_t *ievent);
      void  En_avant2 (Int_t *ievent);
      void  En_arriere(Int_t *ievent);
      void  Leclearn  (Int_t *ktest, Double_t *tout2, Double_t *tin2);
      void  Out       (Int_t *iii, Int_t *maxcycle);
      void  Cout      (Int_t *, Double_t *xxx);
      void  Innit     (char *det, Double_t *tout2, Double_t *tin2, Int_t );
      void  TestNN    ();
      void  Inl       ();
      void  GraphNN   (Int_t *ilearn, Double_t *, Double_t *, char *, Int_t);
      void  Foncf     (Int_t *i__, Double_t *u, Double_t *f);
      void  Cout2     (Int_t * /*i1*/, Double_t *yyy);
      void  Lecev2    (Int_t *ktest, Double_t *tout2, Double_t *tin2);
      void  Arret     (const char* mot );
      void  CollectVar(Int_t *nvar, Int_t *class__, Double_t *xpg);

   protected:

      static Int_t             fg_100;          // constant
      static Int_t             fg_0;            // constant
      static const Int_t       fg_max_nVar_;    // static maximum number of input variables
      static const Int_t       fg_max_nNodes_;  // maximum number of nodes per variable
      static Int_t             fg_999;          // constant
      static const char* const fg_MethodName;   // method name for print

      Double_t W_ref(const Double_t wNN[], Int_t a_1, Int_t a_2, Int_t a_3) const {
         return wNN [(a_3*max_nNodes_ + a_2)*max_nLayers_ + a_1 - 187];
      }
      Double_t& W_ref(Double_t wNN[], Int_t a_1, Int_t a_2, Int_t a_3) {
         return wNN [((a_3)*max_nNodes_ + (a_2))*max_nLayers_ + a_1 - 187];
      }
      
      Double_t Ww_ref(const Double_t wwNN[], Int_t a_1,Int_t a_2) const {
         return wwNN[(a_2)*max_nLayers_ + a_1 - 7];
      }
      Double_t& Ww_ref(Double_t wwNN[], Int_t a_1,Int_t a_2) {
         return wwNN[(a_2)*max_nLayers_ + a_1 - 7];
      }

      // ANN training parameters
      struct {
         Double_t epsmin, epsmax, eeps, eta;
         Int_t layerm, lclass, nevl, nblearn, nunilec, nunisor, nunishort, nunap;
         Int_t nvar, itest, ndiv, ichoi, ndivis, nevt;
      } fParam_1;

      // ANN training results
      struct {
         Double_t xmax[max_nVar_], xmin[max_nVar_];
         Int_t nclass[max_Events_], mclass[max_Events_], iclass;
      } fVarn_1;

      // dynamic data table
      class VARn2 {
      public:
         VARn2() : fNevt(0), fNvar(0) { 
            fxx = 0;
         }
         ~VARn2() {
            Delete();
         }
         void Create( Int_t nevt, Int_t nvar ) {
            fNevt = nevt+1; fNvar = nvar+1; // fortran array style 1...N
            fxx = new Double_t*[fNevt];
            for (Int_t i=0; i<fNevt; i++) fxx[i] = new Double_t[fNvar];
         }
         Double_t operator=( Double_t val ) { return val; }
         Double_t &operator()( Int_t ievt, Int_t ivar ) const { 
            if (0 != fxx && ievt < fNevt && ivar < fNvar) return fxx[ievt][ivar];
            else {
               printf( "*** ERROR in varn3_(): fxx is zero pointer ==> abort ***\n") ;
               std::exit(1);
               return fxx[0][0];
            }
         }
         void Delete( void ) {
            if (0 != fxx) for (Int_t i=0; i<fNevt; i++) if (0 != fxx[i]) delete [] fxx[i];
            delete[] fxx;
            fxx=0;
         }

         Double_t** fxx;
         Int_t fNevt;
         Int_t fNvar;
      } fVarn2_1, fVarn3_1;

      // ANN weights
      struct {
         Double_t x[max_nLayers_*max_nNodes_];
         Double_t y[max_nLayers_*max_nNodes_];
         Double_t o[max_nNodes_];
         Double_t w[max_nLayers_*max_nNodes_*max_nNodes_];
         Double_t ww[max_nLayers_*max_nNodes_];
         Double_t cut[max_nNodes_];
         Double_t deltaww[max_nLayers_*max_nNodes_];
         Int_t neuron[max_nLayers_];
      } fNeur_1;

      // ANN weights
      struct {
         Double_t coef[max_nNodes_], temp[max_nLayers_], demin, demax;
         Double_t del[max_nLayers_*max_nNodes_];
         Double_t delw[max_nLayers_*max_nNodes_*max_nNodes_];
         Double_t delta[max_nLayers_*max_nNodes_*max_nNodes_];
         Double_t delww[max_nLayers_*max_nNodes_];
         Int_t idde;
      } fDel_1;

      // flags and stuff (don't ask me...)
      struct {
         Double_t ancout, tolcou;
         Int_t ieps;
      } fCost_1;

      void SetLogger(MsgLogger *l) { fLogger = l; }

   private:
      MsgLogger * fLogger;
      MsgLogger& ULog()  { if (fLogger) return *fLogger; return *(fLogger = new MsgLogger("CFMLP_Utils")); } // avoiding control reaches end of non-void function warning

   public:

      ClassDef(MethodCFMlpANN_Utils,0)  // Implementation of Clermond-Ferrand artificial neural network
   };

} // namespace TMVA

#endif
 MethodCFMlpANN_Utils.h:1
 MethodCFMlpANN_Utils.h:2
 MethodCFMlpANN_Utils.h:3
 MethodCFMlpANN_Utils.h:4
 MethodCFMlpANN_Utils.h:5
 MethodCFMlpANN_Utils.h:6
 MethodCFMlpANN_Utils.h:7
 MethodCFMlpANN_Utils.h:8
 MethodCFMlpANN_Utils.h:9
 MethodCFMlpANN_Utils.h:10
 MethodCFMlpANN_Utils.h:11
 MethodCFMlpANN_Utils.h:12
 MethodCFMlpANN_Utils.h:13
 MethodCFMlpANN_Utils.h:14
 MethodCFMlpANN_Utils.h:15
 MethodCFMlpANN_Utils.h:16
 MethodCFMlpANN_Utils.h:17
 MethodCFMlpANN_Utils.h:18
 MethodCFMlpANN_Utils.h:19
 MethodCFMlpANN_Utils.h:20
 MethodCFMlpANN_Utils.h:21
 MethodCFMlpANN_Utils.h:22
 MethodCFMlpANN_Utils.h:23
 MethodCFMlpANN_Utils.h:24
 MethodCFMlpANN_Utils.h:25
 MethodCFMlpANN_Utils.h:26
 MethodCFMlpANN_Utils.h:27
 MethodCFMlpANN_Utils.h:28
 MethodCFMlpANN_Utils.h:29
 MethodCFMlpANN_Utils.h:30
 MethodCFMlpANN_Utils.h:31
 MethodCFMlpANN_Utils.h:32
 MethodCFMlpANN_Utils.h:33
 MethodCFMlpANN_Utils.h:34
 MethodCFMlpANN_Utils.h:35
 MethodCFMlpANN_Utils.h:36
 MethodCFMlpANN_Utils.h:37
 MethodCFMlpANN_Utils.h:38
 MethodCFMlpANN_Utils.h:39
 MethodCFMlpANN_Utils.h:40
 MethodCFMlpANN_Utils.h:41
 MethodCFMlpANN_Utils.h:42
 MethodCFMlpANN_Utils.h:43
 MethodCFMlpANN_Utils.h:44
 MethodCFMlpANN_Utils.h:45
 MethodCFMlpANN_Utils.h:46
 MethodCFMlpANN_Utils.h:47
 MethodCFMlpANN_Utils.h:48
 MethodCFMlpANN_Utils.h:49
 MethodCFMlpANN_Utils.h:50
 MethodCFMlpANN_Utils.h:51
 MethodCFMlpANN_Utils.h:52
 MethodCFMlpANN_Utils.h:53
 MethodCFMlpANN_Utils.h:54
 MethodCFMlpANN_Utils.h:55
 MethodCFMlpANN_Utils.h:56
 MethodCFMlpANN_Utils.h:57
 MethodCFMlpANN_Utils.h:58
 MethodCFMlpANN_Utils.h:59
 MethodCFMlpANN_Utils.h:60
 MethodCFMlpANN_Utils.h:61
 MethodCFMlpANN_Utils.h:62
 MethodCFMlpANN_Utils.h:63
 MethodCFMlpANN_Utils.h:64
 MethodCFMlpANN_Utils.h:65
 MethodCFMlpANN_Utils.h:66
 MethodCFMlpANN_Utils.h:67
 MethodCFMlpANN_Utils.h:68
 MethodCFMlpANN_Utils.h:69
 MethodCFMlpANN_Utils.h:70
 MethodCFMlpANN_Utils.h:71
 MethodCFMlpANN_Utils.h:72
 MethodCFMlpANN_Utils.h:73
 MethodCFMlpANN_Utils.h:74
 MethodCFMlpANN_Utils.h:75
 MethodCFMlpANN_Utils.h:76
 MethodCFMlpANN_Utils.h:77
 MethodCFMlpANN_Utils.h:78
 MethodCFMlpANN_Utils.h:79
 MethodCFMlpANN_Utils.h:80
 MethodCFMlpANN_Utils.h:81
 MethodCFMlpANN_Utils.h:82
 MethodCFMlpANN_Utils.h:83
 MethodCFMlpANN_Utils.h:84
 MethodCFMlpANN_Utils.h:85
 MethodCFMlpANN_Utils.h:86
 MethodCFMlpANN_Utils.h:87
 MethodCFMlpANN_Utils.h:88
 MethodCFMlpANN_Utils.h:89
 MethodCFMlpANN_Utils.h:90
 MethodCFMlpANN_Utils.h:91
 MethodCFMlpANN_Utils.h:92
 MethodCFMlpANN_Utils.h:93
 MethodCFMlpANN_Utils.h:94
 MethodCFMlpANN_Utils.h:95
 MethodCFMlpANN_Utils.h:96
 MethodCFMlpANN_Utils.h:97
 MethodCFMlpANN_Utils.h:98
 MethodCFMlpANN_Utils.h:99
 MethodCFMlpANN_Utils.h:100
 MethodCFMlpANN_Utils.h:101
 MethodCFMlpANN_Utils.h:102
 MethodCFMlpANN_Utils.h:103
 MethodCFMlpANN_Utils.h:104
 MethodCFMlpANN_Utils.h:105
 MethodCFMlpANN_Utils.h:106
 MethodCFMlpANN_Utils.h:107
 MethodCFMlpANN_Utils.h:108
 MethodCFMlpANN_Utils.h:109
 MethodCFMlpANN_Utils.h:110
 MethodCFMlpANN_Utils.h:111
 MethodCFMlpANN_Utils.h:112
 MethodCFMlpANN_Utils.h:113
 MethodCFMlpANN_Utils.h:114
 MethodCFMlpANN_Utils.h:115
 MethodCFMlpANN_Utils.h:116
 MethodCFMlpANN_Utils.h:117
 MethodCFMlpANN_Utils.h:118
 MethodCFMlpANN_Utils.h:119
 MethodCFMlpANN_Utils.h:120
 MethodCFMlpANN_Utils.h:121
 MethodCFMlpANN_Utils.h:122
 MethodCFMlpANN_Utils.h:123
 MethodCFMlpANN_Utils.h:124
 MethodCFMlpANN_Utils.h:125
 MethodCFMlpANN_Utils.h:126
 MethodCFMlpANN_Utils.h:127
 MethodCFMlpANN_Utils.h:128
 MethodCFMlpANN_Utils.h:129
 MethodCFMlpANN_Utils.h:130
 MethodCFMlpANN_Utils.h:131
 MethodCFMlpANN_Utils.h:132
 MethodCFMlpANN_Utils.h:133
 MethodCFMlpANN_Utils.h:134
 MethodCFMlpANN_Utils.h:135
 MethodCFMlpANN_Utils.h:136
 MethodCFMlpANN_Utils.h:137
 MethodCFMlpANN_Utils.h:138
 MethodCFMlpANN_Utils.h:139
 MethodCFMlpANN_Utils.h:140
 MethodCFMlpANN_Utils.h:141
 MethodCFMlpANN_Utils.h:142
 MethodCFMlpANN_Utils.h:143
 MethodCFMlpANN_Utils.h:144
 MethodCFMlpANN_Utils.h:145
 MethodCFMlpANN_Utils.h:146
 MethodCFMlpANN_Utils.h:147
 MethodCFMlpANN_Utils.h:148
 MethodCFMlpANN_Utils.h:149
 MethodCFMlpANN_Utils.h:150
 MethodCFMlpANN_Utils.h:151
 MethodCFMlpANN_Utils.h:152
 MethodCFMlpANN_Utils.h:153
 MethodCFMlpANN_Utils.h:154
 MethodCFMlpANN_Utils.h:155
 MethodCFMlpANN_Utils.h:156
 MethodCFMlpANN_Utils.h:157
 MethodCFMlpANN_Utils.h:158
 MethodCFMlpANN_Utils.h:159
 MethodCFMlpANN_Utils.h:160
 MethodCFMlpANN_Utils.h:161
 MethodCFMlpANN_Utils.h:162
 MethodCFMlpANN_Utils.h:163
 MethodCFMlpANN_Utils.h:164
 MethodCFMlpANN_Utils.h:165
 MethodCFMlpANN_Utils.h:166
 MethodCFMlpANN_Utils.h:167
 MethodCFMlpANN_Utils.h:168
 MethodCFMlpANN_Utils.h:169
 MethodCFMlpANN_Utils.h:170
 MethodCFMlpANN_Utils.h:171
 MethodCFMlpANN_Utils.h:172
 MethodCFMlpANN_Utils.h:173
 MethodCFMlpANN_Utils.h:174
 MethodCFMlpANN_Utils.h:175
 MethodCFMlpANN_Utils.h:176
 MethodCFMlpANN_Utils.h:177
 MethodCFMlpANN_Utils.h:178
 MethodCFMlpANN_Utils.h:179
 MethodCFMlpANN_Utils.h:180
 MethodCFMlpANN_Utils.h:181
 MethodCFMlpANN_Utils.h:182
 MethodCFMlpANN_Utils.h:183
 MethodCFMlpANN_Utils.h:184
 MethodCFMlpANN_Utils.h:185
 MethodCFMlpANN_Utils.h:186
 MethodCFMlpANN_Utils.h:187
 MethodCFMlpANN_Utils.h:188
 MethodCFMlpANN_Utils.h:189
 MethodCFMlpANN_Utils.h:190
 MethodCFMlpANN_Utils.h:191
 MethodCFMlpANN_Utils.h:192
 MethodCFMlpANN_Utils.h:193
 MethodCFMlpANN_Utils.h:194
 MethodCFMlpANN_Utils.h:195
 MethodCFMlpANN_Utils.h:196
 MethodCFMlpANN_Utils.h:197
 MethodCFMlpANN_Utils.h:198
 MethodCFMlpANN_Utils.h:199
 MethodCFMlpANN_Utils.h:200
 MethodCFMlpANN_Utils.h:201
 MethodCFMlpANN_Utils.h:202
 MethodCFMlpANN_Utils.h:203
 MethodCFMlpANN_Utils.h:204
 MethodCFMlpANN_Utils.h:205
 MethodCFMlpANN_Utils.h:206
 MethodCFMlpANN_Utils.h:207
 MethodCFMlpANN_Utils.h:208
 MethodCFMlpANN_Utils.h:209
 MethodCFMlpANN_Utils.h:210
 MethodCFMlpANN_Utils.h:211