Gamma  0.9.5
Generic Synthesis Library
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
/Users/ljp/code/gamma/trunk/Gamma/Access.h
00001 #ifndef GAMMA_ACCESS_H_INC
00002 #define GAMMA_ACCESS_H_INC
00003 
00004 /*  Gamma - Generic processing library
00005     See COPYRIGHT file for authors and license information
00006 
00007     File Description: 
00008     Functions/objects for accessing and indexing arrays.
00009 */
00010 
00011 #include "Gamma/pstdint.h"
00012 
00013 namespace gam{
00014 
00015 typedef int32_t index_t;
00016 
00018 inline uint32_t indexLast(uint32_t len, uint32_t str){ return ((len-1)/str)*str; }
00019 
00021 inline index_t posToInd(float v, index_t n){ return n * (v*0.49999f + 0.5f); }
00022 
00023 
00024 // Neighbor accessing strategies
00025 // Valid index interval is [mn, mx]. The max value is inclusive to speed up
00026 // checks of closest neighbors, which is done most often.
00027 namespace acc{
00028 
00029     struct None{
00030         static index_t mapM1(index_t v, index_t mx, index_t mn){ return v; }
00031         static index_t mapP1(index_t v, index_t mx, index_t mn){ return v; }
00032         static index_t map  (index_t v, index_t mx, index_t mn){ return v; }
00033     };
00034 
00035     struct Wrap{
00036         static index_t mapM1(index_t v, index_t mx, index_t mn){ return v<mn ? mx : v; }
00037         static index_t mapP1(index_t v, index_t mx, index_t mn){ return v>mx ? mn : v; }
00038         static index_t map  (index_t v, index_t mx, index_t mn){ return v<mn ? v+mx+1-mn : (v>mx ? v-(mx+1-mn) : v); }
00039     };
00040 
00041     struct Clip{
00042         static index_t mapM1(index_t v, index_t mx, index_t mn){ return v>mn ? v : mn; }
00043         static index_t mapP1(index_t v, index_t mx, index_t mn){ return v<mx ? v : mx; }
00044         static index_t map  (index_t v, index_t mx, index_t mn){ return v>mn ? (v<mx ? v : mx) : mn; }
00045     };
00046 
00047 //  struct Fold{
00048 //      static index_t checkM1(index_t i, index_t mx, index_t mn){ return i>=mn ? i : mn+1; }
00049 //      static index_t mapP1(index_t i, index_t mx, index_t mn){ return i<=mx ? i : mx-1; }
00050 //  };
00051 };
00052 
00053 
00054 
00056 template <class T>
00057 class IndexMap{
00058 public:
00059     IndexMap(index_t idxMax=1, const T& posMax=T(1)){ max(idxMax, posMax); }
00060     
00061     index_t operator()(const T& x) const { return cast(x*mMul); }
00062     
00063     index_t operator()(const T& x, T& f) const {
00064         f = x*mMul;
00065         index_t i = cast(f);
00066         f -= cast(i); 
00067         return i;
00068     }
00069     
00070     T operator()(index_t i) const { return cast(i) * mRec; }
00071 
00072     void max(index_t idxMax, const T& posMax){ mMul=idxMax/posMax; mRec=1/mMul; }
00073 
00074 private:
00075     T mMul, mRec;
00076     //index_t cast(const T& v) const { return castIntTrunc(v); }
00077     index_t cast(const T& v) const { return index_t(v); }   // use native cast, usually optimized
00078     T cast(index_t v) const { return T(v); }
00079 };
00080 
00081 
00082 
00083 
00084 #define L1 for(int32_t i=0;i<count();++i)
00085 #define L2 int32_t n=minCount(v); for(int32_t i=0;i<n;++i)
00086 
00087 
00089 
00094 template <class T>
00095 class Slice{
00096 public:
00097 
00102     Slice(T * src, int32_t count_, int32_t stride_=1, int32_t offset_=0)
00103     :   A(src), C(count_), S(stride_)
00104     {   offset(offset_);    }
00105 
00107     Slice operator()(int32_t cnt, int32_t str=1, int32_t off=0) const { return Slice(A, cnt,str,off); }
00108     
00110     T& operator[](int32_t i) const { return B[i*S]; }
00111 
00112     template <class Gen>
00113     const Slice& operator  = (const Gen& v) const { L1{ (*this)[i] =v(); } return *this; }
00114     const Slice& operator  = (const   T& v) const { L1{ (*this)[i] =v  ; } return *this; }
00115 
00116     template <class Gen>
00117     bool operator == (const Gen& v) const { L1{ if(v() != (*this)[i]) return false; } return true; }
00118     bool operator == (const   T& v) const { L1{ if(v   != (*this)[i]) return false; } return true; }
00119 
00120     template <class U>
00121     const Slice& operator += (const Slice<U>& v) const { L2{ (*this)[i]+=T(v[i]); } return *this; }
00122 
00123     template <class Gen>
00124     const Slice& operator += (const Gen& v) const { L1{ (*this)[i]+=v(); } return *this; }
00125     const Slice& operator += (const   T& v) const { L1{ (*this)[i]+=v  ; } return *this; }
00126 
00127     template <class U>
00128     const Slice& operator -= (const Slice<U>& v) const { L2{ (*this)[i]-=T(v[i]); } return *this; }
00129 
00130     template <class Gen>
00131     const Slice& operator -= (const Gen& v) const { L1{ (*this)[i]-=v(); } return *this; }
00132     const Slice& operator -= (const   T& v) const { L1{ (*this)[i]-=v  ; } return *this; }
00133 
00134     template <class U>
00135     const Slice& operator *= (const Slice<U>& v) const { L2{ (*this)[i]*=T(v[i]); } return *this; }
00136 
00137     template <class Gen>
00138     const Slice& operator *= (const Gen& v) const { L1{ (*this)[i]*=v(); } return *this; }
00139     const Slice& operator *= (const   T& v) const { L1{ (*this)[i]*=v  ; } return *this; }
00140 
00141     template <class U>
00142     const Slice& operator /= (const Slice<U>& v) const { L2{ (*this)[i]/=T(v[i]); } return *this; }
00143 
00144     template <class Gen>
00145     const Slice& operator /= (const Gen& v) const { L1{ (*this)[i]/=v(); } return *this; }
00146     const Slice& operator /= (const   T& v) const { L1{ (*this)[i]/=v  ; } return *this; }
00147 
00149     
00152     template <class U>
00153     const Slice& copy(const Slice<U>& v) const { L2{ (*this)[i]=v[i]; } return *this; }
00154 
00156     template <class Fil>
00157     const Slice& filter(const Fil& v) const { L1{ (*this)[i]=v((*this)[i]); } return *this; }
00158     
00160     template <class R, class X, class A1>
00161     const Slice& filter(R (* const func)(X, A1), const A1& a1){
00162         L1{ (*this)[i] = func((*this)[i], a1); }
00163         return *this;
00164     }
00165 
00167     template <class R, class X, class A1, class A2>
00168     const Slice& filter(R (* const func)(X, A1,A2), const A1& a1, const A2& a2){
00169         L1{ (*this)[i] = func((*this)[i], a1,a2); }
00170         return *this;
00171     }
00172 
00174     const Slice& reverse(){ B=B+(C-1)*S; S=-S; return *this; }
00175     
00177     Slice reversed() const { Slice r=*this; r.B=B+(C-1)*S; r.S=-r.S; return r; }
00178 
00180     const Slice& set(const T& v=T()) const { return (*this = v); }
00181 
00183     template <class U>
00184     const Slice& swap(const Slice<U>& v) const {
00185         L2{ T t=(*this)[i]; (*this)[i]=v[i]; v[i]=t; }
00186         return *this;
00187     }
00188     
00190     T mean() const { return sum()/C; }
00191 
00193     T sum() const { T r=T(0); L1{ r+=(*this)[i]; } return r; }
00194 
00195     int32_t count() const { return C; }
00196     int32_t offset() const { return B-A; }
00197     int32_t stride() const { return S; }
00198     int32_t N() const { return (S>0?S:-S)*C; }
00199 
00200     Slice& count(int32_t v){ C=v; return *this; }
00201     Slice& offset(int32_t v){ B=A+(v<0 ? N()+v : v); return *this; }
00202     Slice& stride(int32_t v){ S=v; return *this; }
00203 
00204 protected:
00205     T * A, * B;     // absolute, relative pointers
00206     int32_t C,S;    // count, stride
00207     int32_t minCount(const Slice& o) const { return count()<o.count() ? count() : o.count(); }
00208 };
00209 
00210 #undef L1
00211 #undef L2
00212 
00214 template <class T>
00215 Slice<T> slice(T * src, int32_t cnt, int32_t str=1, int32_t off=0){ return Slice<T>(src,cnt,str,off); }
00216 
00217 
00218 /*
00219 1 2 3 4 5 6 7 8
00220 1 5 2 6 3 7 4 8     d = 4 + 1/2
00221 1 3 5 7 2 4 6 8     d = 2 + 1/4
00222 
00223 1 2 3 4 5 6 7 8 9
00224 1 4 7 2 5 8 3 6 9   d = 3 + 1/3
00225 
00226 */
00227 
00228 } // gam::
00229 
00230 #endif