/usr/include/root/TNDArray.h is in libroot-hist-dev 5.34.30-0ubuntu8.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | // @(#)root/hist:$Id$
// Author: Axel Naumann, Nov 2011
/*************************************************************************
* Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TNDArray
#define ROOT_TNDArray
#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_TError
#include "TError.h"
#endif
//////////////////////////////////////////////////////////////////////////
// //
// TNDArray //
// //
// N-Dim array class. //
// //
// Storage layout: //
// Assume 3 dimensions, array sizes 2, 4 and 3 i.e. 24 bins: //
// Data is stored as [0,0,0], [0,0,1], [0,0,2], [0,1,0],... //
// //
// fSizes stores the combined size of each bin in a dimension, i.e. in //
// above example it would contain 24, 12, 3, 1. //
// //
// Storage is allocated lazily, only when data is written to the array. //
// //
// TNDArrayRef gives access to a sub-dimension, e.g. arr[0][1] in above //
// three-dimensional example, up to an element with conversion operator //
// to double: double value = arr[0][1][2]; //
// //
//////////////////////////////////////////////////////////////////////////
// Array layout:
// nbins[0] = 2, nbins[1] = 4, nbins[2] = 3 => 24 bins
//
// fSizes: 24, 12, 3 [, 1
class TNDArray: public TObject {
public:
TNDArray(): fNdimPlusOne(), fSizes() {}
TNDArray(Int_t ndim, const Int_t* nbins, bool addOverflow = false):
fNdimPlusOne(), fSizes() {
TNDArray::Init(ndim, nbins, addOverflow);
}
~TNDArray() {
delete[] fSizes;
}
virtual void Init(Int_t ndim, const Int_t* nbins, bool addOverflow = false) {
// Calculate fSize based on ndim dimensions, nbins for each dimension,
// possibly adding over- and underflow bin to each dimensions' nbins.
delete[] fSizes;
fNdimPlusOne = ndim + 1;
fSizes = new Long64_t[ndim + 1];
Int_t overBins = addOverflow ? 2 : 0;
fSizes[ndim] = 1;
for (Int_t i = 0; i < ndim; ++i) {
fSizes[ndim - i - 1] = fSizes[ndim - i] * (nbins[ndim - i - 1] + overBins);
}
}
virtual void Reset(Option_t* option = "") = 0;
Int_t GetNdimensions() const { return fNdimPlusOne - 1; }
Long64_t GetNbins() const { return fSizes[0]; }
Long64_t GetCellSize(Int_t dim) const { return fSizes[dim + 1]; }
Long64_t GetBin(const Int_t* idx) const {
// Get the linear bin number for each dimension's bin index
Long64_t bin = idx[fNdimPlusOne - 2];
for (Int_t d = 0; d < fNdimPlusOne - 2; ++d) {
bin += fSizes[d + 1] * idx[d];
}
return bin;
}
virtual Double_t AtAsDouble(ULong64_t linidx) const = 0;
virtual void SetAsDouble(ULong64_t linidx, Double_t value) = 0;
virtual void AddAt(ULong64_t linidx, Double_t value) = 0;
private:
TNDArray(const TNDArray&); // intentionally not implemented
TNDArray& operator=(const TNDArray&); // intentionally not implemented
protected:
Int_t fNdimPlusOne; // Number of dimensions plus one
Long64_t* fSizes; //[fNdimPlusOne] bin count
ClassDef(TNDArray, 1); //Base for n-dimensional array
};
template <typename T>
class TNDArrayRef {
public:
TNDArrayRef(const T* data, const Long64_t* sizes):
fData(data), fSizes(sizes) {}
TNDArrayRef<T> operator[] (Int_t idx) const {
if (!fData) return TNDArrayRef<T>(0, 0);
R__ASSERT(idx < fSizes[-1] / fSizes[0] && "index out of range!");
return TNDArrayRef<T>(fData + idx * fSizes[0], (fSizes[0] == 1) ? 0 : (fSizes + 1));
}
operator T() const {
if (!fData) return T();
R__ASSERT(fSizes == 0 && "Element operator can only be used on non-array element. Missing an operator[] level?");
return *fData;
}
private:
const T* fData; // pointer into TNDArray's fData
const Long64_t* fSizes; // pointer into TNDArray's fSizes
ClassDefNV(TNDArrayRef, 0); // subdimension of a TNDArray
};
template <typename T>
class TNDArrayT: public TNDArray {
public:
TNDArrayT(): fNumData(), fData() {}
TNDArrayT(Int_t ndim, const Int_t* nbins, bool addOverflow = false):
TNDArray(ndim, nbins, addOverflow),
fNumData(), fData() {
fNumData = fSizes[0];
}
~TNDArrayT() {
delete[] fData;
}
void Init(Int_t ndim, const Int_t* nbins, bool addOverflow = false) {
delete[] fData;
fData = 0;
TNDArray::Init(ndim, nbins, addOverflow);
fNumData = fSizes[0];
}
void Reset(Option_t* /*option*/ = "") {
// Reset the content
// Use placement-new with value initialization:
if (fData) {
new (fData) T[fNumData]();
}
}
#ifndef __CINT__
TNDArrayRef<T> operator[](Int_t idx) const {
if (!fData) return TNDArrayRef<T>(0, 0);
R__ASSERT(idx < fSizes[0] / fSizes[1] && "index out of range!");
return TNDArrayRef<T>(fData + idx * fSizes[1], fSizes + 2);
}
#endif // __CINT__
T At(const Int_t* idx) const {
return At(GetBin(idx));
}
T& At(const Int_t* idx) {
return At(GetBin(idx));
}
T At(ULong64_t linidx) const {
if (!fData) return T();
return fData[linidx];
}
T& At(ULong64_t linidx) {
if (!fData) fData = new T[fNumData]();
return fData[linidx];
}
Double_t AtAsDouble(ULong64_t linidx) const {
if (!fData) return 0.;
return fData[linidx];
}
void SetAsDouble(ULong64_t linidx, Double_t value) {
if (!fData) fData = new T[fNumData]();
fData[linidx] = (T) value;
}
void AddAt(ULong64_t linidx, Double_t value) {
if (!fData) fData = new T[fNumData]();
fData[linidx] += (T) value;
}
protected:
int fNumData; // number of bins, product of fSizes
T* fData; //[fNumData] data
ClassDef(TNDArray, 1); // N-dimensional array
};
#endif // ROOT_TNDArray
|