00001 #ifndef GAMMA_UNITMAPS_H_INC
00002 #define GAMMA_UNITMAPS_H_INC
00003
00004
00005
00006
00007 #include <math.h>
00008 #include <map>
00009 #include <vector>
00010 #include "Gamma/scl.h"
00011 #include "Gamma/Access.h"
00012 #include "Gamma/Strategy.h"
00013 #include "Gamma/Types.h"
00014
00015 namespace gam{
00016
00017
00019 template<
00020 class T,
00021 template<class> class Sipl=ipl::Linear,
00022 class Sacc=acc::Wrap,
00023 class A=gam::Allocator<T>
00024 >
00025 class FunctionTable : public Array<T,A>{
00026 typedef Array<T,A> Base;
00027 public:
00028 using Base::elems; using Base::size;
00029
00030
00032
00035 explicit FunctionTable(uint32_t size=2048, const T& init=T(0))
00036 : Base(size, init)
00037 {
00038 endpoints(0, size);
00039 }
00040
00041 virtual ~FunctionTable(){}
00042
00044 Array<T,A>& array(){ return *this; }
00045 const Array<T,A>& array() const { return *this; }
00046
00048 T operator()(double x) const {
00049
00050 x = scl::wrap(x);
00051 double f;
00052
00053
00054 index_t i1 = mIndMap(x, f) + mInterval.min();
00055 return mIpl(mAcc, *this, i1,f, mInterval.max(), mInterval.min());
00056
00057
00058
00059 }
00060
00061
00063 FunctionTable& endpoints(index_t min, index_t max){
00064 mInterval.endpoints(min, max-1);
00065 mIndMap.max(max-min, 1.);
00066 return *this;
00067 }
00068
00069
00071 template <class Gen>
00072 FunctionTable& operator+=(Gen& g){
00073 for(uint32_t i=0; i<size(); ++i) (*this)[i] += g();
00074 return *this;
00075 }
00076
00077 template <class Gen>
00078 FunctionTable& operator+=(const Gen& g){
00079 for(uint32_t i=0; i<size(); ++i) (*this)[i] += g();
00080 return *this;
00081 }
00082
00083 protected:
00084 IndexMap<double> mIndMap;
00085 Interval<index_t> mInterval;
00086 Sipl<T> mIpl;
00087 Sacc mAcc;
00088
00089 virtual void onResize(){ mIndMap.max(size(), 1.); }
00090 };
00091
00092
00093
00094
00095
00096
00097
00098 template <uint32_t B, class T>
00099 class TablePow2{
00100 public:
00101
00102 enum{ N = 1<<B };
00103
00104 const T& operator[](unsigned i) const { return mElems[i]; }
00105 T& operator[](unsigned i){ return mElems[i]; }
00106
00108
00111 const T& read(double phase) const {
00112 return read(phaseR2I(phase));
00113 }
00114
00116 const T& read(uint32_t phase) const {
00117 return (*this)[phase >> shift()];
00118 }
00119
00121 T readL(uint32_t phase) const {
00122 const T& lo = read(phase);
00123 const T& hi = read(phase + oneIndex());
00124 float fr = gam::fraction(bits(), phase);
00125 return lo + (hi - lo)*fr;
00126 }
00127
00128 static uint32_t mask(){ return N-1; }
00129 static uint32_t size(){ return N; }
00130 static uint32_t bits(){ return B; }
00131 static uint32_t shift(){ return 32U-B; }
00132 static uint32_t oneIndex(){ return 1<<shift(); }
00133
00134 protected:
00135 T mElems[N];
00136 static uint32_t phaseR2I(double v){ return static_cast<uint32_t>(v * 4294967296.); }
00137 };
00138
00139
00140
00141
00142
00143
00144
00145 template <unsigned B=10, unsigned D=2, class TComplex=Complex<double> >
00146 class CSinTable{
00147 public:
00148 typedef TablePow2<B, TComplex> Arc;
00149
00150 CSinTable(){ init(); }
00151
00153 TComplex operator()(double phase){
00154 return (*this)(uint32_t(phase * 4294967296.));
00155 }
00156
00158 TComplex operator()(uint32_t p){
00159
00160 p >>= shift();
00161
00162
00163 TComplex r(arc(D-1)[p & Arc::mask()]);
00164
00165
00166 for(unsigned i=2; i<D+1; ++i){
00167 p >>= B;
00168 r *= arc(D-i)[p & Arc::mask()];
00169 }
00170 return r;
00171 }
00172
00173 static uint32_t shift(){ return 32U - (B*D); }
00174
00175 private:
00176 enum{ M = Arc::N };
00177
00178
00179 static Arc * arcs(){
00180 static Arc tables[D];
00181 return tables;
00182 }
00183
00184 static Arc& arc(unsigned res){ return arcs()[res]; }
00185
00186 static void init(){
00187 static bool tabulate=true;
00188 if(tabulate){
00189 tabulate=false;
00190 unsigned long long N = M;
00191
00192 for(unsigned j=0; j<D; ++j){
00193 for(unsigned i=0; i<M; ++i){
00194 double p = (i*M_PI)/(N>>1);
00195 arc(j)[i].real() = cos(p);
00196 arc(j)[i].imag() = sin(p);
00197 }
00198 N *= M;
00199 }
00200
00201 }
00202 }
00203 };
00204
00205
00206
00208 template <class T>
00209 class UnitMapper{
00210 public:
00211
00213 enum MapType{
00214 MAP_LIN,
00215 MAP_POW,
00216 MAP_EXP2
00217 };
00218
00219
00220 T min, max, p1;
00221 MapType type;
00222 bool clip;
00223
00224
00225 UnitMapper();
00226
00232 UnitMapper(T max, T min=0., T p1=1., MapType type = MAP_POW, bool clip=true);
00233
00234
00236 UnitMapper& set(T max, T min=0., T p1=1., MapType type = MAP_POW, bool clip=true);
00237
00238 T map(T unit);
00239 T unmap(T value);
00240
00241 private:
00242 T mapLin (T u);
00243 T mapPow (T u);
00244 T mapExp2(T u);
00245
00246
00247 void doClip(T& nrm){ if(clip) nrm = scl::clip(nrm); }
00248 };
00249
00250
00251
00252
00253
00254
00255 template <class T> UnitMapper<T>::UnitMapper(){
00256 set(T(1));
00257 }
00258
00259 template <class T> UnitMapper<T>::UnitMapper(T max, T min, T p1, MapType type, bool clip){
00260 set(max, min, p1, type, clip);
00261 }
00262
00263 template <class T> UnitMapper<T>& UnitMapper<T>::set(T max, T min, T p1, MapType type, bool clip){
00264 this->max = max;
00265 this->min = min;
00266 this->p1 = p1;
00267 this->type = type;
00268 this->clip = clip;
00269 return *this;
00270 }
00271
00272 template <class T> inline T UnitMapper<T>::map(T u){
00273 switch(type){
00274 case MAP_LIN: return mapLin(u);
00275 case MAP_POW: return mapPow(u);
00276 case MAP_EXP2: return mapExp2(u);
00277 default:;
00278 }
00279 }
00280
00281 template <class T> T UnitMapper<T>::unmap(T v){
00282 switch(type){
00283 case MAP_LIN:
00284 return scl::mapLin(v, min, max, T(0), T(1));
00285
00286 case MAP_POW:
00287 v = scl::mapLin(v, min, max, T(0), T(1));
00288 return pow(v, 1. / p1);
00289
00290
00291 case MAP_EXP2:
00292 v = log2(v / p1);
00293 return scl::mapLin(v, min, max, T(0), T(1));
00294
00295
00296 default:
00297 return 0;
00298 }
00299 }
00300
00301
00302 template <class T> T UnitMapper<T>::mapLin(T u){
00303 doClip(u); return min + u * (max - min);
00304 }
00305
00306 template <class T> T UnitMapper<T>::mapPow(T u){
00307 doClip(u); return (T)scl::mapPower(u, max, min, p1);
00308 }
00309
00310 template <class T> T UnitMapper<T>::mapExp2(T u){
00311 doClip(u);
00312 return (T)(pow(2., scl::mapPower(u, max, min, 1.)) * p1);
00313 }
00314
00315 }
00316
00317 #endif