par.h

Go to the documentation of this file.
00001 
00002 //----------------------------------------------------------------------------------
00004 //----------------------------------------------------------------------------------
00005 #ifndef         PAR_H
00006 #define         PAR_H
00007 
00008 #include        <iomanip>
00009 #include        <stdlib.h>
00010 #include        <cmath>
00011 #include        <stack>
00012 
00013 using namespace std;
00014 
00016 template <class T> static T par_add(T x, T y)   { return x + y; }
00017 template <class T> static T par_sub(T x, T y)   { return x - y; }
00018 template <class T> static T par_mul(T x, T y)   { return x * y; }
00019 template <class T> static T par_div(T x, T y)   { return x / y; }
00020 template <class T> static T par_mod(T x, T y)   { return x % y; }
00021 template <class T> static T par_or(T x, T y)    { return x | y; }
00022 template <class T> static T par_and(T x, T y)   { return x & y; }
00023 template <class T> static T par_max(T x, T y)   { return x>=y ? x : y; }
00024 template <class T> static T par_min(T x, T y)   { return x<=y ? x : y; }
00025 template <class T> static T par_neg(T x)                { return -x; }
00026 template <class T> static T par_nop(T x)                { return x; }
00027 template <class T> static T par_not(T x)                { return !x; }
00028 
00029 
00030 //      -------------- special functions -----------------
00031 template <class T> static T par_pow(T x, T y)   { return pow(x,y); }
00032 
00034 template <class T>  static bool par_eq(T x, T y){ return x==y; }
00035 template <class T>  static bool par_ne(T x, T y){ return x!=y; }
00036 template <class T>  static bool par_lt(T x, T y){ return x<y; }
00037 template <class T>  static bool par_gt(T x, T y){ return x>y; }
00038 template <class T>  static bool par_le(T x, T y){ return x<=y; }
00039 template <class T>  static bool par_ge(T x, T y){ return x>=y; }
00040 
00042 bool            *flag=NULL;
00043 int                     flag_N=0;
00044 
00046 bool            *flagtemp=NULL;         // current useful array of bools (active flags)
00047 bool            restrict=false;         // if on, then in some sort of if block
00048 bool            ifelseflag=true;        // if on, then in an IFP block (off in an ELSEP block)
00049 
00051 stack<bool *>   rs;                                     // stack of flags
00052 stack<bool>             ifelses;                        // saves ifp/elsep status in a nested IFP
00053 
00055 #define ifp(x) \
00056         (x); \
00057         flagtemp = new bool[flag_N]; \
00058         memcpy(flagtemp, flag, flag_N); \
00059         rs.push(flagtemp);  \
00060         ifelses.push(true); \
00061         restrict = true; \
00062         ifelseflag = true;
00063                                 // restrict will not work for nested, use stack of bool...
00064 
00066 #define elsep() \
00067         flagtemp = rs.top(); \
00068         ifelseflag = false; \
00069         ifelses.pop(); \
00070         ifelses.push(false);
00071         
00073 #define endifp \
00074         flagtemp = rs.top(); \
00075         delete [] flagtemp; \
00076         rs.pop(); \
00077         ifelses.pop(); \
00078         if (!ifelses.empty()) ifelseflag = ifelses.top(); \
00079                 else ifelseflag = true; \
00080         if (!rs.empty()) flagtemp = rs.top(); \
00081                 else { flagtemp=NULL; restrict = false; }
00082                         
00083 
00084 //--------------------------------------------------------------------------------
00086 //--------------------------------------------------------------------------------
00087 template <class T>
00088 class par
00089 {
00091  private:                                       
00092   T             *data;                                  
00093   int   N;                                              
00094 
00096  public:
00097   
00098         par(const int n=1)                      
00099     { 
00100       N = n;    
00101       data = new T[n];
00102     }
00103 
00104         ~par()                                          
00105     { delete [] data; }
00106         
00107         par(const par<T> &x)            
00108     {                                                   
00109     for (int i=0; i<x.N; i++)
00110                 data[i] = x.data[i];
00111         N = x.N;
00112     }
00113 
00114   // cast conversions
00115   /*par(const T &d)
00116     {
00117       for (int i=0; i<N; i++)
00118         data[i] = d;    
00119     }
00120   */
00121   //-----------------------------------------------------------------------
00123   //-----------------------------------------------------------------------
00125     friend  void par_bool_par(par<T> &x, bool f(T,T), par<T> &y)
00126     {
00127     delete [] flag;
00128     flag = new bool[x.N];
00129         flag_N = x.N; 
00130         for (int i=0; i<x.N; i++)
00131                 {
00132                 flag[i] = f(x.data[i],y.data[i]);
00133                 }
00134     }
00135 
00136     friend void par_bool_sing(par<T> &x, bool f(T,T), const T &t)
00137     {
00138     par<T> y(x.N);
00139         y=t;
00140     par_bool_par(x,f,y);
00141     }
00142 
00144     friend void par_self(par<T> &x, T f(T))
00145     {
00146     for (int i=0; i<x.N; i++)
00147                 x.data[i] = f(x.data[i]);
00148     }
00149 
00150     friend void par_to_par(par<T> &y, T f(T), par<T> &x)
00151     {
00152     for (int i=0; i<y.N; i++)
00153                 y.data[i] = f(x.data[i]);
00154     }
00155 
00156     void par2_to_par(T f(T,T) , par<T> &x, par<T> &y)
00157     {
00158     for (int i=0; i<N; i++)
00159                 data[i] = f(x.data[i],y.data[i]);                       // Farg occurs here when data different size
00160     }
00161 
00164     friend void sing_to_par(par<T> &y, T f(T), const T &t)
00165     {
00166     for (int i=0; i<y.N; i++)
00167                 y.data[i] = f(t);
00168     }
00169 
00170     friend void par_and_sing_to_par(par<T> &z, T f(T,T), par<T> &x, const T &t)
00171     {
00172     par<T> y(x.N);      y=t;
00173     z.par2_to_par(f,x,y);               
00174     }
00175 
00176     friend void par_and_sing_to_par_rev(par<T> &z, T f(T,T), par<T> &x, const T &t)
00177     {
00178     par<T> y(x.N);      y=t;
00179     z.par2_to_par(f,y,x);       
00180     }
00181 
00182 
00183     //-----------------------------------------------------------------------
00185     //-----------------------------------------------------------------------
00187     par<T> &operator - () 
00188     { static par<T> z(N); z.reassign(N); par_to_par(z ,par_neg ,*this ); return z;}
00189 
00190         par<T> &operator ! () 
00191     { static par<T> z(N); z.reassign(N); par_to_par(z ,par_not ,*this ); return z;}
00192 
00193     par<T> &operator + ()
00194     { return *this; }
00195 
00196 
00198     par<T> &operator + (par<T> &y)
00199         {static par<T> z(N); z.reassign(N); z.par2_to_par( par_add, *this, y); return z;}
00200 
00201     par<T> &operator - (par<T> &y)
00202     {static par<T> z(N); z.reassign(N); z.par2_to_par( par_sub, *this, y); return z;}
00203 
00204     par<T> &operator * (par<T> &y)
00205     {static par<T> z(N); z.reassign(N); z.par2_to_par( par_mul, *this, y); return z;}
00206 
00207     par<T> &operator / (par<T> &y)
00208     {static par<T> z(N); z.reassign(N); z.par2_to_par( par_div, *this, y); return z;}
00209 
00210     par<T> &operator % (par<T> &y)
00211     {static par<T> z(N); z.reassign(N); z.par2_to_par( par_mod, *this, y); return z;}
00212 
00213     par<T> &operator | (par<T> &y)
00214     {static par<T> z(N); z.reassign(N); z.par2_to_par( par_or, *this, y); return z;}
00215 
00216     par<T> &operator & (par<T> &y)
00217     {static par<T> z(N); z.reassign(N); z.par2_to_par( par_and, *this, y); return z;}
00218 
00220     par<T> &operator += (par<T> &y)
00221         {this->par2_to_par( par_add, *this, y); return *this;}
00222 
00223     par<T> &operator -= (par<T> &y)
00224     {this->par2_to_par( par_sub, *this, y); return *this;}
00225 
00226     par<T> &operator *= (par<T> &y)
00227     {this->par2_to_par( par_mul, *this, y); return *this;}
00228 
00229     par<T> &operator /= (par<T> &y)
00230     {this->par2_to_par( par_div, *this, y); return *this;}
00231 
00232     par<T> &operator %= (par<T> &y)
00233     {this->par2_to_par( par_mod, *this, y); return *this;}
00234 
00235     par<T> &operator |= (par<T> &y)
00236     {this->par2_to_par( par_or, *this, y); return *this;}
00237 
00238     par<T> &operator &= (par<T> &y)
00239     {this->par2_to_par( par_and, *this, y); return *this;}
00240 
00242     friend T reduce(T init, T f(T,T), const par<T> &x)
00243     { for (int i=0; i<x.N; i++)  init = f(init , x.data[i]);  return init; }
00244         
00245         friend T operator += (T &x, par<T> &y)
00246         {return x=reduce( 0, par_add, y);}
00247 
00248     friend T operator -= (T &x, par<T> &y)
00249     {return x=reduce( 0, par_sub, y);}
00250 
00251     friend T operator *= (T &x, par<T> &y)
00252     {return x=reduce( 1, par_mul, y);}
00253 
00254     friend T operator /= (T &x, par<T> &y)
00255     {return x=reduce( 1, par_div, y);}
00256 
00257     friend T operator %= (T &x, par<T> &y)
00258     {return x=reduce( 1, par_mod, y);}
00259 
00260     friend T operator |= (T &x, par<T> &y)
00261     {return x=reduce( false, par_or, y);}
00262 
00263     friend T operator &= (T &x, par<T> &y)
00264     {return x=reduce( true, par_and, y);}
00265 
00266         T max_value(par<T> &y)
00267         {return reduce( y.data[0], par_max, y);}
00268 
00269         T min_value(par<T> &y)
00270         {return reduce( y.data[0], par_min, y);}
00271 
00272 
00273 
00275 
00276         friend par<bool> &flag_setup_x_op_y(par<T> &x)
00277         {static par<bool> r(x.N);  r.reassign(x.N); r=flag;  return r;}
00278 
00279     friend par<bool> &operator == (par<T> &x, par<T> &y)
00280     { par_bool_par(x, par_eq, y); return flag_setup_x_op_y(x);}
00281 
00282     friend par<bool> &operator != (par<T> &x, par<T> &y)
00283     { par_bool_par(x, par_ne, y); return flag_setup_x_op_y(x);}
00284 
00285     friend par<bool> &operator < (par<T> &x, par<T> &y)
00286     { par_bool_par(x, par_lt, y); return flag_setup_x_op_y(x);}
00287 
00288     friend par<bool> &operator > (par<T> &x, par<T> &y)
00289     { par_bool_par(x, par_gt, y); return flag_setup_x_op_y(x);}
00290 
00291     friend par<bool> &operator <= (par<T> &x, par<T> &y)
00292     { par_bool_par(x, par_le, y); return flag_setup_x_op_y(x);}
00293 
00294     friend par<bool> &operator >= (par<T> &x, par<T> &y)
00295     { par_bool_par(x, par_ge, y); return flag_setup_x_op_y(x);}
00296 
00297         friend par<bool> &operator && (par<T> &x, par<T> &y)
00298     { par_bool_par(x, par_and, y); return flag_setup_x_op_y(x);}
00299 
00300         friend par<bool> &operator || (par<T> &x, par<T> &y)
00301     { par_bool_par(x, par_or, y); return flag_setup_x_op_y(x);}
00302 
00304     friend par<bool> &operator == (par<T> &x, const T &t)
00305     { par_bool_sing(x, par_eq, t); return flag_setup_x_op_y(x);}
00306 
00307     friend par<bool> &operator != (par<T> &x, const T &t)
00308     { par_bool_sing(x, par_ne, t); return flag_setup_x_op_y(x);}
00309 
00310     friend par<bool> &operator < (par<T> &x, const T &t)
00311     { par_bool_sing(x, par_lt, t); return flag_setup_x_op_y(x);}
00312 
00313     friend par<bool> &operator > (par<T> &x, const T &t)
00314     { par_bool_sing(x, par_gt, t); return flag_setup_x_op_y(x);}
00315 
00316     friend par<bool> &operator <= (par<T> &x, const T &t)
00317         { par_bool_sing(x, par_le, t); return flag_setup_x_op_y(x);}
00318 
00319     friend par<bool> &operator >= (par<T> &x, const T &t)
00320     { par_bool_sing(x, par_ge, t); return flag_setup_x_op_y(x);}
00321 
00322     friend par<bool> &operator == (const T &t, par<T> &x)
00323     { par_bool_sing(t, par_eq, x); return flag_setup_x_op_y(x);}
00324 
00325     friend par<bool> &operator != (const T &t, par<T> &x)
00326     { par_bool_sing(t, par_ne, x); return flag_setup_x_op_y(x);}
00327 
00328     friend par<bool> &operator < (const T &t, par<T> &x)
00329     { par_bool_sing(t, par_lt, x); return flag_setup_x_op_y(x);}
00330 
00331     friend par<bool> &operator > (const T &t, par<T> &x)
00332     { par_bool_sing(t, par_gt, x); return flag_setup_x_op_y(x);}
00333 
00334     friend par<bool> &operator >= (const T &t, par<T> &x)
00335     { par_bool_sing(t, par_ge, x); return flag_setup_x_op_y(x);}
00336 
00337     friend par<bool> &operator <= (const T &t, par<T> &x)
00338     { par_bool_sing(t, par_le, x); return flag_setup_x_op_y(x);}
00339 
00340     friend par<bool> &operator && (const T &t, par<T> &x)
00341     { par_bool_sing(t, par_and, x); return flag_setup_x_op_y(x);}
00342 
00343     friend par<bool> &operator && (par<T> &x, const T &t)
00344     { par_bool_sing(t, par_and, x); return flag_setup_x_op_y(x);}
00345 
00346         friend par<bool> &operator || (const T &t, par<T> &x)
00347     { par_bool_sing(t, par_and, x); return flag_setup_x_op_y(x);}
00348 
00349     friend par<bool> &operator || (par<T> &x, const T &t)
00350     { par_bool_sing(t, par_and, x); return flag_setup_x_op_y(x);}
00351 
00352 
00354     friend par<T> &operator + (par<T> &x, const T &t)
00355     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_add, x, t); return z;}
00356 
00357     friend par<T> &operator + (const T &t, par<T> &x)
00358         {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_add, x, t); return z;}
00359 
00360     friend par<T> &operator - (par<T> &x, const T &t)
00361     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_sub, x, t); return z;}
00362 
00363     friend par<T> &operator - (const T &t, par<T> &x)
00364     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_sub, x, t); return z;}
00365 
00366     friend par<T> &operator * (par<T> &x, const T &t)
00367     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_mul, x, t); return z;}
00368 
00369     friend par<T> &operator * (const T &t, par<T> &x)
00370     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_mul, x, t); return z;}
00371 
00372     friend par<T> &operator / (par<T> &x, const T &t)
00373     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_div, x, t); return z;}
00374 
00375     friend par<T> &operator / (const T &t, par<T> &x)
00376     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_div, x, t); return z;}
00377 
00378     friend par<T> &operator % (par<T> &x, const T &t)
00379     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_mod, x, t); return z;}
00380 
00381     friend par<T> &operator % (const T &t, par<T> &x)
00382     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_mod, x, t); return z;}
00383 
00384     friend par<T> &operator | (par<T> &x, const T &t)
00385     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_or, x, t); return z;}
00386 
00387     friend par<T> &operator | (const T &t, par<T> &x)
00388     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_or, x, t); return z;}
00389 
00390     friend par<T> &operator & (par<T> &x, const T &t)
00391     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par( z, par_and, x, t); return z;}
00392 
00393     friend par<T> &operator & (const T &t, par<T> &x)
00394     {static par<T> z(x.N); z.reassign(x.N); par_and_sing_to_par_rev( z, par_and, x, t); return z;}
00395 
00397         par<T> &operator ++ ()
00398         {
00399         par_and_sing_to_par(*this, par_add, *this, 1);
00400         return *this;
00401         }
00402 
00403         par<T> &operator ++ (int a)
00404         {
00405         static par<T> z(N); z.reassign(N);
00406         par_and_sing_to_par(*z, par_add, *this, 1);
00407         return z;
00408         }
00409 
00410         par<T> &operator -- ()
00411         {
00412         par_and_sing_to_par(*this, par_sub, *this, 1);
00413         return *this;
00414         }
00415 
00416         par<T> &operator -- (int a)
00417         {
00418         static par<T> z(N); z.reassign(N);
00419         par_and_sing_to_par(z, par_sub, *this, 1);
00420         return z;
00421         }
00422 
00423     // ---------------------------------------------------------------------
00425     // ---------------------------------------------------------------------
00426     friend std::ostream &operator << ( std::ostream &out, par<T> &x)
00427     {
00428     for (int i=0; i<x.N; i++)
00429                 out << std::setw(12) << x.data[i];
00430     return out;
00431         }
00432 
00433 
00434     friend std::istream &operator >> ( std::istream &in, par<T> &x)
00435     {
00436     for (int i=0; i<x.N; i++)
00437                 in >> x.data[i];
00438     return in;
00439     }
00440     // -------------------------------------------------
00442     // -------------------------------------------------
00443     T &operator [] ( int i )                            // single, left
00444     { return data[i]; } 
00445 
00446     const T &operator [] ( int i ) const        // single, right
00447     { return data[i]; } 
00448 
00449         par<T> &operator [] ( par<T> &x )                                       
00450     { 
00451         static par<T> z(x.N); z.reassign(x.N);
00452         for (int i=0; i<x.N; i++)
00453                 z.data[i] = data[ x.data[i]%x.N ];                              // permutation
00454         return z;
00455     } 
00456 
00457 
00458     // ----------------------------------------------------------------------
00460     // ----------------------------------------------------------------------
00462     par<T> &operator = (const par<T> &x)
00463     {
00464         if (flagtemp !=NULL && restrict)
00465                 for (int i=0; i<N; i++)
00466                         {if (flagtemp[i]) data[i] = x.data[i];}
00467                 else
00468                         for (int i=0; i<N; i++)
00469                                 data[i] = x.data[i];
00470                 return *this;
00471     }
00472 
00473 
00476     par<T> &operator = (const T &t)
00477     {
00478         if (flagtemp !=NULL && restrict)
00479                 for (int i=0; i<N; i++)
00480                         {if (flagtemp[i]) data[i] = t;}
00481         else    
00482                 for (int i=0; i<N; i++)
00483                         data[i]=t;
00484         return *this;
00485         }
00486 
00488     par<T> &operator = (const T *t)
00489         {
00490         if (flagtemp !=NULL && restrict)
00491                 for (int i=0; i<N; i++)
00492                         { if (flag[i]) data[i] = t[i]; }
00493         else    
00494                 for (int i=0; i<N; i++)
00495                         data[i]=t[i];
00496         return *this;
00497         }
00498 
00499 
00500 
00501     // ----------------------------------------------------------------------
00503     // ----------------------------------------------------------------------
00505 
00506     friend void addr(par<T> &x)
00507     { for (int i=0; i<x.N; i++) x.data[i] = i; }
00508 
00509     void all_on()
00510     {
00511     delete [] flag;
00512     flag = new bool[N];
00513         flag_N = N;
00514         for (int i=0; i<flag_N; i++) flag[i]=true;
00515     }
00516 
00517         friend T first(const par<T> &x)
00518         {
00519         if (flag != NULL)
00520                 for (int i=0; i<x.N; i++)
00521                         if (flag[i]) return x.data[i];
00522         return x.data[0];
00523         }
00524 
00525         friend int first_index(const par<T> &x)
00526         {
00527         if (flag != NULL)
00528                 for (int i=0; i<x.N; i++)
00529                         if (flag[i]) return i;
00530         return -1;
00531         }
00532 
00533         friend T nth(const par<T> &x, int n)
00534         {
00535         int c=0;
00536         if (flag != NULL)
00537                 for (int i=0; i<x.N; i++)
00538                         if (flag[i]) 
00539                                 {
00540                                 c++;
00541                                 if (c==n) return x.data[i];
00542                                 }
00543         return x.data[0];
00544         }
00545 
00546         friend T nth_index(const par<T> &x, int n)
00547         {
00548         int c=0;
00549         if (flag != NULL)
00550                 for (int i=0; i<x.N; i++)
00551                         if (flag[i]) 
00552                                 {
00553                                 c++;
00554                                 if (c==n) return i;
00555                                 }
00556         return -1;
00557         }
00558 
00559         friend bool any(par<T> &x)
00560         {
00561         for (int i=0; i<x.N; i++)
00562                 if (x.data[i]) return true;
00563         return false;
00564         }
00565 
00566         friend bool all(par<T> &x)
00567         {
00568         for (int i=0; i<x.N; i++)
00569                 if (!x.data[i]) return false;
00570         return true;
00571         }
00572 
00573         friend int active(par<T> &x)
00574         {
00575         int c=0;
00576         for (int i=0; i<x.N; i++)
00577                 if (flag[i]) c++;
00578         return c;
00579         }
00580 
00581         friend par<T> &scan(T init, T f(T,T), const par<T> &x)
00582         { 
00583         static par<T> z(N); z.reassign(N);
00584         z.data[0] = x.data[0];
00585         for (int i=1; i<x.N; i++)
00586                 z.data[i] = f(z.data[i-1], x.data[i]);
00587         return z;
00588         }
00589 
00590     
00591     // -------------------------------------------------
00593     // -------------------------------------------------
00594         void reassign(int n)
00595         { delete [] data;  N = n;  data = new T[n]; }
00596 
00597 
00598     void dumpflags()
00599         {
00600     for (int i=0; i<flag_N; i++)
00601                 std::cout<<flag[i];
00602     std::cout << std::endl;             
00603     }
00604         
00605         friend par<T> &pow(par<T> &x, T t)
00606     {
00607         par<T> y(x.N);
00608     static par<T> z(x.N);
00609         z.reassign(x.N); 
00610     y = t;
00611         z.par2_to_par( std::pow, x, y); return z;
00612     }
00613 
00614     friend par<T> &pow(T t, par<T> &x)
00615     {
00616         par<T> y(x.N);
00617     static par<T> z(x.N);  
00618         z.reassign(x.N); 
00619     y = t;
00620         z.par2_to_par( std::pow, y, x); return z;
00621     }
00622 
00623 
00624     // -------------------------------------------------
00626     // -------------------------------------------------
00627         friend par<T> &rotate(par<T> &x, int amt)
00628         {
00629         static par<T> z(x.N); z.reassign(x.N);
00630         for (int i=0; i<x.N; i++)
00631                 z.data[(i+amt+x.N)%x.N] = x.data[i];            
00632         return z;
00633         }
00634 
00635         friend par<T> &permute(par<T> &x, par<int> &y)
00636         {
00637         static par<T> z(x.N); z.reassign(x.N);
00638         for (int i=0; i<x.N; i++)
00639                 z.data[y.data[i]%x.N] = x.data[i];
00640         return z;
00641         }
00642 
00643         friend par<T> &pack(par<T> &x)
00644         {
00645         static par<T> z(x.N); z.reassign(x.N);
00646         int c=0;
00647         for (int i=0; i<x.N; i++)
00648                 if (flag[i]) z.data[c++] = x.data[i];
00649         return z;
00650         }
00651 
00652 };                      
00653 
00654 
00655 #endif                  
00656 

Generated on Tue Jan 4 17:45:14 2005 for ZIPPAR by  doxygen 1.3.9.1