// @(#)root/tmva $Id$
// Author: S. Jadach, Tancredi Carli, Dominik Dannheim, Alexander Voigt

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Classes: PDEFoamVect                                                           *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Auxiliary class PDEFoamVect of n-dimensional vector, with dynamic         *
 *      allocation used for the cartesian geometry of the PDEFoam cells           *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      S. Jadach        - Institute of Nuclear Physics, Cracow, Poland           *
 *      Tancredi Carli   - CERN, Switzerland                                      *
 *      Dominik Dannheim - CERN, Switzerland                                      *
 *      Alexander Voigt  - TU Dresden, Germany                                    *
 *                                                                                *
 * Copyright (c) 2008:                                                            *
 *      CERN, Switzerland                                                         *
 *      MPI-K Heidelberg, Germany                                                 *
 *                                                                                *
 * 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)                                          *
 **********************************************************************************/

#include <iostream>
#include <iomanip>

#ifndef ROOT_TMVA_PDEFoamVect
#include "TMVA/PDEFoamVect.h"
#endif

using namespace std;

//#define SW2 std::setw(12)

ClassImp(TMVA::PDEFoamVect)

//_____________________________________________________________________
TMVA::PDEFoamVect::PDEFoamVect()
   : TObject(),
     fDim(0),
     fCoords(0)
{
   // Default constructor for streamer
}

//_____________________________________________________________________
TMVA::PDEFoamVect::PDEFoamVect(Int_t n)
   : TObject(),
     fDim(n),
     fCoords(0)
{
   // User constructor creating n-dimensional vector
   // and allocating dynamically array of components

   if (n>0) {
      fCoords = new Double_t[fDim];
      for (Int_t i=0; i<n; i++) *(fCoords+i)=0.0;
   }
}

//_____________________________________________________________________
TMVA::PDEFoamVect::PDEFoamVect(const PDEFoamVect &vect)
   : TObject(),
     fDim(vect.fDim),
     fCoords(vect.fCoords)
{
   // Copy constructor
   Error( "PDEFoamVect", "COPY CONSTRUCTOR NOT IMPLEMENTED" );
}

//_____________________________________________________________________
TMVA::PDEFoamVect::~PDEFoamVect()
{
   // Destructor
   delete [] fCoords; //  free(fCoords)
   fCoords=0;
}

//////////////////////////////////////////////////////////////////////////////
//                     Overloading operators                                //
//////////////////////////////////////////////////////////////////////////////

//_____________________________________________________________________
TMVA::PDEFoamVect& TMVA::PDEFoamVect::operator =(const PDEFoamVect& vect)
{
   // substitution operator

   if (&vect == this) return *this;
   if (fDim != vect.fDim)
      Error("PDEFoamVect", "operator=Dims. are different: %d and %d \n ", fDim, vect.fDim);
   if (fDim != vect.fDim) {  // cleanup
      delete [] fCoords;
      fCoords = new Double_t[fDim];
   }
   fDim = vect.fDim;
   for(Int_t i=0; i<fDim; i++)
      fCoords[i] = vect.fCoords[i];
   return *this;
}

//_____________________________________________________________________
Double_t &TMVA::PDEFoamVect::operator[](Int_t n)
{
   // [] is for access to elements as in ordinary matrix like a[j]=b[j]
   // (Perhaps against some strict rules but rather practical.)
   // Range protection is built in, consequently for substitution
   // one should use rather use a=b than explicit loop!

   if ((n<0) || (n>=fDim)) {
      Error(  "PDEFoamVect","operator[], out of range \n");
   }
   return fCoords[n];
}

//_____________________________________________________________________
TMVA::PDEFoamVect& TMVA::PDEFoamVect::operator*=(const Double_t &x)
{
   // unary multiplication operator *=

   for(Int_t i=0;i<fDim;i++)
      fCoords[i] = fCoords[i]*x;
   return *this;
}

