static const char* szModule        = "para.cpp";

//------------------------------------------------------------------------------
//    module para.cpp                                                         //
//                                                                            //
//    The class TParameter is derived from TParaSet and serves as a struct    //
//    with all parameters needed by the PNC cluster/learn algorithm.          //
//    See below or http://www.newty.de/pnc2/sdocu.html for more information.  //
//                                                                            //
//    copyright (c) 2000-2003 by Lars Haendel                                 //
//    home: www.newty.de                                                      //
//                                                                            //
//    This program is free software and can be used under the terms of the    //
//    GNU licence. See header file for further information and disclaimer.    //
//                                                                            //
//------------------------------------------------------------------------------
//                                                                            //
//    USE: Encapsulates all parameters needed to learn and use a model        //
//    with the PNC2 cluster algorithm. Class is derived from TParaSet.        //
//                                                                            //
//    NOTE: Defines for parameter minima, maxima, default value etc.          //
//    are located in the header                                               //
//                                                                            //
//    File I/O: Load and save routines                                        //
//------------------------------------------------------------------------------


//----------------------------------------------------------------------------------------------------------------------
#include <stdio>                 // due to   sprintf()
#include <iomanip>               //          setw()

#include "para.h"
#include "fileutil.h"            // due to   file io routines
#include "util.h"                //          ValueToText()
#include "exception.h"           //          IfTrueThrowTypeA()



//----------------------------------------------------------------------------------------------------------------------
// constructor: initialize parameters with default values
// note: 'nIntegerMaxMin' is the # symbols of the output variable. This value is 0 for continous outputs
TParameter::TParameter(const int& nIntegerMaxMin, const bool& _f_Regression) : TParaSet()
{
   // pre-check
   IfTrueThrowTypeA(!_f_Regression && nIntegerMaxMin==0, "Regression flag conflicts with 'nIntegerMaxMin=0'!"
                     , "TParameter::TParameter", szModule);

   f_Regression = _f_Regression;                   // copy

   N_G_Max             = DEF_N_G_MAX;              // initialize additional parameters with default values
   N_Bins              = DEF_N_BINS;
   OverlapFac          = DEF_OVERLAP_FAC;
   f_NormalizeByRange  = DEF_NORMALIZE_BY_RANGE;
   f_EqualWidthBinning = DEF_EQUAL_WIDTH_BINNING;


   // overwrite ini to DEF_N_INT done in the base class's constructor for classification tasks
   if(nIntegerMaxMin!=0)
      N_Int  = nIntegerMaxMin;            // set to # output classes
}


//----------------------------------------------------------------------------------------------------------------------
// write parameters to file (ofstream)  -  either commented or for use with Load()
void TParameter::Save(ofstream& file, const bool& f_Commented/*=false*/) const
{
   // a) call base class version and initialize comment string
   TParaSet::Save(file, f_Commented);
   char szComment[16];
   sprintf(szComment, "%c ", ComChar);                // ini
   if(!f_Commented)                                   // if none-commented style ...
      szComment[0]='\0';                              // 'delete' comment string




   // b) write additional parameters
   file << setiosflags(ios::left) << resetiosflags(ios::right);                       // left justified output

   file << szComment << setw(WNAME) << SZ_N_G_MAX     << " = " << N_G_Max               << endl;
   file << szComment << setw(WNAME) << SZ_N_BINS      << " = " << N_Bins                << endl;
   file << szComment << setw(WNAME) << SZ_OVERLAP_FAC << " = " << OverlapFac            << endl;
   file << szComment << setw(WNAME) << SZ_NORMALIZE_BY_RANGE << " = " << FlagToString(f_NormalizeByRange) << endl;
   file << szComment << setw(WNAME) << SZ_EQUAL_WIDTH_BINNING << " = " << FlagToString(f_EqualWidthBinning) << endl;
   file << szComment << setw(WNAME) << "Regression" << " = " << FlagToString(f_Regression) << endl;

   file << resetiosflags(ios::left) << setiosflags(ios::right);                       // restore right justified output
}


//----------------------------------------------------------------------------------------------------------------------
// load parameters from file (ifstream)
bool TParameter::Load(ifstream& file, int& line)
{
   // a) call base class version
   TParaSet::Load(file, line);


   // b) read and check additional parameters
   try
   {
      // b1) read additional parameters
      N_G_Max      = ReadKeyValue(file, SZ_N_G_MAX      , DEF_N_G_MAX      , SEARCH_LINES);
      N_Bins       = ReadKeyValue(file, SZ_N_BINS       , DEF_N_BINS       , SEARCH_LINES);
      OverlapFac   = ReadKeyValue(file, SZ_OVERLAP_FAC  , DEF_OVERLAP_FAC  , SEARCH_LINES);
      f_NormalizeByRange  = ReadKeyBool(file, SZ_NORMALIZE_BY_RANGE, DEF_NORMALIZE_BY_RANGE, SEARCH_LINES);
      f_EqualWidthBinning = ReadKeyBool(file, SZ_EQUAL_WIDTH_BINNING, DEF_EQUAL_WIDTH_BINNING, SEARCH_LINES);
      f_Regression = ReadKeyBool (file, "Regression"    , false            , SEARCH_LINES);

      // b2) check
      if(N_G_Max      < MIN_N_G_MAX)                                             throw 1;
      if(N_Bins       < MIN_N_BINS       || N_Bins       > MAX_N_BINS)           throw 2;
      if(OverlapFac   < MIN_OVERLAP_FAC  || OverlapFac   > MAX_OVERLAP_FAC)      throw 3;

   }
   catch(int errNo)     // exception handling: compose error text and throw again
   {
      char szText[STS];
      switch(errNo){

         case 1 : sprintf(szText, "Error in section [Parameter]: Value of '%s' not e[%d..oo]!", SZ_N_G_MAX, MIN_N_G_MAX); break;
         case 2 : sprintf(szText, "Error in section [Parameter]: Value of '%s' not e[%d..%d]!", SZ_N_BINS, MIN_N_BINS, MAX_N_BINS); break;
         case 3 : sprintf(szText, "Error in section [Parameter]: Value of '%s' not e[%d..%d]!", SZ_OVERLAP_FAC, MIN_OVERLAP_FAC, MAX_OVERLAP_FAC); break;
         default  :  sprintf(szText, "Error in section [Parameter]: %s", GetLastError(errNo)); break;
      }
      ThrowTypeU(szText);  // throw exception
   }

   return true;   // not used here, only necessary in base class's versione
}