00001
00023 #include "jbltools/sfh/IntFun.h"
00024 #include "jbltools/sfh/FloatFun.h"
00025 #include "jbltools/sfh/IntFunHelpers.h"
00026 #include "jbltools/sfh/JBLMath.h"
00027
00028 #include <cstdlib>
00029 #include <iostream>
00030 #include <climits>
00031 #include <cmath>
00032
00033 #include <stdio.h>
00034 #include <cstring>
00035 #include <vector>
00036
00037 static const char *ident="@(#)$Id: IntFun.C,v 1.16 2005/11/22 09:00:17 blist Exp $";
00038
00039 FloatIntFun::FloatIntFun(const IntFun& theIntFun_, const char *name_)
00040 : FloatFun (name_ ? name_ : std::string("float(")+theIntFun_.getName()+")"),
00041 theIntFun (theIntFun_)
00042 {}
00043
00044 OneIntFunCompound::OneIntFunCompound (const std::string& funname_, const IntFun& arg_)
00045 : IntFun (funname_+'('+arg_.getName()+')'),
00046 arg (arg_)
00047 {}
00048
00049 ScalarIntFunCompound::ScalarIntFunCompound (int s_, const std::string& opname_, const IntFun& fun_)
00050 : IntFun (str(s_)+opname_+'('+fun_.getName()+')'),
00051 fun (fun_), s (s_)
00052 {
00053 assert(&fun);
00054 }
00055 ScalarIntFunCompound::ScalarIntFunCompound (int s_, const IntFun& fun_, const std::string& name_)
00056 : IntFun (name_),
00057 fun (fun_), s (s_)
00058 {
00059 assert(&fun);
00060 }
00061
00062 ScalarDivisionIntFun2::ScalarDivisionIntFun2 (const IntFun& fun_, int s_)
00063 : ScalarIntFunCompound (s_, fun_, std::string(fun_.getName())+'/'+str(s_))
00064 {}
00065
00066 TwoIntFunCompound::TwoIntFunCompound (const IntFun& lhs_, const std::string& opname_, const IntFun& rhs_)
00067 : IntFun (str('(')+lhs_.getName()+')'+opname_+'('+rhs_.getName()+')'),
00068 lhs (lhs_),
00069 rhs (rhs_)
00070 {
00071 assert (&lhs);
00072 assert (&rhs);
00073 assert (!lhs.getIterator() || !rhs.getIterator() || lhs.getIterator()==rhs.getIterator());
00074 }
00075
00076 const FillIterator *TwoIntFunCompound::getIterator() const {
00077 assert (!lhs.getIterator() || !rhs.getIterator() || lhs.getIterator()==rhs.getIterator());
00078 return (lhs.getIterator()) ? lhs.getIterator() : rhs.getIterator();
00079 }
00080
00081
00082 TwoIntFunComp::TwoIntFunComp (const IntFun& lhs_, const std::string& opname_, const IntFun& rhs_)
00083 : IntFunComp (str('(')+lhs_.getName()+')'+opname_+'('+rhs_.getName()+')'),
00084 lhs (lhs_),
00085 rhs (rhs_)
00086 {
00087 assert (&lhs);
00088 assert (&rhs);
00089 }
00090
00091 IntChainComparison::IntChainComparison (const IntFunComp& lhs_, const std::string& opname_, const IntFun& rhs_)
00092 : IntFunComp (str('(')+lhs_.getName()+')'+opname_+'('+rhs_.getName()+')'),
00093 lhs (lhs_),
00094 rhs (rhs_)
00095 {
00096 assert (&lhs);
00097 assert (&rhs);
00098 }
00099
00100 IntChainCompInt::IntChainCompInt (const IntFunComp& lhs_, const std::string& opname_, int rhs_)
00101 : IntFunComp (str('(')+lhs_.getName()+')'+opname_+str(rhs_)),
00102 lhs (lhs_),
00103 rhs (rhs_)
00104 {
00105 assert (&lhs);
00106 }
00107 IntIntFunComp::IntIntFunComp (int lhs_, const std::string& opname_, const IntFun& rhs_)
00108 : IntFunComp (str(lhs_)+opname_+'('+rhs_.getName()+')'),
00109 lhs (lhs_),
00110 rhs (rhs_)
00111 {
00112 assert (&rhs);
00113 }
00114
00115 IntFunIntComp::IntFunIntComp (const IntFun& lhs_, const std::string& opname_, int rhs_)
00116 : IntFunComp (str('(')+lhs_.getName()+')'+opname_+str(rhs_)),
00117 lhs (lhs_),
00118 rhs (rhs_)
00119 {
00120 assert (&lhs);
00121 }
00122
00123 FloatFun& IntFun::Float () const {
00124 return *new FloatIntFun(*this);
00125 }
00126
00127
00128 CollectiveIntFun::CollectiveIntFun (const std::string& funname_,
00129 const IntFunPoRConst& fun_,
00130 const BaseCutPoRConst& cut_,
00131 const FillIteratorPoR& intiter_,
00132 const FillIteratorPoRConst& extiter_
00133 )
00134 : IntFun (makeName (funname_, fun_, cut_, intiter_, extiter_)),
00135 fun (fun_.pif), cut (cut_.pbc), intiter (intiter_.pfi), extiter (extiter_.pfi)
00136 {
00137 checkIterators();
00138 setName (makeName (funname_, fun, cut, intiter, extiter));
00139 }
00140
00141 std::string CollectiveIntFun::makeName(const std::string& funname_,
00142 const IntFunPoRConst& fun_,
00143 const BaseCutPoRConst& cut_,
00144 const FillIteratorPoR& intiter_,
00145 const FillIteratorPoRConst& extiter_
00146 ){
00147 const char *fname = fun_.pif ? fun_.pif->getName() : 0;
00148 const char *cutname = cut_.pbc ? cut_.pbc->getName() : 0;
00149 const char *intitername = intiter_.pfi ? intiter_.pfi->getName() : 0;
00150 const char *extitername = extiter_.pfi ? extiter_.pfi->getName() : 0;
00151 if (!fname) fname="1";
00152 if (!cutname) cutname="true";
00153 std::string result = funname_+'('+fname+", "+cutname+')';
00154 if (extitername) result = result + '['+intitername+']';
00155
00156 return result;
00157 }
00158
00159 void CollectiveIntFun::checkIterators() {
00160
00161
00162
00163
00164
00165 FillIterator *funiter = fun ? const_cast<FillIterator *>(fun->getIterator()) : 0;
00166 FillIterator *cutiter = cut ? const_cast<FillIterator *>(cut->getIterator()) : 0;
00167
00168 if (!intiter) {
00169
00170 if (funiter && cutiter) {
00171
00172 if (funiter == cutiter) {
00173 if (funiter != extiter) {
00174 intiter = funiter;
00175 #if (DEBUG>=2)
00176 std::cerr << "CollectiveIntFun: taking intiter from funiter == cutiter\n";
00177 #endif
00178 }
00179 }
00180 else {
00181
00182
00183 if (funiter == extiter) {
00184 intiter = cutiter;
00185 #if (DEBUG>=2)
00186 std::cerr << "CollectiveIntFun: taking intiter from cutiter != funiter\n";
00187 #endif
00188 }
00189 else if (cutiter == extiter) {
00190 intiter = funiter;
00191 #if (DEBUG>=2)
00192 std::cerr << "CollectiveIntFun: taking intiter from funiter != cutiter\n";
00193 #endif
00194 }
00195 }
00196 }
00197 else if (funiter) {
00198
00199 if (funiter != extiter) {
00200 intiter = funiter;
00201 #if (DEBUG>=2)
00202 std::cerr << "CollectiveIntFun: taking intiter from funiter, cutiter==0\n";
00203 #endif
00204 }
00205 }
00206 else if (cutiter) {
00207
00208 if (cutiter != extiter) {
00209 #if (DEBUG>=2)
00210 std::cerr << "CollectiveIntFun: taking intiter from cutiter, cutiter==0\n";
00211 #endif
00212 intiter = cutiter;
00213 }
00214 }
00215 else {
00216
00217 std::cerr << "CollectiveIntFun: Error! cutiter, intiter and intiter all 0!\n";
00218 }
00219 }
00220
00221 if (!intiter) {
00222 std::cerr << "CollectiveIntFun: Cannot determine intiter from fun and cut!\n";
00223 }
00224
00225 assert (intiter);
00226 assert (!extiter || extiter!=intiter);
00227 assert (!funiter || funiter==intiter || funiter==extiter);
00228 assert (!cutiter || cutiter==intiter || cutiter==extiter);
00229 }
00230
00231 int MaxIntFun::operator() () const {
00232
00233 int result = INT_MIN;
00234 if (intiter->reset()) {
00235 do {
00236 if (!cut || (*cut)()) {
00237 int f = fun ? (*fun)() : 0;
00238 if (f > result) result = f;
00239 }
00240 } while (intiter->next());
00241 }
00242 return result;
00243 }
00244
00245 int MinIntFun::operator() () const {
00246
00247 int result = INT_MAX;
00248 if (intiter->reset()) {
00249 do {
00250 if (!cut || (*cut)()) {
00251 int f = fun ? (*fun)() : 0;
00252 if (f < result) result = f;
00253 }
00254 } while (intiter->next());
00255 }
00256 return result;
00257 }
00258
00259 int SumIntFun::operator() () const {
00260 int sum = 0;
00261 if (intiter->reset()) {
00262 do {
00263 if (!cut || (*cut)()) {
00264 int f = fun ? (*fun)() : 1;
00265 sum += f;
00266 }
00267 } while (intiter->next());
00268 }
00269 return sum;
00270 }
00271
00272 CachedIntFun::CachedIntFun (const ROListPoR& rol, const IntFun& arg_)
00273 : IntFun (std::string("cached(")+arg_.getName()+')'),
00274 CachedO (rol),
00275 arg(arg_),
00276 cacheValid (false)
00277 {
00278 assert (&arg);
00279 }
00280
00281 int CachedIntFun::operator() () const {
00282 if (!cacheValid) {
00283 cachedValue = arg();
00284 cacheValid = true;
00285 }
00286 return cachedValue;
00287 }
00288
00289 CachedIntFunIt::CachedIntFunIt (const ROListPoR& rol,
00290 const IntFun& arg_,
00291 const FillIterator& iter_
00292 )
00293 : IntFun (std::string("cached(")+arg_.getName()+')'),
00294 CachedO (rol),
00295 arg (arg_),
00296 iter (iter_),
00297 cacheValid (),
00298 cachedValues ()
00299 {
00300 assert (&arg);
00301 assert (&iter);
00302 }
00303
00304 int CachedIntFunIt::operator() () const {
00305 int i = iter();
00306 assert (i >= 0);
00307 if (static_cast<unsigned int>(i) >= cacheValid.size()) growCache (i+1);
00308 if (!cacheValid[i]) {
00309 cacheValid[i] = true;
00310 cachedValues[i] = arg();
00311 }
00312 return cachedValues[i];
00313 }
00314
00315 void CachedIntFunIt::growCache (unsigned int s) const {
00316 unsigned int oldsize = cacheValid.size();
00317 if (s < oldsize) return;
00318 cacheValid.resize (s);
00319 cachedValues.resize(s);
00320 for (unsigned int i = oldsize; i < s; ++i) cacheValid[i] = false;
00321 }
00322
00323 IntFun& cached (const ROListPoR& rol,
00324 const IntFunPoR& fun,
00325 const FillIteratorPoR& iter
00326 ) {
00327 assert (fun.pif);
00328 if (iter.pfi) return *new CachedIntFunIt (rol, *fun.pif, *iter.pfi);
00329 if (const FillIterator *fi = fun.pif->getIterator())
00330 return *new CachedIntFunIt (rol, *fun.pif, *fi);
00331 return *new CachedIntFun (rol, *fun.pif);
00332 }
00333
00334
00335 FloatFun& Float (const IntFun& arg) {
00336 return *new FloatIntFun(arg);
00337 }
00338
00339 IntFun& operator+ (const IntFun& lhs_, const IntFun& rhs_) {
00340 return *new SumOfTwoIntFuns (lhs_, rhs_);
00341 }
00342
00343 IntFun& operator+ (int lhs_, const IntFun& rhs_) {
00344 return *new ScalarSumIntFun (lhs_, rhs_);
00345 }
00346
00347 IntFun& operator+ (const IntFun& lhs_, int rhs_) {
00348 return *new ScalarSumIntFun (rhs_, lhs_);
00349 }
00350
00351 IntFun& operator- (const IntFun& lhs_, const IntFun& rhs_) {
00352 return *new DiffOfTwoIntFuns (lhs_, rhs_);
00353 }
00354
00355 IntFun& operator- (int lhs_, const IntFun& rhs_) {
00356 return *new ScalarDiffIntFun (lhs_, rhs_);
00357 }
00358
00359 IntFun& operator- (const IntFun& lhs_, int rhs_) {
00360 return *new ScalarSumIntFun (-rhs_, lhs_);
00361 }
00362
00363 IntFun& operator- (const IntFun& arg_) {
00364 return *new ScalarProductIntFun (-1, arg_, std::string("-(")+arg_.getName()+')');
00365 }
00366
00367 IntFun& operator+ (IntFun& arg_) {
00368 return arg_;
00369 }
00370
00371 const IntFun& operator+ (const IntFun& arg_) {
00372 return arg_;
00373 }
00374
00375 IntFun& operator* (const IntFun& lhs_, const IntFun& rhs_) {
00376 if (&lhs_ == &rhs_) return square (lhs_);
00377 return *new ProdOfTwoIntFuns (lhs_, rhs_);
00378 }
00379
00380 IntFun& operator/ (const IntFun& lhs_, const IntFun& rhs_) {
00381 return *new DivOfTwoIntFuns (lhs_, rhs_);
00382 }
00383
00384 IntFun& operator* (int lhs_, const IntFun& rhs_) {
00385 return *new ScalarProductIntFun (lhs_, rhs_);
00386 }
00387
00388 IntFun& operator* (const IntFun& lhs_, int rhs_) {
00389 return *new ScalarProductIntFun (rhs_, lhs_);
00390 }
00391
00393
00394 IntFun& operator/ (int lhs_, const IntFun& rhs_) {
00395 return *new ScalarDivisionIntFun (lhs_, rhs_);
00396 }
00397
00398 IntFun& operator/ (const IntFun& lhs_, int rhs_) {
00399 return *new ScalarDivisionIntFun2 (lhs_, rhs_);
00400 }
00401
00402 IntFun& operator& (const IntFun& lhs_, const IntFun& rhs_) {
00403 return *new AndOfTwoIntFuns (lhs_, rhs_);
00404 }
00405
00406 IntFun& operator| (const IntFun& lhs_, const IntFun& rhs_) {
00407 return *new OrOfTwoIntFuns (lhs_, rhs_);
00408 }
00409
00410 IntFun& operator^ (const IntFun& lhs_, const IntFun& rhs_) {
00411 return *new XorOfTwoIntFuns (lhs_, rhs_);
00412 }
00413
00414 IntFun& operator& (const IntFun& lhs_, int rhs_) {
00415 return *new ScalarAndIntFun (rhs_, lhs_);
00416 }
00417
00418 IntFun& operator& (int lhs_, const IntFun& rhs_) {
00419 return *new ScalarAndIntFun (lhs_, rhs_);
00420 }
00421
00422 IntFun& operator| (const IntFun& lhs_, int rhs_) {
00423 return *new ScalarOrIntFun (rhs_, lhs_);
00424 }
00425
00426 IntFun& operator| (int lhs_, const IntFun& rhs_) {
00427 return *new ScalarOrIntFun (lhs_, rhs_);
00428 }
00429
00430 IntFun& operator^ (const IntFun& lhs_, int rhs_) {
00431 return *new ScalarXorIntFun (rhs_, lhs_);
00432 }
00433
00434 IntFun& operator^ (int lhs_, const IntFun& rhs_) {
00435 return *new ScalarXorIntFun (lhs_, rhs_);
00436 }
00437
00438 IntFun& operator~ (const IntFun& arg_) {
00439 return *new IntFunComplement (arg_);
00440 }
00441
00442
00443 IntFun& square (const IntFun& arg_) {
00444 return *new AnyIntFun1<square>("square", arg_);
00445 }
00446
00447 IntFun& abs (const IntFun& arg_) {
00448 return *new AnyIntFun1<std::abs>("abs", arg_);
00449 }
00450
00451 IntFunComp& operator< (const IntFun& lhs_, const IntFun& rhs_) {
00452 return *new IntFunLess (lhs_, rhs_);
00453 }
00454
00455 IntFunComp& operator> (const IntFun& lhs_, const IntFun& rhs_) {
00456 return *new IntFunGreater (lhs_, rhs_);
00457 }
00458
00459 IntFunComp& operator<= (const IntFun& lhs_, const IntFun& rhs_) {
00460 return *new IntFunLessEqual (lhs_, rhs_);
00461 }
00462
00463 IntFunComp& operator>= (const IntFun& lhs_, const IntFun& rhs_) {
00464 return *new IntFunGreaterEqual (lhs_, rhs_);
00465 }
00466
00467 IntFunComp& operator== (const IntFun& lhs_, const IntFun& rhs_) {
00468 return *new IntFunEqual (lhs_, rhs_);
00469 }
00470
00471 IntFunComp& operator!= (const IntFun& lhs_, const IntFun& rhs_) {
00472 return *new IntFunNotEqual (rhs_, lhs_);
00473 }
00474
00475
00476
00477
00478 IntFunComp& operator< (int lhs_, const IntFun& rhs_) {
00479 return *new IntIntFunLess (lhs_, rhs_);
00480 }
00481
00482 IntFunComp& operator<= (int lhs_, const IntFun& rhs_) {
00483 return *new IntIntFunLessEqual (lhs_, rhs_);
00484 }
00485
00486 IntFunComp& operator> (int lhs_, const IntFun& rhs_) {
00487 return *new IntIntFunGreater (lhs_, rhs_);
00488 }
00489
00490 IntFunComp& operator>= (int lhs_, const IntFun& rhs_) {
00491 return *new IntIntFunGreaterEqual (lhs_, rhs_);
00492 }
00493
00494 IntFunComp& operator== (int lhs_, const IntFun& rhs_) {
00495 return *new IntIntFunEqual (lhs_, rhs_);
00496 }
00497
00498 IntFunComp& operator!= (int lhs_, const IntFun& rhs_) {
00499 return *new IntIntFunNotEqual (lhs_, rhs_);
00500 }
00501
00502 IntFunComp& operator< (const IntFun& lhs_, int rhs_) {
00503 return *new IntFunIntLess (lhs_, rhs_);
00504 }
00505
00506 IntFunComp& operator<= (const IntFun& lhs_, int rhs_) {
00507 return *new IntFunIntLessEqual (lhs_, rhs_);
00508 }
00509
00510 IntFunComp& operator> (const IntFun& lhs_, int rhs_) {
00511 return *new IntFunIntGreater (lhs_, rhs_);
00512 }
00513
00514 IntFunComp& operator>= (const IntFun& lhs_, int rhs_) {
00515 return *new IntFunIntGreaterEqual (lhs_, rhs_);
00516 }
00517
00518 IntFunComp& operator== (const IntFun& lhs_, int rhs_) {
00519 return *new IntFunIntEqual (lhs_, rhs_);
00520 }
00521
00522 IntFunComp& operator!= (const IntFun& lhs_, int rhs_) {
00523 return *new IntFunIntNotEqual (lhs_, rhs_);
00524 }
00525
00526
00527
00528
00529
00530
00531 IntFunComp& operator< (const IntFunComp& lhs_, const IntFun& rhs_) {
00532 return *new IntChainCompLess (lhs_, rhs_);
00533 }
00534
00535 IntFunComp& operator<= (const IntFunComp& lhs_, const IntFun& rhs_) {
00536 return *new IntChainCompLessEqual (lhs_, rhs_);
00537 }
00538
00539 IntFunComp& operator> (const IntFunComp& lhs_, const IntFun& rhs_) {
00540 return *new IntChainCompGreater (lhs_, rhs_);
00541 }
00542
00543 IntFunComp& operator>= (const IntFunComp& lhs_, const IntFun& rhs_) {
00544 return *new IntChainCompGreaterEqual (lhs_, rhs_);
00545 }
00546
00547 IntFunComp& operator== (const IntFunComp& lhs_, const IntFun& rhs_) {
00548 return *new IntChainCompEqual (lhs_, rhs_);
00549 }
00550
00551 IntFunComp& operator!= (const IntFunComp& lhs_, const IntFun& rhs_) {
00552 return *new IntChainCompNotEqual (lhs_, rhs_);
00553 }
00554
00555
00556 IntFunComp& operator< (const IntFunComp& lhs_, int rhs_) {
00557 return *new IntChainCompIntLess (lhs_, rhs_);
00558 }
00559
00560 IntFunComp& operator<= (const IntFunComp& lhs_, int rhs_) {
00561 return *new IntChainCompIntLessEqual (lhs_, rhs_);
00562 }
00563
00564 IntFunComp& operator> (const IntFunComp& lhs_, int rhs_) {
00565 return *new IntChainCompIntGreater (lhs_, rhs_);
00566 }
00567
00568 IntFunComp& operator>= (const IntFunComp& lhs_, int rhs_) {
00569 return *new IntChainCompIntGreaterEqual (lhs_, rhs_);
00570 }
00571
00572 IntFunComp& operator== (const IntFunComp& lhs_, int rhs_) {
00573 return *new IntChainCompIntEqual (lhs_, rhs_);
00574 }
00575
00576 IntFunComp& operator!= (const IntFunComp& lhs_, int rhs_) {
00577 return *new IntChainCompIntNotEqual (lhs_, rhs_);
00578 }
00579
00580 IntFun& max (const IntFunPoRConst& fun,
00581 const BaseCutPoRConst& cut,
00582 const FillIteratorPoR& intiter,
00583 const FillIteratorPoRConst& extiter
00584 ) {
00585 return *new MaxIntFun (fun, cut, intiter, extiter);
00586 }
00587
00588 IntFun& min (const IntFunPoRConst& fun,
00589 const BaseCutPoRConst& cut,
00590 const FillIteratorPoR& intiter,
00591 const FillIteratorPoRConst& extiter
00592 ) {
00593 return *new MinIntFun (fun, cut, intiter, extiter);
00594 }
00595
00596 IntFun& sum (const IntFunPoRConst& fun,
00597 const BaseCutPoRConst& cut,
00598 const FillIteratorPoR& intiter,
00599 const FillIteratorPoRConst& extiter
00600 ) {
00601 return *new SumIntFun (fun, cut, intiter, extiter);
00602 }
00603
00604 IntFun& count (const BaseCutPoRConst& cut,
00605 const FillIteratorPoR& intiter,
00606 const FillIteratorPoRConst& extiter
00607 ) {
00608 return *new SumIntFun (0, cut, intiter, extiter);
00609 }