//_____________________________________________________________________
TMVA::PDEFoamVect& TMVA::PDEFoamVect::operator+=(const PDEFoamVect& shift)
{
   // unary addition operator +=; adding vector c*=x,
   if(fDim != shift.fDim){
      Error("PDEFoamVect", "operator+, different dimensions= %d %d \n", fDim, shift.fDim);
   }
   for(Int_t i=0;i<fDim;i++)
      fCoords[i] = fCoords[i] + shift.fCoords[i];
   return *this;
}

//_____________________________________________________________________
TMVA::PDEFoamVect& TMVA::PDEFoamVect::operator-=(const PDEFoamVect& shift)
{
   // unary subtraction operator -=
   if(fDim != shift.fDim) {
      Error("PDEFoamVect", "operator+, different dimensions= %d %d \n", fDim, shift.fDim);
   }
   for(Int_t i=0;i<fDim;i++)
      fCoords[i] = fCoords[i] - shift.fCoords[i];
   return *this;
}

//_____________________________________________________________________
TMVA::PDEFoamVect TMVA::PDEFoamVect::operator+(const PDEFoamVect &p2)
{
   // addition operator +; sum of 2 vectors: c=a+b, a=a+b,
   // NEVER USE IT, VERY SLOW!!!
   PDEFoamVect temp(fDim);
   temp  = (*this);
   temp += p2;
   return temp;
}

//_____________________________________________________________________
TMVA::PDEFoamVect TMVA::PDEFoamVect::operator-(const PDEFoamVect &p2)
{
   // subtraction operator -; difference of 2 vectors; c=a-b, a=a-b,
   // NEVER USE IT, VERY SLOW!!!
   PDEFoamVect temp(fDim);
   temp  = (*this);
   temp -= p2;
   return temp;
}

//_____________________________________________________________________
TMVA::PDEFoamVect& TMVA::PDEFoamVect::operator =(Double_t Vect[])
{
   // Loading in ordinary double prec. vector, sometimes can be useful
   for(Int_t i=0; i<fDim; i++)
      fCoords[i] = Vect[i];
   return *this;
}

//_____________________________________________________________________
TMVA::PDEFoamVect& TMVA::PDEFoamVect::operator =(Double_t x)
{
   // Loading in double prec. number, sometimes can be useful
   if(fCoords != 0) {
      for(Int_t i=0; i<fDim; i++)
         fCoords[i] = x;
   }
   return *this;
}

//////////////////////////////////////////////////////////////////////////////
//                          OTHER METHODS                                   //
//////////////////////////////////////////////////////////////////////////////

