File indexing completed on 2026-08-06 09:38:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 namespace ACDCGenerator {
0011
0012 template <typename Rnd, typename FncPtr>
0013 inline ACDCGen<Rnd,FncPtr>::ACDCGen(Rnd * r)
0014 : theRnd(r), theNAcc(0), theN(0), theNI(1, 0),
0015 theSumW(1, 0.0), theSumW2(1, 0.0),
0016 theEps(100*std::numeric_limits<double>::epsilon()), theMargin(1.1),
0017 theNTry(100), theMaxTry(10000), useCheapRandom(false), theFunctions(1),
0018 theDimensions(1, 0), thePrimaryCells(1), theSumMaxInts(1, 0.0), theLast(0),
0019 theLastCell(0), theLastF(0.0) {
0020 maxsize = 0;
0021 }
0022
0023 template <typename Rnd, typename FncPtr>
0024 inline ACDCGen<Rnd,FncPtr>::ACDCGen()
0025 : theRnd(0), theNAcc(0), theN(0), theNI(1, 0),
0026 theSumW(1, 0.0), theSumW2(1, 0.0),
0027 theEps(100*std::numeric_limits<double>::epsilon()), theMargin(1.1),
0028 theNTry(100), theMaxTry(10000), useCheapRandom(false), theFunctions(1),
0029 theDimensions(1, 0), thePrimaryCells(1), theSumMaxInts(1, 0.0), theLast(0),
0030 theLastCell(0), theLastF(0.0) {
0031 maxsize = 0;
0032 }
0033
0034 template <typename Rnd, typename FncPtr>
0035 inline ACDCGen<Rnd,FncPtr>::~ACDCGen() {
0036 clear();
0037 }
0038
0039 template <typename Rnd, typename FncPtr>
0040 inline void ACDCGen<Rnd,FncPtr>::setRnd(Rnd * r) {
0041 theRnd = r;
0042 }
0043
0044 template <typename Rnd, typename FncPtr>
0045 inline void ACDCGen<Rnd,FncPtr>::clear() {
0046 theNAcc = 0;
0047 theN = 0;
0048 theNI = vector<long>(1, 0);
0049 theSumW = DVector(1, 0.0);
0050 theSumW2 = DVector(1, 0.0);
0051 theFunctions = FncVector(1);
0052 theDimensions = DimVector(1, 0);
0053 for ( int i = 0, N = thePrimaryCells.size(); i < N; ++i )
0054 delete thePrimaryCells[i];
0055 thePrimaryCells = CellVector(1);
0056 theSumMaxInts = DVector(1, 0.0);
0057 theLast = 0;
0058 theLastCell = 0;
0059 theLastPoint.clear();
0060 theLastF = 0.0;
0061 levels.clear();
0062 }
0063
0064 template <typename Rnd, typename FncPtr>
0065 inline bool ACDCGen<Rnd,FncPtr>::
0066 addFunction(DimType dim, FncPtrType fnc, double maxrat) {
0067 if ( maxrat < 0.0 ) maxrat = 1.0/nTry();
0068 typedef multimap<double,DVector> PointMap;
0069 theLast = theFunctions.size();
0070 theFunctions.push_back(fnc);
0071 theNI.push_back(0);
0072 theSumW.push_back(0.0);
0073 theSumW2.push_back(0.0);
0074 theDimensions.push_back(dim);
0075
0076
0077 DVector x(dim);
0078 PointMap pmap;
0079 long itry = 0;
0080 while ( pmap.size() < nTry() ) {
0081 if ( ++itry > maxTry() ) {
0082 thePrimaryCells.push_back(new ACDCGenCell(0.0));
0083 theSumMaxInts.push_back(theSumMaxInts.back() + cells().back()->doMaxInt());
0084 return false;
0085 }
0086 rnd(dim, x);
0087 double val = FncTraits::value(fnc, x);
0088 if ( val > 0.0 ) {
0089 pmap.insert(make_pair(val, x));
0090 itry = 0;
0091 }
0092 }
0093
0094
0095
0096 double minf = pmap.begin()->first;
0097 double maxf = (--pmap.end())->first;
0098 minf = max(minf, maxrat*maxf);
0099
0100 thePrimaryCells.push_back(new ACDCGenCell(minf));
0101 theLastF = pmap.begin()->first;
0102 pmap.erase(pmap.begin());
0103 theSumMaxInts.push_back(theSumMaxInts.back() + cells().back()->doMaxInt());
0104
0105
0106
0107 theLastF = (--pmap.end())->first;
0108 theLastPoint = (--pmap.end())->second;
0109 pmap.erase(--pmap.end());
0110 DVector up(dim, 1.0);
0111 DVector lo(dim, 0.0);
0112 theLastCell = cells().back()->getCell(lo, lastPoint(), up);
0113 if ( lastF() > lastCell()->g() ) {
0114 compensate(lo, up);
0115 levels.clear();
0116 }
0117
0118
0119
0120
0121 while ( !pmap.empty() ) {
0122 theLastPoint = pmap.begin()->second;
0123 theLastF = pmap.begin()->first;
0124 pmap.erase(pmap.begin());
0125 DVector up(dim, 1.0);
0126 DVector lo(dim, 0.0);
0127 theLastCell = cells().back()->getCell(lo, lastPoint(), up);
0128 if ( lastF() > lastCell()->g() ) {
0129 compensate(lo, up);
0130 levels.clear();
0131 }
0132 }
0133
0134 return true;
0135 }
0136
0137 template <typename Rnd, typename FncPtr>
0138 inline void ACDCGen<Rnd,FncPtr>::chooseCell(DVector & lo, DVector & up) {
0139 if ( compensating() ) {
0140
0141 up = levels.back().up;
0142 lo = levels.back().lo;
0143 theLastCell = levels.back().cell;
0144 theLast = levels.back().index;
0145 } else {
0146
0147
0148 theLast = upper_bound(sumMaxInts().begin(), sumMaxInts().end(),
0149 rnd()*sumMaxInts().back())
0150 - sumMaxInts().begin();
0151 if(theLast>=sumMaxInts().size()) {
0152 throw ThePEG::Exception() << "Selected a function outside the allowed range"
0153 << " in ACDCGen::chooseCell(). This is usually due"
0154 << " to a floating point error (nan or inf) in the"
0155 << " calculation of the weight"
0156 << ThePEG::Exception::abortnow;
0157 }
0158 up = DVector(lastDimension(), 1.0);
0159 lo = DVector(lastDimension(), 0.0);
0160 theLastCell = lastPrimary();
0161 }
0162
0163
0164 if ( cheapRandom() ) {
0165 theLastCell = lastCell()->generate(lo, up, theRnd);
0166 } else {
0167 DVector rndv(lastDimension());
0168 rnd(lastDimension(), rndv);
0169 theLastCell = lastCell()->generate(lo, up, rndv);
0170 }
0171 }
0172
0173 template <typename Rnd, typename FncPtr>
0174 inline typename ACDCGen<Rnd,FncPtr>::FncPtrType
0175 ACDCGen<Rnd,FncPtr>::generate() {
0176 long itry = 0;
0177 while ( true ) {
0178 if ( ++itry > maxTry() ) return FncPtrType();
0179 ++theN;
0180
0181
0182 DVector up;
0183 DVector lo;
0184 chooseCell(lo, up);
0185
0186
0187 DimType D = lastDimension();
0188 theLastPoint.resize(D);
0189 for ( DimType d = 0; d < D; ++d ) theLastPoint[d] = rnd(lo[d], up[d]);
0190
0191
0192 theLastF = FncTraits::value(lastFunction(), theLastPoint);
0193 if ( theLastF <= 0.0 ) continue;
0194
0195
0196
0197 if ( compensating() && lastF() < levels.back().g ) theLastF = 0.0;
0198
0199 double w = lastF()/lastCell()->g();
0200 if ( w > 1.0 ) {
0201
0202
0203 --theN;
0204 compensate(lo, up);
0205 continue;
0206 }
0207
0208
0209
0210 theSumW[last()] += w;
0211 theSumW2[last()] += w*w;
0212 ++theNI[last()];
0213 if ( w > rnd() ) {
0214 ++theNAcc;
0215 return lastFunction();
0216 }
0217 }
0218 }
0219
0220 template <typename Rnd, typename FncPtr>
0221 inline void ACDCGen<Rnd,FncPtr>::reject() {
0222 theSumW[last()] -= 1.0;
0223 theSumW2[last()] -= 1.0;
0224 --theNAcc;
0225 }
0226
0227 template <typename Rnd, typename FncPtr>
0228 inline bool ACDCGen<Rnd,FncPtr>::compensating() {
0229 while ( levels.size() && levels.back().lastN < N() ) levels.pop_back();
0230
0231
0232 return !levels.empty();
0233 }
0234
0235 template <typename Rnd, typename FncPtr>
0236 inline long ACDCGen<Rnd,FncPtr>::compleft() const {
0237 if ( levels.empty() ) return 0;
0238 long left = 1;
0239 for ( int i = 0, Ni = levels.size(); i < Ni; ++i )
0240 left = max(left, levels[i].lastN - N());
0241
0242 return left;
0243 }
0244
0245 template <typename Rnd, typename FncPtr>
0246 inline void ACDCGen<Rnd,FncPtr>::
0247 compensate(const DVector & lo, const DVector & up) {
0248
0249
0250 double i0 = maxInt();
0251 Level level;
0252 level.g = lastCell()->g();
0253
0254
0255
0256 Slicer slicer(lastDimension(), *this, lo, up);
0257 level.cell = slicer.first;
0258 level.index = last();
0259 level.up = slicer.firstup;
0260 level.lo = slicer.firstlo;
0261
0262
0263
0264 double rat = (doMaxInt())/i0;
0265 level.lastN = long(N()*rat);
0266
0267
0268
0269 for ( size_type i = 0; i < levels.size(); ++i )
0270 levels[i].lastN = long(levels[i].lastN*rat);
0271 levels.insert(levels.end(), level);
0272 maxsize = std::max(maxsize, levels.size());
0273 }
0274
0275 template <typename Rnd, typename FncPtr>
0276 inline void ACDCGen<Rnd,FncPtr>::eps(double newEps) {
0277 theEps = newEps;
0278 }
0279
0280 template <typename Rnd, typename FncPtr>
0281 inline void ACDCGen<Rnd,FncPtr>::margin(double newMargin) {
0282 theMargin = newMargin;
0283 }
0284
0285 template <typename Rnd, typename FncPtr>
0286 inline long ACDCGen<Rnd,FncPtr>::N() const {
0287 return theN;
0288 }
0289
0290 template <typename Rnd, typename FncPtr>
0291 inline long ACDCGen<Rnd,FncPtr>::n() const {
0292 return theNAcc;
0293 }
0294
0295 template <typename Rnd, typename FncPtr>
0296 inline typename ACDCGen<Rnd,FncPtr>::size_type
0297 ACDCGen<Rnd,FncPtr>::nTry() const {
0298 return theNTry;
0299 }
0300
0301 template <typename Rnd, typename FncPtr>
0302 inline void ACDCGen<Rnd,FncPtr>::nTry(size_type newNTry) {
0303 theNTry = newNTry;
0304 }
0305
0306 template <typename Rnd, typename FncPtr>
0307 inline long ACDCGen<Rnd,FncPtr>::maxTry() const {
0308 return theMaxTry;
0309 }
0310
0311 template <typename Rnd, typename FncPtr>
0312 inline void ACDCGen<Rnd,FncPtr>::maxTry(long newMaxTry) {
0313 theMaxTry = newMaxTry;
0314 }
0315
0316 template <typename Rnd, typename FncPtr>
0317 inline bool ACDCGen<Rnd,FncPtr>::cheapRandom() const {
0318 return useCheapRandom;
0319 }
0320
0321 template <typename Rnd, typename FncPtr>
0322 inline void ACDCGen<Rnd,FncPtr>::cheapRandom(bool b) {
0323 useCheapRandom = b;
0324 }
0325
0326 template <typename Rnd, typename FncPtr>
0327 inline double ACDCGen<Rnd,FncPtr>::maxInt() const {
0328 return theSumMaxInts.back();
0329 }
0330
0331 template <typename Rnd, typename FncPtr>
0332 inline double ACDCGen<Rnd,FncPtr>::doMaxInt() {
0333 for ( size_type i = 1, imax = functions().size(); i < imax; ++i )
0334 theSumMaxInts[i] = sumMaxInts()[i - 1] + cells()[i]->doMaxInt();
0335 return maxInt();
0336 }
0337
0338 template <typename Rnd, typename FncPtr>
0339 inline int ACDCGen<Rnd,FncPtr>::nBins() const {
0340 int sum = 0;
0341 for ( size_type i = 1; i < functions().size(); ++i )
0342 sum += cell(i)->nBins();
0343 return sum;
0344 }
0345
0346 template <typename Rnd, typename FncPtr>
0347 inline int ACDCGen<Rnd,FncPtr>::depth() const {
0348 int mx = 0;
0349 for ( size_type i = 1; i < functions().size(); ++i )
0350 mx = max(mx, cell(i)->depth());
0351 return mx;
0352 }
0353
0354 template <typename Rnd, typename FncPtr>
0355 inline double ACDCGen<Rnd,FncPtr>::efficiency() const {
0356 return N() > 0? double(n())/double(N()): 0.0;
0357 }
0358
0359 template <typename Rnd, typename FncPtr>
0360 inline double ACDCGen<Rnd,FncPtr>::integral(FncPtrType f) const {
0361 if ( N() <= 0 ) return maxInt();
0362 double sumw = 0.0;
0363 for ( size_type i = 1; i < functions().size(); ++i )
0364 if ( functions()[i] == f || !f ) sumw += theSumW[i];
0365 return maxInt()*sumw/N();
0366 }
0367
0368 template <typename Rnd, typename FncPtr>
0369 inline double ACDCGen<Rnd,FncPtr>::integralErr(FncPtrType f) const {
0370 if ( N() <= 0 ) return maxInt();
0371 double sumw2 = 0.0;
0372 double sumw = 0.0;
0373 for ( size_type i = 1; i < functions().size(); ++i )
0374 if ( functions()[i] == f || !f ) {
0375 sumw2 += theSumW2[i];
0376 sumw += theSumW[i];
0377 }
0378 if ( f ) return maxInt()*sqrt(sumw2)/N();
0379 return maxInt()*sqrt(max(0.,sumw2 - sumw*sumw/N()))/N();
0380 }
0381
0382 template <typename Rnd, typename FncPtr>
0383 inline double ACDCGen<Rnd,FncPtr>::eps() const {
0384 return theEps;
0385 }
0386
0387 template <typename Rnd, typename FncPtr>
0388 inline double ACDCGen<Rnd,FncPtr>::margin() const {
0389 return theMargin;
0390 }
0391
0392 template <typename Rnd, typename FncPtr>
0393 inline double ACDCGen<Rnd,FncPtr>::rnd() const {
0394 return RndTraits::rnd(theRnd);
0395 }
0396
0397 template <typename Rnd, typename FncPtr>
0398 inline double ACDCGen<Rnd,FncPtr>::rnd(double lo, double up) const {
0399 return RndTraits::rnd(theRnd, lo, up);
0400 }
0401
0402 template <typename Rnd, typename FncPtr>
0403 inline void ACDCGen<Rnd,FncPtr>::
0404 rnd(const DVector & lo, const DVector & up, DVector & r) const {
0405 RndTraits::rnd(theRnd, lo.begin(), lo.end(), up.begin(), r.begin());
0406 }
0407
0408 template <typename Rnd, typename FncPtr>
0409 inline void ACDCGen<Rnd,FncPtr>::
0410 rnd(DimType D, DVector & r) const {
0411 RndTraits::rnd(theRnd, D, r.begin());
0412 }
0413
0414 template <typename Rnd, typename FncPtr>
0415 inline long ACDCGen<Rnd,FncPtr>::rndInt(long x) const {
0416 return RndTraits::rndInt(theRnd, x);
0417 }
0418
0419 template <typename Rnd, typename FncPtr>
0420 inline const typename ACDCGen<Rnd,FncPtr>::FncVector &
0421 ACDCGen<Rnd,FncPtr>::functions() const {
0422 return theFunctions;
0423 }
0424
0425 template <typename Rnd, typename FncPtr>
0426 inline typename ACDCGen<Rnd,FncPtr>::FncPtrType
0427 ACDCGen<Rnd,FncPtr>::function(size_type i) const {
0428 return functions()[i];
0429 }
0430
0431 template <typename Rnd, typename FncPtr>
0432 inline typename ACDCGen<Rnd,FncPtr>::FncPtrType
0433 ACDCGen<Rnd,FncPtr>::lastFunction() const {
0434 return function(last());
0435 }
0436
0437 template <typename Rnd, typename FncPtr>
0438 inline const typename ACDCGen<Rnd,FncPtr>::DimVector &
0439 ACDCGen<Rnd,FncPtr>::dimensions() const {
0440 return theDimensions;
0441 }
0442
0443 template <typename Rnd, typename FncPtr>
0444 inline DimType ACDCGen<Rnd,FncPtr>::dimension(size_type i) const {
0445 return dimensions()[i];
0446 }
0447
0448 template <typename Rnd, typename FncPtr>
0449 inline DimType ACDCGen<Rnd,FncPtr>::lastDimension() const {
0450 return dimension(last());
0451 }
0452
0453 template <typename Rnd, typename FncPtr>
0454 inline const typename ACDCGen<Rnd,FncPtr>::CellVector &
0455 ACDCGen<Rnd,FncPtr>::cells() const {
0456 return thePrimaryCells;
0457 }
0458
0459 template <typename Rnd, typename FncPtr>
0460 inline ACDCGenCell * ACDCGen<Rnd,FncPtr>::cell(size_type i) const {
0461 return cells()[i];
0462 }
0463
0464 template <typename Rnd, typename FncPtr>
0465 inline ACDCGenCell * ACDCGen<Rnd,FncPtr>::lastPrimary() const {
0466 return cell(last());
0467 }
0468
0469 template <typename Rnd, typename FncPtr>
0470 inline const DVector & ACDCGen<Rnd,FncPtr>::sumMaxInts() const {
0471 return theSumMaxInts;
0472 }
0473
0474 template <typename Rnd, typename FncPtr>
0475 inline typename ACDCGen<Rnd,FncPtr>::size_type
0476 ACDCGen<Rnd,FncPtr>::last() const {
0477 return theLast;
0478 }
0479
0480 template <typename Rnd, typename FncPtr>
0481 inline typename ACDCGen<Rnd,FncPtr>::size_type
0482 ACDCGen<Rnd,FncPtr>::size() const {
0483 return cells().size() - 1;
0484 }
0485
0486 template <typename Rnd, typename FncPtr>
0487 inline ACDCGenCell * ACDCGen<Rnd,FncPtr>::lastCell() const {
0488 return theLastCell;
0489 }
0490
0491 template <typename Rnd, typename FncPtr>
0492 inline const DVector & ACDCGen<Rnd,FncPtr>::lastPoint() const {
0493 return theLastPoint;
0494 }
0495
0496 template <typename Rnd, typename FncPtr>
0497 inline double ACDCGen<Rnd,FncPtr>::lastF() const {
0498 return theLastF;
0499 }
0500
0501 template <typename Rnd, typename FncPtr>
0502 typename ACDCGen<Rnd,FncPtr>::size_type ACDCGen<Rnd,FncPtr>::maxsize = 0;
0503
0504 template <typename Rnd, typename FncPtr>
0505 vector<ACDCGenCellInfo> ACDCGen<Rnd,FncPtr>::extractCellInfo() const {
0506 vector<ACDCGenCellInfo> ret;
0507 for ( size_type i = 1; i < cells().size(); ++i ) {
0508 DVector lo(dimension(i), 0.0);
0509 DVector up(dimension(i), 1.0);
0510 cell(i)->extract(lo, up, ret);
0511 }
0512 return ret;
0513 }
0514
0515 template <typename Rnd, typename FncPtr>
0516 ACDCGen<Rnd,FncPtr>::Slicer::
0517 Slicer(DimType Din, ACDCGen & gen, const DVector & loin, const DVector & upin)
0518 : D(Din), lo(loin), up(upin), xcl(loin), xcu(upin), xhl(loin), xhu(upin),
0519 fhl(Din, 0.0), fhu(Din, 0.0), xsel(gen.lastPoint()), fsel(gen.lastF()),
0520 current(gen.lastCell()), first(gen.lastCell()),
0521 firstlo(loin), firstup(upin),f(gen.lastFunction()),
0522 epsilon(gen.eps()), margin(gen.margin()), minf(0.0), wholecomp(false) {
0523 divideandconquer();
0524 }
0525
0526 template <typename Rnd, typename FncPtr>
0527 ACDCGen<Rnd,FncPtr>::Slicer::~Slicer() {
0528
0529 }
0530
0531 template <typename Rnd, typename FncPtr>
0532 void ACDCGen<Rnd,FncPtr>::Slicer::divideandconquer() {
0533
0534
0535
0536 if ( fsel < current->g()*margin ) {
0537 current->g(current->g()*margin);
0538 return;
0539 }
0540
0541
0542
0543 init();
0544 slice();
0545 if ( !wholecomp ) {
0546 first = current;
0547 firstlo = lo;
0548 firstup = up;
0549 }
0550
0551
0552
0553
0554 while ( shiftmaxmin() > current->g() ) {
0555 current->g(minf*margin);
0556 if ( current->g() > fsel ) return;
0557 init();
0558 slice();
0559 }
0560 }
0561
0562 template <typename Rnd, typename FncPtr>
0563 double ACDCGen<Rnd,FncPtr>::Slicer::shiftmaxmin() {
0564
0565 DVector test = xsel;
0566 double scale = 0.0;
0567 for ( DimType d = 0; d < D; ++d )
0568 if ( fhl[d] > fsel || fhu[d] > fsel ) scale += 1.0;
0569 scale = sqrt(scale);
0570 for ( DimType d = 0; d < D; ++d ) {
0571 if ( fhl[d] > fsel && fhl[d] > fhu[d] )
0572 test[d] = test[d] + (xhl[d] - test[d])/scale;
0573 if ( fhu[d] > fsel && fhu[d] > fhl[d] )
0574 test[d] = test[d] + (xhu[d] - test[d])/scale;
0575 }
0576
0577
0578 DimType dsel = -1;
0579 double x = 0;
0580 minf = fsel;
0581 for ( DimType d = 0; d < D; ++d ) {
0582
0583
0584
0585 minf = std::min(minf, fhl[d]);
0586 minf = std::min(minf, fhu[d]);
0587
0588
0589
0590 if ( fhu[d] > fsel ) {
0591 fsel = fhu[d];
0592 dsel = d;
0593 x = xhu[d];
0594 }
0595 if ( fhl[d] > fsel ) {
0596 fsel = fhl[d];
0597 dsel = d;
0598 x = xhl[d];
0599 }
0600 }
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610 if ( dsel >= 0 ) xsel[dsel] = x;
0611 minf = std::max(minf, current->g());
0612 return fsel;
0613 }
0614
0615 template <typename Rnd, typename FncPtr>
0616 void ACDCGen<Rnd,FncPtr>::Slicer::dohalf(DimType d) {
0617 xcl[d] = lo[d];
0618
0619
0620
0621
0622
0623
0624 while ( true ) {
0625 xhl[d] = (xsel[d] + xcl[d])*0.5;
0626
0627 std::swap(xsel[d], xhl[d]);
0628 fhl[d] = FncTraits::value(f, xsel);
0629 std::swap(xsel[d], xhl[d]);
0630
0631 if ( fhl[d] > current->g() ) break;
0632 if ( xsel[d] - xcl[d] < epsilon ) break;
0633
0634 xcl[d] = xhl[d];
0635 }
0636
0637
0638 double cut = ( up[d] - xcl[d] )/( up[d] - lo[d] );
0639 if ( cut < 1.0 - current->g()/fsel && cut > 0.0 )
0640 rateslice.insert(std::make_pair(cut, -1-d));
0641
0642
0643
0644
0645
0646
0647 xcu[d] = up[d];
0648 while ( true ) {
0649 xhu[d] = (xsel[d] + xcu[d])*0.5;
0650
0651 std::swap(xsel[d], xhu[d]);
0652 fhu[d] = FncTraits::value(f, xsel);
0653 std::swap(xsel[d], xhu[d]);
0654
0655 if ( fhu[d] > current->g() ) break;
0656 if ( xcu[d] - xsel[d] < epsilon ) break;
0657
0658 xcu[d] = xhu[d];
0659 }
0660
0661
0662 cut = ( xcu[d] - lo[d] )/( up[d] - lo[d] );
0663 if ( cut < 1.0 - current->g()/fsel && cut > 0.0 )
0664 rateslice.insert(std::make_pair(cut, 1+d));
0665
0666 }
0667
0668 template <typename Rnd, typename FncPtr>
0669 void ACDCGen<Rnd,FncPtr>::Slicer::init() {
0670 for ( DimType d = 0; d < D; ++d ) dohalf(d);
0671 }
0672
0673 template <typename Rnd, typename FncPtr>
0674 void ACDCGen<Rnd,FncPtr>::Slicer::slice() {
0675 while ( !rateslice.empty() ) {
0676
0677
0678 DimType d = rateslice.begin()->second;
0679 rateslice.erase(rateslice.begin());
0680 if ( d > 0 ) {
0681
0682 d = d - 1;
0683 current->splitme(lo[d], xcu[d], up[d], d);
0684 checkdiag(current->upper(), d, xcu[d], up[d]);
0685 current = current->lower();
0686 up[d] = xcu[d];
0687 } else {
0688
0689 d = -d - 1;
0690 current->splitme(lo[d], xcl[d], up[d], d);
0691 checkdiag(current->lower(), d, lo[d], xcl[d]);
0692 current = current->upper();
0693 lo[d] = xcl[d];
0694 }
0695 dohalf(d);
0696 }
0697 }
0698
0699 template <typename Rnd, typename FncPtr>
0700 void ACDCGen<Rnd,FncPtr>::Slicer::
0701 checkdiag(ACDCGenCell * cell, DimType dc, double lod, double upd) {
0702 return;
0703
0704
0705 if ( upd - lod <= epsilon ) return;
0706 DVector newlo = lo;
0707 DVector newup = up;
0708 newlo[dc] = lod;
0709 newup[dc] = upd;
0710 DVector newsel = xsel;
0711 newsel[dc] = 0.5*(lod + upd);
0712 double newfsel = FncTraits::value(f, newsel);
0713 double newfh = newfsel;
0714 DVector newxsel = newsel;
0715 vector<int> dir(D, 0);
0716
0717
0718
0719
0720 for ( DimType d = 0; d < D; ++d ) {
0721 if ( d == dc ) continue;
0722 double xdum = 0.5*(newlo[d] + newsel[d]);
0723 swap(xdum, newsel[d]);
0724 double fh1 = FncTraits::value(f, newsel);
0725 if ( fh1 > newfsel ) {
0726 newfsel = fh1;
0727 newxsel = newsel;
0728 }
0729 if ( fh1 > newfh ) dir[d] = -1;
0730 swap(xdum, newsel[d]);
0731 xdum = 0.5*(newsel[d] + newup[d]);
0732 swap(xdum, newsel[d]);
0733 double fh2 = FncTraits::value(f, newsel);
0734 if ( fh2 > newfsel ) {
0735 newfsel = fh2;
0736 newxsel = newsel;
0737 }
0738 if ( fh2 > newfh && fh2 > fh1 ) dir[d] = 1;
0739 swap(xdum, newsel[d]);
0740 }
0741
0742
0743 for ( DimType d = 0; d < D; ++d ) {
0744 if ( dir[d] == 0 ) continue;
0745 if ( dir[d] > 0 ) newsel[d] = 0.5*(newsel[d] + newup[d]);
0746 else newsel[d] = 0.5*(newlo[d] + newsel[d]);
0747 }
0748 newfh = FncTraits::value(f, newsel);
0749 if ( newfh > newfsel ) {
0750 newfsel = newfh;
0751 newxsel = newsel;
0752 }
0753
0754 if ( newfsel < cell->g() ) return;
0755
0756
0757
0758 wholecomp = true;
0759 Slicer dummy(D, *this, cell, newlo, newxsel, newup, newfsel);
0760 }
0761
0762 template <typename Rnd, typename FncPtr>
0763 ACDCGen<Rnd,FncPtr>::Slicer::
0764 Slicer(DimType Din, const Slicer & s, ACDCGenCell * cellin,
0765 const DVector & loin, const DVector & xselin, const DVector & upin,
0766 double fselin)
0767 : D(Din), lo(loin), up(upin), xcl(loin), xcu(upin), xhl(loin), xhu(upin),
0768 fhl(Din, 0.0), fhu(Din, 0.0), xsel(xselin), fsel(fselin),
0769 current(cellin), first(cellin),
0770 firstlo(loin), firstup(upin),f(s.f),
0771 epsilon(s.epsilon), margin(s.margin), minf(0.0), wholecomp(false) {
0772 divideandconquer();
0773 }
0774
0775 template <typename Rnd, typename FncPtr>
0776 template <typename POStream>
0777 void ACDCGen<Rnd,FncPtr>::output(POStream & os) const {
0778 os << theNAcc << theN << theEps << theMargin << theNTry << theMaxTry
0779 << useCheapRandom << theLast << theLastPoint << theLastF
0780 << theFunctions.size() << levels.size();
0781 for ( int i = 1, N = theFunctions.size(); i < N; ++i )
0782 os << theFunctions[i] << theDimensions [i] << theSumMaxInts[i]
0783 << *thePrimaryCells[i] << theNI[i] << theSumW[i] << theSumW2[i];
0784 if ( theLast > 0 )
0785 os << thePrimaryCells[theLast]->getIndex(theLastCell);
0786 else
0787 os << -1l;
0788 for ( int i = 0, N = levels.size(); i < N; ++i )
0789 os << levels[i].lastN << levels[i].g << levels[i].index
0790 << levels[i].up << levels[i].lo
0791 << thePrimaryCells[levels[i].index]->getIndex(levels[i].cell);
0792 }
0793
0794 template <typename Rnd, typename FncPtr>
0795 template <typename PIStream>
0796 void ACDCGen<Rnd,FncPtr>::input(PIStream & is) {
0797 clear();
0798 long fsize = 0;
0799 long lsize = 0;
0800 is >> theNAcc >> theN >> theEps >> theMargin >> theNTry >> theMaxTry
0801 >> useCheapRandom >> theLast >> theLastPoint >> theLastF >> fsize >> lsize;
0802 while ( --fsize ) {
0803 theFunctions.push_back(FncPtrType());
0804 theDimensions.push_back(DimType());
0805 theSumMaxInts.push_back(0.0);
0806 theNI.push_back(0);
0807 theSumW.push_back(0.0);
0808 theSumW2.push_back(0.0);
0809 thePrimaryCells.push_back(new ACDCGenCell(0.0));
0810 is >> theFunctions.back() >> theDimensions.back() >> theSumMaxInts.back()
0811 >> *thePrimaryCells.back() >> theNI.back()
0812 >> theSumW.back() >> theSumW2.back();
0813 }
0814 long index = -1;
0815 is >> index;
0816 if ( index == -1 )
0817 theLastCell = 0x0;
0818 else
0819 theLastCell = thePrimaryCells[theLast]->getCell(index);
0820 while ( lsize-- ) {
0821 levels.push_back(Level());
0822 is >> levels.back().lastN >> levels.back().g >> levels.back().index
0823 >> levels.back().up >> levels.back().lo >> index;
0824 levels.back().cell = thePrimaryCells[levels.back().index]->getCell(index);
0825 }
0826 }
0827
0828 }