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/** \class TNDArray
19
20N-Dim array class.
21
22Storage layout:
23Assume 3 dimensions, array sizes 2, 4 and 3 i.e. 24 bins:
24Data is stored as [0,0,0], [0,0,1], [0,0,2], [0,1,0],...
25
26fSizes stores the combined size of each bin in a dimension, i.e. in
27above example it would contain 24, 12, 3, 1.
28
29Storage is allocated lazily, only when data is written to the array.
30*/
31
32
33/** \class TNDArrayRef
34
35gives access to a sub-dimension, e.g. arr[0][1] in above
36three-dimensional example, up to an element with conversion operator
37to double: double value = arr[0][1][2];
38*/
39
40
41// Array layout:
42// nbins[0] = 2, nbins[1] = 4, nbins[2] = 3 => 24 bins
43//
44// fSizes: 24, 12, 3 [, 1
45
46class TNDArray: public TObject {
47public:
49
50 TNDArray(Int_t ndim, const Int_t *nbins, bool addOverflow = false) : fSizes()
51 {
52 TNDArray::Init(ndim, nbins, addOverflow);
53 }
54
55 virtual void Init(Int_t ndim, const Int_t* nbins, bool addOverflow = false) {
56 // Calculate fSize based on ndim dimensions, nbins for each dimension,
57 // possibly adding over- and underflow bin to each dimensions' nbins.
58 fSizes.resize(ndim + 1);
59 Int_t overBins = addOverflow ? 2 : 0;
60 fSizes[ndim] = 1;
61 for (Int_t i = 0; i < ndim; ++i) {
62 fSizes[ndim - i - 1] = fSizes[ndim - i] * (nbins[ndim - i - 1] + overBins);
63 }
64 }
65
66 virtual void Reset(Option_t* option = "") = 0;
67
68 Int_t GetNdimensions() const { return fSizes.size() - 1; }
69 Long64_t GetNbins() const { return fSizes[0]; }
70 Long64_t GetCellSize(Int_t dim) const { return fSizes[dim + 1]; }
71
72 Long64_t GetBin(const Int_t* idx) const {
73 // Get the linear bin number for each dimension's bin index
74 Long64_t bin = idx[fSizes.size() - 2];
75 for (unsigned int d = 0; d < fSizes.size() - 2; ++d) {
76 bin += fSizes[d + 1] * idx[d];
77 }
78 return bin;
79 }
80
81 virtual Double_t AtAsDouble(ULong64_t linidx) const = 0;
82 virtual void SetAsDouble(ULong64_t linidx, Double_t value) = 0;
83 virtual void AddAt(ULong64_t linidx, Double_t value) = 0;
84
85protected:
86 std::vector<Long64_t> fSizes; ///< bin count
87 ClassDefOverride(TNDArray, 2); ///< Base for n-dimensional array
88};
89
90template <typename T>
92public:
93 TNDArrayRef(const T* data, const Long64_t* sizes):
94 fData(data), fSizes(sizes) {}
95
97 if (!fData) return TNDArrayRef<T>(0, 0);
98 R__ASSERT(idx < fSizes[-1] / fSizes[0] && "index out of range!");
99 return TNDArrayRef<T>(fData + idx * fSizes[0], (fSizes[0] == 1) ? 0 : (fSizes + 1));
100 }
101 operator T() const {
102 if (!fData) return T();
103 R__ASSERT(fSizes == 0 && "Element operator can only be used on non-array element. Missing an operator[] level?");
104 return *fData;
105 }
106
107private:
108 const T* fData; ///< Pointer into TNDArray's fData
109 const Long64_t* fSizes; ///< Pointer into TNDArray's fSizes
110 ClassDefNV(TNDArrayRef, 0); ///< Subdimension of a TNDArray
111};
112
113template <typename T>
114class TNDArrayT: public TNDArray {
115public:
117
118 TNDArrayT(Int_t ndim, const Int_t *nbins, bool addOverflow = false) : TNDArray(ndim, nbins, addOverflow), fData() {}
119
120 void Init(Int_t ndim, const Int_t* nbins, bool addOverflow = false) override {
121 fData.clear();
122 TNDArray::Init(ndim, nbins, addOverflow);
123 }
124
125 void Reset(Option_t* /*option*/ = "") override {
126 // Reset the content
127 fData.assign(fSizes[0], T());
128 }
129
130#ifndef __CINT__
132 if (!fData) return TNDArrayRef<T>(0, 0);
133 R__ASSERT(idx < fSizes[0] / fSizes[1] && "index out of range!");
134 return TNDArrayRef<T>(fData.data() + idx * fSizes[1], fSizes.data() + 2);
135 }
136#endif // __CINT__
137
138 T At(const Int_t* idx) const {
139 return At(GetBin(idx));
140 }
141 T& At(const Int_t* idx) {
142 return At(GetBin(idx));
143 }
144 T At(ULong64_t linidx) const {
145 if (fData.empty())
146 return T();
147 return fData[linidx];
148 }
149 T& At(ULong64_t linidx) {
150 if (fData.empty())
151 fData.resize(fSizes[0], T());
152 return fData[linidx];
153 }
154
155 Double_t AtAsDouble(ULong64_t linidx) const override {
156 if (fData.empty())
157 return 0.;
158 return fData[linidx];
159 }
160 void SetAsDouble(ULong64_t linidx, Double_t value) override {
161 if (fData.empty())
162 fData.resize(fSizes[0], T());
163 fData[linidx] = (T) value;
164 }
165 void AddAt(ULong64_t linidx, Double_t value) override {
166 if (fData.empty())
167 fData.resize(fSizes[0], T());
168 fData[linidx] += (T) value;
169 }
170
171protected:
172 std::vector<T> fData; // data
173 ClassDefOverride(TNDArrayT, 2); // N-dimensional array
174};
175
176// FIXME: Remove once we implement https://sft.its.cern.ch/jira/browse/ROOT-6284
177// When building with -fmodules, it instantiates all pending instantiations,
178// instead of delaying them until the end of the translation unit.
179// We 'got away with' probably because the use and the definition of the
180// explicit specialization do not occur in the same TU.
181//
182// In case we are building with -fmodules, we need to forward declare the
183// specialization in order to compile the dictionary G__Hist.cxx.
184template<> void TNDArrayT<double>::Streamer(TBuffer &R__b);
185template<> TClass *TNDArrayT<double>::Class();
186
187
188#endif // ROOT_TNDArray
#define d(i)
Definition: RSha256.hxx:102
long long Long64_t
Definition: RtypesCore.h:80
unsigned long long ULong64_t
Definition: RtypesCore.h:81
const char Option_t
Definition: RtypesCore.h:66
#define ClassDefNV(name, id)
Definition: Rtypes.h:343
#define ClassDefOverride(name, id)
Definition: Rtypes.h:339
#define R__ASSERT(e)
Definition: TError.h:118
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Buffer base class used for serializing objects.
Definition: TBuffer.h:43
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
gives access to a sub-dimension, e.g.
Definition: TNDArray.h:91
TNDArrayRef< T > operator[](Int_t idx) const
Definition: TNDArray.h:96
TNDArrayRef(const T *data, const Long64_t *sizes)
Definition: TNDArray.h:93
const Long64_t * fSizes
Pointer into TNDArray's fSizes.
Definition: TNDArray.h:109
const T * fData
Pointer into TNDArray's fData.
Definition: TNDArray.h:108
Double_t AtAsDouble(ULong64_t linidx) const override
Definition: TNDArray.h:155
T & At(const Int_t *idx)
Definition: TNDArray.h:141
std::vector< T > fData
Definition: TNDArray.h:172
void Reset(Option_t *="") override
Definition: TNDArray.h:125
T & At(ULong64_t linidx)
Definition: TNDArray.h:149
TNDArrayRef< T > operator[](Int_t idx) const
Definition: TNDArray.h:131
void Streamer(TBuffer &) override
Stream an object of class TObject.
void SetAsDouble(ULong64_t linidx, Double_t value) override
Definition: TNDArray.h:160
void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false) override
Definition: TNDArray.h:120
TNDArrayT(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:118
T At(ULong64_t linidx) const
Definition: TNDArray.h:144
void AddAt(ULong64_t linidx, Double_t value) override
Definition: TNDArray.h:165
static TClass * Class()
T At(const Int_t *idx) const
Definition: TNDArray.h:138
TNDArrayT()
Definition: TNDArray.h:116
N-Dim array class.
Definition: TNDArray.h:46
TNDArray()
Definition: TNDArray.h:48
TNDArray(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:50
virtual void AddAt(ULong64_t linidx, Double_t value)=0
virtual Double_t AtAsDouble(ULong64_t linidx) const =0
Long64_t GetNbins() const
Definition: TNDArray.h:69
std::vector< Long64_t > fSizes
bin count
Definition: TNDArray.h:86
Long64_t GetCellSize(Int_t dim) const
Definition: TNDArray.h:70
Long64_t GetBin(const Int_t *idx) const
Definition: TNDArray.h:72
virtual void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:55
virtual void Reset(Option_t *option="")=0
virtual void SetAsDouble(ULong64_t linidx, Double_t value)=0
Int_t GetNdimensions() const
Definition: TNDArray.h:68
Mother of all ROOT objects.
Definition: TObject.h:37
double T(double x)
Definition: ChebyshevPol.h:34