Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members | Related Pages

IntFun.C

Go to the documentation of this file.
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   // Rules:
00161   // If no internal iterator is given, try to get iterator from
00162   // fun or cut; if both have an iterator, they must be equal or 
00163   // one of them must be equal to the external ietartor
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     // intiter not explicitly given, try to get it
00170     if (funiter && cutiter) {
00171       // funiter and cutiter defined
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         // funiter and cutiter different: One  must be equal to extiter,
00182         // the other should become intiter.
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       // funiter defined, cutiter == 0
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       // cutiter defined, funiter == 0
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       // funcutiter and cutiter == 0
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   // int result = std::numeric_limits<int>::min();
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   // int result = std::numeric_limits<int>::max();
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 // External functions that implement comparison operators between
00476 // a int and a IntFun object
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 // External functions that allow chain comparisons like 1 < x < y <= 15
00528 // Such a chain comparison is defined as
00529 // (1 < x) && (x < y) && (y <= 15)
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 }

Generated on Thu Oct 26 12:52:57 2006 for SFH by doxygen 1.3.2