//_____________________________________________________________________
void TMVA::PDEFoamVect::Print(Option_t *option) const
{
   // Printout of all vector components
   streamsize wid = std::cout.width(); // saving current field width
   if(!option) Error( "Print ", "No option set \n");
   std::cout << "(";
   for(Int_t i=0; i<fDim-1; i++)
      std::cout << std::setw(12) << *(fCoords+i) << ",";
   std::cout << std::setw(12) << *(fCoords+fDim-1);
   std::cout << ")";
   std::cout.width(wid);
}
 PDEFoamVect.cxx:1
 PDEFoamVect.cxx:2
 PDEFoamVect.cxx:3
 PDEFoamVect.cxx:4
 PDEFoamVect.cxx:5
 PDEFoamVect.cxx:6
 PDEFoamVect.cxx:7
 PDEFoamVect.cxx:8
 PDEFoamVect.cxx:9
 PDEFoamVect.cxx:10
 PDEFoamVect.cxx:11
 PDEFoamVect.cxx:12
 PDEFoamVect.cxx:13
 PDEFoamVect.cxx:14
 PDEFoamVect.cxx:15
 PDEFoamVect.cxx:16
 PDEFoamVect.cxx:17
 PDEFoamVect.cxx:18
 PDEFoamVect.cxx:19
 PDEFoamVect.cxx:20
 PDEFoamVect.cxx:21
 PDEFoamVect.cxx:22
 PDEFoamVect.cxx:23
 PDEFoamVect.cxx:24
 PDEFoamVect.cxx:25
 PDEFoamVect.cxx:26
 PDEFoamVect.cxx:27
 PDEFoamVect.cxx:28
 PDEFoamVect.cxx:29
 PDEFoamVect.cxx:30
 PDEFoamVect.cxx:31
 PDEFoamVect.cxx:32
 PDEFoamVect.cxx:33
 PDEFoamVect.cxx:34
 PDEFoamVect.cxx:35
 PDEFoamVect.cxx:36
 PDEFoamVect.cxx:37
 PDEFoamVect.cxx:38
 PDEFoamVect.cxx:39
 PDEFoamVect.cxx:40
 PDEFoamVect.cxx:41
 PDEFoamVect.cxx:42
 PDEFoamVect.cxx:43
 PDEFoamVect.cxx:44
 PDEFoamVect.cxx:45
 PDEFoamVect.cxx:46
 PDEFoamVect.cxx:47
 PDEFoamVect.cxx:48
 PDEFoamVect.cxx:49
 PDEFoamVect.cxx:50
 PDEFoamVect.cxx:51
 PDEFoamVect.cxx:52
 PDEFoamVect.cxx:53
 PDEFoamVect.cxx:54
 PDEFoamVect.cxx:55
 PDEFoamVect.cxx:56
 PDEFoamVect.cxx:57
 PDEFoamVect.cxx:58
 PDEFoamVect.cxx:59
 PDEFoamVect.cxx:60
 PDEFoamVect.cxx:61
 PDEFoamVect.cxx:62
 PDEFoamVect.cxx:63
 PDEFoamVect.cxx:64
 PDEFoamVect.cxx:65
 PDEFoamVect.cxx:66
 PDEFoamVect.cxx:67
 PDEFoamVect.cxx:68
 PDEFoamVect.cxx:69
 PDEFoamVect.cxx:70
 PDEFoamVect.cxx:71
 PDEFoamVect.cxx:72
 PDEFoamVect.cxx:73
 PDEFoamVect.cxx:74
 PDEFoamVect.cxx:75
 PDEFoamVect.cxx:76
 PDEFoamVect.cxx:77
 PDEFoamVect.cxx:78
 PDEFoamVect.cxx:79
 PDEFoamVect.cxx:80
 PDEFoamVect.cxx:81
 PDEFoamVect.cxx:82
 PDEFoamVect.cxx:83
 PDEFoamVect.cxx:84
 PDEFoamVect.cxx:85
 PDEFoamVect.cxx:86
 PDEFoamVect.cxx:87
 PDEFoamVect.cxx:88
 PDEFoamVect.cxx:89
 PDEFoamVect.cxx:90
 PDEFoamVect.cxx:91
 PDEFoamVect.cxx:92
 PDEFoamVect.cxx:93
 PDEFoamVect.cxx:94
 PDEFoamVect.cxx:95
 PDEFoamVect.cxx:96
 PDEFoamVect.cxx:97
 PDEFoamVect.cxx:98
 PDEFoamVect.cxx:99
 PDEFoamVect.cxx:100
 PDEFoamVect.cxx:101
 PDEFoamVect.cxx:102
 PDEFoamVect.cxx:103
 PDEFoamVect.cxx:104
 PDEFoamVect.cxx:105
 PDEFoamVect.cxx:106
 PDEFoamVect.cxx:107
 PDEFoamVect.cxx:108
 PDEFoamVect.cxx:109
 PDEFoamVect.cxx:110
 PDEFoamVect.cxx:111
 PDEFoamVect.cxx:112
 PDEFoamVect.cxx:113
 PDEFoamVect.cxx:114
 PDEFoamVect.cxx:115
 PDEFoamVect.cxx:116
 PDEFoamVect.cxx:117
 PDEFoamVect.cxx:118
 PDEFoamVect.cxx:119
 PDEFoamVect.cxx:120
 PDEFoamVect.cxx:121
 PDEFoamVect.cxx:122
 PDEFoamVect.cxx:123
 PDEFoamVect.cxx:124
 PDEFoamVect.cxx:125
 PDEFoamVect.cxx:126
 PDEFoamVect.cxx:127
 PDEFoamVect.cxx:128
 PDEFoamVect.cxx:129
 PDEFoamVect.cxx:130
 PDEFoamVect.cxx:131
 PDEFoamVect.cxx:132
 PDEFoamVect.cxx:133
 PDEFoamVect.cxx:134
 PDEFoamVect.cxx:135
 PDEFoamVect.cxx:136
 PDEFoamVect.cxx:137
 PDEFoamVect.cxx:138
 PDEFoamVect.cxx:139
 PDEFoamVect.cxx:140
 PDEFoamVect.cxx:141
 PDEFoamVect.cxx:142
 PDEFoamVect.cxx:143
 PDEFoamVect.cxx:144
 PDEFoamVect.cxx:145
 PDEFoamVect.cxx:146
 PDEFoamVect.cxx:147
 PDEFoamVect.cxx:148
 PDEFoamVect.cxx:149
 PDEFoamVect.cxx:150
 PDEFoamVect.cxx:151
 PDEFoamVect.cxx:152
 PDEFoamVect.cxx:153
 PDEFoamVect.cxx:154
 PDEFoamVect.cxx:155
 PDEFoamVect.cxx:156
 PDEFoamVect.cxx:157
 PDEFoamVect.cxx:158
 PDEFoamVect.cxx:159
 PDEFoamVect.cxx:160
 PDEFoamVect.cxx:161
 PDEFoamVect.cxx:162
 PDEFoamVect.cxx:163
 PDEFoamVect.cxx:164
 PDEFoamVect.cxx:165
 PDEFoamVect.cxx:166
 PDEFoamVect.cxx:167
 PDEFoamVect.cxx:168
 PDEFoamVect.cxx:169
 PDEFoamVect.cxx:170
 PDEFoamVect.cxx:171
 PDEFoamVect.cxx:172
 PDEFoamVect.cxx:173
 PDEFoamVect.cxx:174
 PDEFoamVect.cxx:175
 PDEFoamVect.cxx:176
 PDEFoamVect.cxx:177
 PDEFoamVect.cxx:178
 PDEFoamVect.cxx:179
 PDEFoamVect.cxx:180
 PDEFoamVect.cxx:181
 PDEFoamVect.cxx:182
 PDEFoamVect.cxx:183
 PDEFoamVect.cxx:184
 PDEFoamVect.cxx:185
 PDEFoamVect.cxx:186
 PDEFoamVect.cxx:187
 PDEFoamVect.cxx:188
 PDEFoamVect.cxx:189
 PDEFoamVect.cxx:190
 PDEFoamVect.cxx:191
 PDEFoamVect.cxx:192
 PDEFoamVect.cxx:193
 PDEFoamVect.cxx:194
 PDEFoamVect.cxx:195
 PDEFoamVect.cxx:196
 PDEFoamVect.cxx:197
 PDEFoamVect.cxx:198
 PDEFoamVect.cxx:199
 PDEFoamVect.cxx:200
 PDEFoamVect.cxx:201
 PDEFoamVect.cxx:202
 PDEFoamVect.cxx:203
 PDEFoamVect.cxx:204
 PDEFoamVect.cxx:205
 PDEFoamVect.cxx:206
 PDEFoamVect.cxx:207
 PDEFoamVect.cxx:208
 PDEFoamVect.cxx:209
 PDEFoamVect.cxx:210
 PDEFoamVect.cxx:211
 PDEFoamVect.cxx:212