Logo ROOT  
Reference Guide
TNDArray.h
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Axel Naumann, Nov 2011
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TNDArray
13 #define ROOT_TNDArray
14 
15 #include "TObject.h"
16 #include "TError.h"
17 
18 //////////////////////////////////////////////////////////////////////////
19 // //
20 // TNDArray //
21 // //
22 // N-Dim array class. //
23 // //
24 // Storage layout: //
25 // Assume 3 dimensions, array sizes 2, 4 and 3 i.e. 24 bins: //
26 // Data is stored as [0,0,0], [0,0,1], [0,0,2], [0,1,0],... //
27 // //
28 // fSizes stores the combined size of each bin in a dimension, i.e. in //
29 // above example it would contain 24, 12, 3, 1. //
30 // //
31 // Storage is allocated lazily, only when data is written to the array. //
32 // //
33 // TNDArrayRef gives access to a sub-dimension, e.g. arr[0][1] in above //
34 // three-dimensional example, up to an element with conversion operator //
35 // to double: double value = arr[0][1][2]; //
36 // //
37 //////////////////////////////////////////////////////////////////////////
38 
39 // Array layout:
40 // nbins[0] = 2, nbins[1] = 4, nbins[2] = 3 => 24 bins
41 //
42 // fSizes: 24, 12, 3 [, 1
43 
44 class TNDArray: public TObject {
45 public:
46  TNDArray(): fNdimPlusOne(), fSizes() {}
47 
48  TNDArray(Int_t ndim, const Int_t* nbins, bool addOverflow = false):
49  fNdimPlusOne(), fSizes() {
50  TNDArray::Init(ndim, nbins, addOverflow);
51  }
53  delete[] fSizes;
54  }
55 
56  virtual void Init(Int_t ndim, const Int_t* nbins, bool addOverflow = false) {
57  // Calculate fSize based on ndim dimensions, nbins for each dimension,
58  // possibly adding over- and underflow bin to each dimensions' nbins.
59  delete[] fSizes;
60  fNdimPlusOne = ndim + 1;
61  fSizes = new Long64_t[ndim + 1];
62  Int_t overBins = addOverflow ? 2 : 0;
63  fSizes[ndim] = 1;
64  for (Int_t i = 0; i < ndim; ++i) {
65  fSizes[ndim - i - 1] = fSizes[ndim - i] * (nbins[ndim - i - 1] + overBins);
66  }
67  }
68 
69  virtual void Reset(Option_t* option = "") = 0;
70 
71  Int_t GetNdimensions() const { return fNdimPlusOne - 1; }
72  Long64_t GetNbins() const { return fSizes[0]; }
73  Long64_t GetCellSize(Int_t dim) const { return fSizes[dim + 1]; }
74 
75  Long64_t GetBin(const Int_t* idx) const {
76  // Get the linear bin number for each dimension's bin index
77  Long64_t bin = idx[fNdimPlusOne - 2];
78  for (Int_t d = 0; d < fNdimPlusOne - 2; ++d) {
79  bin += fSizes[d + 1] * idx[d];
80  }
81  return bin;
82  }
83 
84  virtual Double_t AtAsDouble(ULong64_t linidx) const = 0;
85  virtual void SetAsDouble(ULong64_t linidx, Double_t value) = 0;
86  virtual void AddAt(ULong64_t linidx, Double_t value) = 0;
87 
88 private:
89  TNDArray(const TNDArray&); // intentionally not implemented
90  TNDArray& operator=(const TNDArray&); // intentionally not implemented
91 
92 protected:
93  Int_t fNdimPlusOne; // Number of dimensions plus one
94  Long64_t* fSizes; //[fNdimPlusOne] bin count
95  ClassDef(TNDArray, 1); //Base for n-dimensional array
96 };
97 
98 template <typename T>
99 class TNDArrayRef {
100 public:
101  TNDArrayRef(const T* data, const Long64_t* sizes):
102  fData(data), fSizes(sizes) {}
103 
105  if (!fData) return TNDArrayRef<T>(0, 0);
106  R__ASSERT(idx < fSizes[-1] / fSizes[0] && "index out of range!");
107  return TNDArrayRef<T>(fData + idx * fSizes[0], (fSizes[0] == 1) ? 0 : (fSizes + 1));
108  }
109  operator T() const {
110  if (!fData) return T();
111  R__ASSERT(fSizes == 0 && "Element operator can only be used on non-array element. Missing an operator[] level?");
112  return *fData;
113  }
114 
115 private:
116  const T* fData; // pointer into TNDArray's fData
117  const Long64_t* fSizes; // pointer into TNDArray's fSizes
118  ClassDefNV(TNDArrayRef, 0); // subdimension of a TNDArray
119 };
120 
121 template <typename T>
122 class TNDArrayT: public TNDArray {
123 public:
125 
126  TNDArrayT(Int_t ndim, const Int_t* nbins, bool addOverflow = false):
127  TNDArray(ndim, nbins, addOverflow),
128  fNumData(), fData() {
129  fNumData = fSizes[0];
130  }
132  delete[] fData;
133  }
134 
135  void Init(Int_t ndim, const Int_t* nbins, bool addOverflow = false) {
136  delete[] fData;
137  fData = 0;
138  TNDArray::Init(ndim, nbins, addOverflow);
139  fNumData = fSizes[0];
140  }
141 
142  void Reset(Option_t* /*option*/ = "") {
143  // Reset the content
144 
145  // Use placement-new with value initialization:
146  if (fData) {
147  new (fData) T[fNumData]();
148  }
149  }
150 
151 #ifndef __CINT__
153  if (!fData) return TNDArrayRef<T>(0, 0);
154  R__ASSERT(idx < fSizes[0] / fSizes[1] && "index out of range!");
155  return TNDArrayRef<T>(fData + idx * fSizes[1], fSizes + 2);
156  }
157 #endif // __CINT__
158 
159  T At(const Int_t* idx) const {
160  return At(GetBin(idx));
161  }
162  T& At(const Int_t* idx) {
163  return At(GetBin(idx));
164  }
165  T At(ULong64_t linidx) const {
166  if (!fData) return T();
167  return fData[linidx];
168  }
169  T& At(ULong64_t linidx) {
170  if (!fData) fData = new T[fNumData]();
171  return fData[linidx];
172  }
173 
174  Double_t AtAsDouble(ULong64_t linidx) const {
175  if (!fData) return 0.;
176  return fData[linidx];
177  }
178  void SetAsDouble(ULong64_t linidx, Double_t value) {
179  if (!fData) fData = new T[fNumData]();
180  fData[linidx] = (T) value;
181  }
182  void AddAt(ULong64_t linidx, Double_t value) {
183  if (!fData) fData = new T[fNumData]();
184  fData[linidx] += (T) value;
185  }
186 
187 protected:
188  int fNumData; // number of bins, product of fSizes
189  T* fData; //[fNumData] data
190  ClassDef(TNDArrayT, 1); // N-dimensional array
191 };
192 
193 // FIXME: Remove once we implement https://sft.its.cern.ch/jira/browse/ROOT-6284
194 // When building with -fmodules, it instantiates all pending instantiations,
195 // instead of delaying them until the end of the translation unit.
196 // We 'got away with' probably because the use and the definition of the
197 // explicit specialization do not occur in the same TU.
198 //
199 // In case we are building with -fmodules, we need to forward declare the
200 // specialization in order to compile the dictionary G__Hist.cxx.
201 template<> void TNDArrayT<double>::Streamer(TBuffer &R__b);
202 template<> TClass *TNDArrayT<double>::Class();
203 
204 
205 #endif // ROOT_TNDArray
TNDArray::GetBin
Long64_t GetBin(const Int_t *idx) const
Definition: TNDArray.h:81
TNDArray::SetAsDouble
virtual void SetAsDouble(ULong64_t linidx, Double_t value)=0
TNDArray::~TNDArray
~TNDArray()
Definition: TNDArray.h:58
TNDArrayT::fData
T * fData
Definition: TNDArray.h:189
Long64_t
long long Long64_t
Definition: RtypesCore.h:73
TNDArrayT::TNDArrayT
TNDArrayT(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:126
Int_t
int Int_t
Definition: RtypesCore.h:45
TNDArray::Reset
virtual void Reset(Option_t *option="")=0
TNDArrayRef::ClassDefNV
ClassDefNV(TNDArrayRef, 0)
TNDArrayT::At
T & At(ULong64_t linidx)
Definition: TNDArray.h:169
TNDArrayT::Streamer
void Streamer(TBuffer &R__b)
TNDArrayT::fNumData
int fNumData
Definition: TNDArray.h:188
TNDArrayT::TNDArrayT
TNDArrayT()
Definition: TNDArray.h:124
TNDArrayT::Class
TClass * Class()
TBuffer
Definition: TBuffer.h:43
TNDArrayRef::fSizes
const Long64_t * fSizes
Definition: TNDArray.h:117
TNDArray::operator=
TNDArray & operator=(const TNDArray &)
TNDArrayRef
Definition: TNDArray.h:99
TNDArrayT
Definition: TNDArray.h:122
Option_t
const typedef char Option_t
Definition: RtypesCore.h:66
TNDArrayT::At
T & At(const Int_t *idx)
Definition: TNDArray.h:162
TNDArray
Definition: TNDArray.h:44
TNDArray::GetCellSize
Long64_t GetCellSize(Int_t dim) const
Definition: TNDArray.h:79
TNDArrayT::AtAsDouble
Double_t AtAsDouble(ULong64_t linidx) const
Definition: TNDArray.h:174
TNDArray::TNDArray
TNDArray()
Definition: TNDArray.h:52
TNDArrayT::operator[]
TNDArrayRef< T > operator[](Int_t idx) const
Definition: TNDArray.h:152
TNDArrayT::Init
void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:135
TNDArrayRef::fData
const T * fData
Definition: TNDArray.h:116
TNDArray::AtAsDouble
virtual Double_t AtAsDouble(ULong64_t linidx) const =0
TNDArray::fNdimPlusOne
Int_t fNdimPlusOne
Definition: TNDArray.h:99
TNDArrayT::~TNDArrayT
~TNDArrayT()
Definition: TNDArray.h:131
TNDArrayT::At
T At(ULong64_t linidx) const
Definition: TNDArray.h:165
TNDArray::GetNbins
Long64_t GetNbins() const
Definition: TNDArray.h:78
TNDArray::GetNdimensions
Int_t GetNdimensions() const
Definition: TNDArray.h:77
ULong64_t
unsigned long long ULong64_t
Definition: RtypesCore.h:74
TNDArray::Init
virtual void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:62
TNDArrayT::AddAt
void AddAt(ULong64_t linidx, Double_t value)
Definition: TNDArray.h:182
TNDArray::fSizes
Long64_t * fSizes
Definition: TNDArray.h:100
Double_t
double Double_t
Definition: RtypesCore.h:59
R__ASSERT
#define R__ASSERT(e)
Definition: TError.h:120
TObject.h
TClass
Definition: TClass.h:80
TObject
Definition: TObject.h:37
ClassDef
#define ClassDef(name, id)
Definition: Rtypes.h:325
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:52
d
#define d(i)
Definition: RSha256.hxx:120
TNDArrayT::SetAsDouble
void SetAsDouble(ULong64_t linidx, Double_t value)
Definition: TNDArray.h:178
TNDArrayRef::TNDArrayRef
TNDArrayRef(const T *data, const Long64_t *sizes)
Definition: TNDArray.h:101
TNDArrayRef::operator[]
TNDArrayRef< T > operator[](Int_t idx) const
Definition: TNDArray.h:104
TNDArray::AddAt
virtual void AddAt(ULong64_t linidx, Double_t value)=0
TNDArrayT::At
T At(const Int_t *idx) const
Definition: TNDArray.h:159
TNDArrayT::Reset
void Reset(Option_t *="")
Definition: TNDArray.h:142
int
TError.h