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
44class TNDArray: public TObject {
45public:
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
88private:
89 TNDArray(const TNDArray&); // intentionally not implemented
90 TNDArray& operator=(const TNDArray&); // intentionally not implemented
91
92protected:
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
98template <typename T>
100public:
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
115private:
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
121template <typename T>
122class TNDArrayT: public TNDArray {
123public:
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
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
187protected:
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.
203
204
205#endif // ROOT_TNDArray
#define d(i)
Definition: RSha256.hxx:102
double Double_t
Definition: RtypesCore.h:57
long long Long64_t
Definition: RtypesCore.h:71
unsigned long long ULong64_t
Definition: RtypesCore.h:72
const char Option_t
Definition: RtypesCore.h:64
#define ClassDef(name, id)
Definition: Rtypes.h:322
#define R__ASSERT(e)
Definition: TError.h:96
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
TNDArrayRef< T > operator[](Int_t idx) const
Definition: TNDArray.h:104
TNDArrayRef(const T *data, const Long64_t *sizes)
Definition: TNDArray.h:101
const Long64_t * fSizes
Definition: TNDArray.h:117
const T * fData
Definition: TNDArray.h:116
ClassDefNV(TNDArrayRef, 0)
int fNumData
Definition: TNDArray.h:188
void Reset(Option_t *="")
Definition: TNDArray.h:142
T & At(const Int_t *idx)
Definition: TNDArray.h:162
T & At(ULong64_t linidx)
Definition: TNDArray.h:169
TNDArrayRef< T > operator[](Int_t idx) const
Definition: TNDArray.h:152
void AddAt(ULong64_t linidx, Double_t value)
Definition: TNDArray.h:182
void Streamer(TBuffer &R__b)
Double_t AtAsDouble(ULong64_t linidx) const
Definition: TNDArray.h:174
TNDArrayT(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:126
void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:135
T At(ULong64_t linidx) const
Definition: TNDArray.h:165
T * fData
Definition: TNDArray.h:189
void SetAsDouble(ULong64_t linidx, Double_t value)
Definition: TNDArray.h:178
~TNDArrayT()
Definition: TNDArray.h:131
T At(const Int_t *idx) const
Definition: TNDArray.h:159
TNDArrayT()
Definition: TNDArray.h:124
TClass * Class()
~TNDArray()
Definition: TNDArray.h:52
TNDArray()
Definition: TNDArray.h:46
TNDArray(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:48
virtual void AddAt(ULong64_t linidx, Double_t value)=0
virtual Double_t AtAsDouble(ULong64_t linidx) const =0
Long64_t * fSizes
Definition: TNDArray.h:94
Long64_t GetNbins() const
Definition: TNDArray.h:72
TNDArray & operator=(const TNDArray &)
Long64_t GetCellSize(Int_t dim) const
Definition: TNDArray.h:73
Long64_t GetBin(const Int_t *idx) const
Definition: TNDArray.h:75
virtual void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:56
virtual void Reset(Option_t *option="")=0
virtual void SetAsDouble(ULong64_t linidx, Double_t value)=0
Int_t fNdimPlusOne
Definition: TNDArray.h:93
Int_t GetNdimensions() const
Definition: TNDArray.h:71
TNDArray(const TNDArray &)
Mother of all ROOT objects.
Definition: TObject.h:37
double T(double x)
Definition: ChebyshevPol.h:34