File indexing completed on 2026-08-06 09:38:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 namespace ACDCGenerator {
0011
0012 inline ACDCGenCell::ACDCGenCell(double newG)
0013 : theG(newG), theV(1.0), theUpper(0), theLower(0),
0014 theDivision(-1.0), theSplitDimension(-1) {}
0015
0016 inline ACDCGenCell::
0017 ACDCGenCell(double newG, double newV)
0018 : theG(newG), theV(newV), theUpper(0), theLower(0),
0019 theDivision(-1.0), theSplitDimension(-1) {}
0020
0021 inline ACDCGenCell::~ACDCGenCell() {
0022 if ( isSplit() ) {
0023 delete theUpper;
0024 delete theLower;
0025 }
0026 }
0027
0028 template <typename RndType>
0029 inline ACDCGenCell * ACDCGenCell::
0030 generate(DVector & lo, DVector & up, RndType * rnd) {
0031 if ( isSplit() ) {
0032 if ( ACDCRandomTraits<RndType>::
0033 rndBool(rnd, upper()->maxInt(), lower()->maxInt()) ) {
0034 lo[dim()] = div();
0035 return upper()->generate(lo, up, rnd);
0036 } else {
0037 up[dim()] = div();
0038 return lower()->generate(lo, up, rnd);
0039 }
0040 }
0041 return this;
0042 }
0043
0044 inline ACDCGenCell * ACDCGenCell::
0045 generate(DVector & lo, DVector & up, DVector & rndv) {
0046 if ( isSplit() ) {
0047 double r = lower()->maxInt()/maxInt();
0048 if ( rndv[dim()] > r ) {
0049 lo[dim()] = div();
0050 rndv[dim()] = (rndv[dim()] - r)/(1.0 - r);
0051 return upper()->generate(lo, up, rndv);
0052 } else {
0053 up[dim()] = div();
0054 rndv[dim()] = rndv[dim()]/r;
0055 return lower()->generate(lo, up, rndv);
0056 }
0057 }
0058 return this;
0059 }
0060
0061 inline ACDCGenCell * ACDCGenCell::
0062 getCell(DVector & lo, const DVector & x, DVector & up) {
0063 if ( isSplit() ) {
0064 if ( x[dim()] > div() ) {
0065 lo[dim()] = div();
0066 return upper()->getCell(lo, x, up);
0067 } else {
0068 up[dim()] = div();
0069 return lower()->getCell(lo, x, up);
0070 }
0071 } else
0072 return this;
0073 }
0074
0075 inline void ACDCGenCell::
0076 splitme(double lo, double newDiv, double up, DimType newDim) {
0077 theSplitDimension = newDim;
0078 theDivision = newDiv;
0079 double frac = (up - div())/(up - lo);
0080 theUpper = new ACDCGenCell(g(), v()*frac);
0081 frac = (div() - lo)/(up - lo);
0082 theLower = new ACDCGenCell(g(), v()*frac);
0083 }
0084
0085 inline bool ACDCGenCell::isSplit() const {
0086 return upper();
0087 }
0088
0089 inline double ACDCGenCell::doMaxInt(double scale) {
0090 if ( isSplit() ) theG = (upper()->doMaxInt() + lower()->doMaxInt())/v();
0091 else theG *= scale;
0092 return maxInt();
0093 }
0094
0095 inline void ACDCGenCell::smooth(double frac) {
0096 if ( !isSplit() ) return;
0097 upper()->smooth(frac);
0098 lower()->smooth(frac);
0099 if ( upper()->maxInt() < lower()->maxInt()*frac &&
0100 upper()->maxInt() > 0.0 )
0101 upper()->doMaxInt(lower()->maxInt()*frac/upper()->maxInt());
0102 else if ( lower()->maxInt() < upper()->maxInt()*frac &&
0103 lower()->maxInt() > 0.0 )
0104 lower()->doMaxInt(upper()->maxInt()*frac/lower()->maxInt());
0105 doMaxInt();
0106 }
0107
0108 inline double ACDCGenCell::maxInt() const {
0109 return g()*v();
0110 }
0111
0112 inline void ACDCGenCell::g(double newG) {
0113 theG = newG;
0114 }
0115
0116 inline int ACDCGenCell::nBins() const {
0117 return isSplit()? upper()->nBins() + lower()->nBins(): 1;
0118 }
0119
0120 inline int ACDCGenCell::depth() const {
0121 return isSplit()? std::max(upper()->depth(), lower()->depth()) + 1: 1;
0122 }
0123
0124 inline double ACDCGenCell::g() const {
0125 return theG;
0126 }
0127
0128 inline double ACDCGenCell::v() const {
0129 return theV;
0130 }
0131
0132 inline double ACDCGenCell::div() const {
0133 return theDivision;
0134 }
0135
0136 inline DimType ACDCGenCell::dim() const {
0137 return theSplitDimension;
0138 }
0139
0140 inline ACDCGenCell * ACDCGenCell::upper() const {
0141 return theUpper;
0142 }
0143
0144 inline ACDCGenCell * ACDCGenCell::lower() const {
0145 return theLower;
0146 }
0147
0148 inline void ACDCGenCell::
0149 extract(DVector & lo, DVector & up, vector<ACDCGenCellInfo> & out) const {
0150
0151
0152 ACDCGenCellInfo::Index isave = out.size();
0153 out.push_back(ACDCGenCellInfo());
0154 out.back().g = g();
0155 out.back().v = v();
0156 out.back().up = up;
0157 out.back().lo = lo;
0158 out.back().iup = 0;
0159 out.back().ilo = 0;
0160
0161 if ( isSplit() ) {
0162
0163 out[isave].iup = out.size();
0164 double save = lo[dim()];
0165 lo[dim()] = div();
0166 upper()->extract(lo, up, out);
0167 lo[dim()] = save;
0168
0169
0170 out[isave].ilo = out.size();
0171 save = up[dim()];
0172 up[dim()] = div();
0173 lower()->extract(lo, up, out);
0174 up[dim()] = save;
0175 }
0176 }
0177
0178 template <typename OStream>
0179 inline OStream & operator<<(OStream & os, const ACDCGenCell & c) {
0180 os << c.dim() << c.div() << c.g() << c.v();
0181 if ( c.dim() < 0 ) return os;
0182 return os << *c.upper() << *c.lower();
0183 }
0184
0185 template <typename IStream>
0186 inline IStream & operator>>(IStream & is, ACDCGenCell & c) {
0187 is >> c.theSplitDimension >> c.theDivision >> c.theG >> c.theV;
0188 if ( c.dim() < 0 ) return is;
0189 c.theUpper = new ACDCGenCell(0.0);
0190 c.theLower = new ACDCGenCell(0.0);
0191 return is >> *c.theUpper >> *c.theLower;
0192 }
0193
0194 inline long ACDCGenCell::getIndex(const ACDCGenCell * c) const {
0195 long indx = -1;
0196 return getIndex(c, indx);
0197 }
0198
0199
0200 inline long ACDCGenCell::getIndex(const ACDCGenCell * c, long & indx) const {
0201 ++indx;
0202 if ( c == this ) return indx;
0203 if ( isSplit() ) {
0204 long i = upper()->getIndex(c, indx);
0205 if ( i >= 0 ) return i;
0206 return lower()->getIndex(c, indx);
0207 }
0208 return -1;
0209 }
0210
0211 inline ACDCGenCell * ACDCGenCell::getCell(long i) {
0212 long indx = -1;
0213 return getCell(i, indx);
0214 }
0215
0216 inline ACDCGenCell * ACDCGenCell::getCell(long i, long & indx) {
0217 ++indx;
0218 if ( i == indx ) return this;
0219 if ( isSplit() ) {
0220 ACDCGenCell * tmp = upper()->getCell(i, indx);
0221 if ( tmp ) return tmp;
0222 return lower()->getCell(i, indx);
0223 }
0224 return 0;
0225 }
0226
0227 }