Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

nrutil_mtl.h

Go to the documentation of this file.
00001 #ifndef _NR_UTIL_H_
00002 #define _NR_UTIL_H_
00003 
00004 #include <string>
00005 #include <cmath>
00006 #include <complex>
00007 #include <iostream>
00008 using namespace std;
00009 
00010 typedef double DP;
00011 
00012 template<class T>
00013 inline const T SQR(const T a) {return a*a;}
00014 
00015 template<class T>
00016 inline const T MAX(const T &a, const T &b)
00017         {return b > a ? (b) : (a);}
00018 
00019 inline float MAX(const double &a, const float &b)
00020         {return b > a ? (b) : float(a);}
00021 
00022 inline float MAX(const float &a, const double &b)
00023         {return b > a ? float(b) : (a);}
00024 
00025 template<class T>
00026 inline const T MIN(const T &a, const T &b)
00027         {return b < a ? (b) : (a);}
00028 
00029 inline float MIN(const double &a, const float &b)
00030         {return b < a ? (b) : float(a);}
00031 
00032 inline float MIN(const float &a, const double &b)
00033         {return b < a ? float(b) : (a);}
00034 
00035 template<class T>
00036 inline const T SIGN(const T &a, const T &b)
00037         {return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);}
00038 
00039 inline float SIGN(const float &a, const double &b)
00040         {return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);}
00041 
00042 inline float SIGN(const double &a, const float &b)
00043         {return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);}
00044 
00045 template<class T>
00046 inline void SWAP(T &a, T &b)
00047         {T dum=a; a=b; b=dum;}
00048 
00049 namespace NR {
00050         inline void nrerror(const string error_text)
00051         // Numerical Recipes standard error handler
00052         {
00053                 cerr << "Numerical Recipes run-time error..." << endl;
00054                 cerr << error_text << endl;
00055                 cerr << "...now exiting to system..." << endl;
00056                 exit(1);
00057         }
00058 }
00059 
00060 #include "mtl/mtl.h"
00061 using namespace mtl;
00062 
00063 // mtl Wrapper File
00064 // This is the file that "joins" the mtl Vector<> and Matrix<> classes
00065 // to the NRVec and NRMat classes by the Wrapper Class Method
00066 
00067 // NRVec contains a Vector and a &Vector. All its constructors, except the
00068 // conversion constructor, create the Vector and point the &Vector to it.
00069 // The conversion constructor only points the &Vector. All operations
00070 // (size, subscript) are through the &Vector, which as a reference
00071 // (not pointer) has no indirection overhead.
00072 
00073 template<class T>
00074 class NRVec {
00075 // Use the std::vector based dense1D for our Vector type
00076 typedef dense1D<T> Vector;
00077 protected:              //access required in NRVec<bool> below
00078         Vector myvec;
00079         Vector &myref;
00080 public:
00081         NRVec<T>() : myvec(), myref(myvec) {}
00082         explicit NRVec<T>(const int n) : myvec(n), myref(myvec) {}
00083         NRVec<T>(const T &a, int n) : myvec(n), myref(myvec) {
00084                 for (int i=0; i<n; i++) myvec[i] = a;}
00085         NRVec<T>(const T *a, int n) : myvec(n), myref(myvec) {
00086                 for (int i=0; i<n; i++) myvec[i] = *a++;}
00087         NRVec<T>(Vector &rhs) : myref(rhs) {}
00088         // conversion constructor makes a special NRVec pointing to Vector's data
00089         // this handles Vector actual args sent to NRVec formal args in functions
00090         NRVec(const NRVec<T>& rhs) : myvec(rhs.myref.size()), myref(myvec)
00091                 {copy(rhs.myref,myref);}
00092         // copy constructor. mtl copy constructor
00093         // does shallow copy only. so use copy() instead
00094         inline NRVec& operator=(const NRVec& rhs) {
00095                 if (myref.size() != rhs.myref.size())
00096                         myref.resize(rhs.myref.size());
00097                 copy(rhs.myref,myref); return *this;}
00098         inline int size() const {return myref.size();}
00099         inline T & operator[](const int i) const {return myref[i];}
00100         inline operator Vector() const {return myref;}
00101         // conversion operator to Vector
00102         // handles NRVec function return types when used in Vector expressions
00103         ~NRVec() {}
00104 };
00105 
00106 //The std:vector class has a specialization for vector<bool> that doesn't
00107 //work with the above wrapper class scheme. So implement our own
00108 //specialization as a derived class of NRVec<int>. This could cause
00109 //problems if you mix mtl::Vector<bool> with NRVec<bool>!
00110 
00111 template <> class NRVec<bool> : public NRVec<int> {
00112 public:
00113         NRVec() : NRVec<int>() {}
00114         explicit NRVec(const int n) : NRVec<int>(n) {}
00115         NRVec(const bool &a, int n) : NRVec<int>(int(a),n) {}
00116         NRVec(const bool *a, int n) : NRVec<int>(n) {
00117                 for (int i=0; i<n; i++) myvec[i] = *a++;}
00118 //note: defaults OK for copy constructor and assignment
00119 };
00120 
00121 template <class T>
00122 class NRMat {
00123 // Use the matrix generator to select a matrix type
00124 typedef matrix< T,
00125         rectangle<>,
00126         dense<>,
00127         row_major>::type Matrix;
00128 protected:
00129         Matrix mymat;
00130         Matrix &myref;
00131 public:
00132         NRMat() : mymat(), myref(mymat) {}
00133         NRMat(int n, int m) : mymat(n,m), myref(mymat) {}
00134         NRMat(const T& a, int n, int m) : mymat(n,m), myref(mymat) {
00135                 for (int i=0; i< n; i++)
00136                         for (int j=0; j<m; j++)
00137                                 mymat[i][j] = a;}
00138         NRMat(const T* a, int n, int m) : mymat(n,m), myref(mymat) {
00139                 for (int i=0; i< n; i++)
00140                         for (int j=0; j<m; j++)
00141                                 mymat[i][j] = *a++;}
00142         NRMat<T>(Matrix &rhs) : myref(rhs) {}
00143         NRMat(const NRMat& rhs) :
00144                 mymat(rhs.myref.nrows(),rhs.myref.ncols()), myref(mymat)
00145                 {copy(rhs.myref,myref);}
00146         inline NRMat& operator=(const NRMat& rhs) {
00147                 if (myref.nrows() != rhs.myref.nrows() && myref.ncols() !=
00148                         rhs.myref.ncols()) {
00149                                 cerr << "assignment with incompatible matrix sizes\n";
00150                                 abort();
00151                 }
00152                 copy(rhs.myref,myref); return *this;
00153         }
00154         typename Matrix::OneD operator[](const int i) const {return myref[i];}
00155         //return type is whatever Matrix returns for a single [] dereference
00156         inline int nrows() const {return myref.nrows();}
00157         inline int ncols() const {return myref.ncols();}
00158         inline operator Matrix() const {return myref;}
00159         ~NRMat() {}
00160 };
00161 
00162 template <> class NRMat<bool> : public NRMat<int> {
00163 public:
00164         NRMat() : NRMat<int>() {}
00165         explicit NRMat(int n, int m) : NRMat<int>(n,m) {}
00166         NRMat(const bool &a, int n, int m) : NRMat<int>(int(a),n,m) {}
00167         NRMat(const bool *a, int n, int m) : NRMat<int>(n,m) {
00168                 for (int i=0; i< n; i++)
00169                         for (int j=0; j<m; j++)
00170                                 mymat[i][j] = *a++;}
00171 //note: defaults OK for copy constructor and assignment
00172 };
00173 
00174 template <class T>
00175 class NRMat3d {
00176 private:
00177         int nn;
00178         int mm;
00179         int kk;
00180         T ***v;
00181 public:
00182         NRMat3d();
00183         NRMat3d(int n, int m, int k);
00184         inline T** operator[](const int i);     //subscripting: pointer to row i
00185         inline const T* const * operator[](const int i) const;
00186         inline int dim1() const;
00187         inline int dim2() const;
00188         inline int dim3() const;
00189         ~NRMat3d();
00190 };
00191 
00192 template <class T>
00193 NRMat3d<T>::NRMat3d(): nn(0), mm(0), kk(0), v(0) {}
00194 
00195 template <class T>
00196 NRMat3d<T>::NRMat3d(int n, int m, int k) : nn(n), mm(m), kk(k), v(new T**[n])
00197 {
00198         int i,j;
00199         v[0] = new T*[n*m];
00200         v[0][0] = new T[n*m*k];
00201         for(j=1; j<m; j++)
00202                 v[0][j] = v[0][j-1] + k;
00203         for(i=1; i<n; i++) {
00204                 v[i] = v[i-1] + m;
00205                 v[i][0] = v[i-1][0] + m*k;
00206                 for(j=1; j<m; j++)
00207                         v[i][j] = v[i][j-1] + k;
00208         }
00209 }
00210 
00211 template <class T>
00212 inline T** NRMat3d<T>::operator[](const int i) //subscripting: pointer to row i
00213 {
00214         return v[i];
00215 }
00216 
00217 template <class T>
00218 inline const T* const * NRMat3d<T>::operator[](const int i) const
00219 {
00220         return v[i];
00221 }
00222 
00223 template <class T>
00224 inline int NRMat3d<T>::dim1() const
00225 {
00226         return nn;
00227 }
00228 
00229 template <class T>
00230 inline int NRMat3d<T>::dim2() const
00231 {
00232         return mm;
00233 }
00234 
00235 template <class T>
00236 inline int NRMat3d<T>::dim3() const
00237 {
00238         return kk;
00239 }
00240 
00241 template <class T>
00242 NRMat3d<T>::~NRMat3d()
00243 {
00244         if (v != 0) {
00245                 delete[] (v[0][0]);
00246                 delete[] (v[0]);
00247                 delete[] (v);
00248         }
00249 }
00250 
00251 //The next 3 classes are used in artihmetic coding, Huffman coding, and
00252 //wavelet transforms respectively. This is as good a place as any to put them!
00253 
00254 class arithcode {
00255 private:
00256         NRVec<unsigned long> *ilob_p,*iupb_p,*ncumfq_p;
00257 public:
00258         NRVec<unsigned long> &ilob,&iupb,&ncumfq;
00259         unsigned long jdif,nc,minint,nch,ncum,nrad;
00260         arithcode(unsigned long n1, unsigned long n2, unsigned long n3)
00261                 : ilob_p(new NRVec<unsigned long>(n1)),
00262                 iupb_p(new NRVec<unsigned long>(n2)),
00263                 ncumfq_p(new NRVec<unsigned long>(n3)),
00264                 ilob(*ilob_p),iupb(*iupb_p),ncumfq(*ncumfq_p) {}
00265         ~arithcode() {
00266                 if (ilob_p != 0) delete ilob_p;
00267                 if (iupb_p != 0) delete iupb_p;
00268                 if (ncumfq_p != 0) delete ncumfq_p;
00269         }
00270 };
00271 
00272 class huffcode {
00273 private:
00274         NRVec<unsigned long> *icod_p,*ncod_p,*left_p,*right_p;
00275 public:
00276         NRVec<unsigned long> &icod,&ncod,&left,&right;
00277         int nch,nodemax;
00278         huffcode(unsigned long n1, unsigned long n2, unsigned long n3,
00279                 unsigned long n4) :
00280                 icod_p(new NRVec<unsigned long>(n1)),
00281                 ncod_p(new NRVec<unsigned long>(n2)),
00282                 left_p(new NRVec<unsigned long>(n3)),
00283                 right_p(new NRVec<unsigned long>(n4)),
00284                 icod(*icod_p),ncod(*ncod_p),left(*left_p),right(*right_p) {}
00285         ~huffcode() {
00286                 if (icod_p != 0) delete icod_p;
00287                 if (ncod_p != 0) delete ncod_p;
00288                 if (left_p != 0) delete left_p;
00289                 if (right_p != 0) delete right_p;
00290         }
00291 };
00292 
00293 class wavefilt {
00294 private:
00295         NRVec<DP> *cc_p,*cr_p;
00296 public:
00297         int ncof,ioff,joff;
00298         NRVec<DP> &cc,&cr;
00299         wavefilt() : cc(*cc_p),cr(*cr_p) {}
00300         wavefilt(const DP *a, const int n) :  //initialize to array
00301                 cc_p(new NRVec<DP>(n)),cr_p(new NRVec<DP>(n)),
00302                 ncof(n),ioff(-(n >> 1)),joff(-(n >> 1)),cc(*cc_p),cr(*cr_p) {
00303                         int i;
00304                         for (i=0; i<n; i++)
00305                                 cc[i] = *a++;
00306                         DP sig = -1.0;
00307                         for (i=0; i<n; i++) {
00308                                 cr[n-1-i]=sig*cc[i];
00309                                 sig = -sig;
00310                         }
00311         }
00312         ~wavefilt() {
00313                 if (cc_p != 0) delete cc_p;
00314                 if (cr_p != 0) delete cr_p;
00315         }
00316 };
00317 
00318 //Overloaded complex operations to handle mixed float and double
00319 //This takes care of e.g. 1.0/z, z complex<float>
00320 
00321 inline const complex<float> operator+(const double &a,
00322         const complex<float> &b) { return float(a)+b; }
00323 
00324 inline const complex<float> operator+(const complex<float> &a,
00325         const double &b) { return a+float(b); }
00326 
00327 inline const complex<float> operator-(const double &a,
00328         const complex<float> &b) { return float(a)-b; }
00329 
00330 inline const complex<float> operator-(const complex<float> &a,
00331         const double &b) { return a-float(b); }
00332 
00333 inline const complex<float> operator*(const double &a,
00334         const complex<float> &b) { return float(a)*b; }
00335 
00336 inline const complex<float> operator*(const complex<float> &a,
00337         const double &b) { return a*float(b); }
00338 
00339 inline const complex<float> operator/(const double &a,
00340         const complex<float> &b) { return float(a)/b; }
00341 
00342 inline const complex<float> operator/(const complex<float> &a,
00343         const double &b) { return a/float(b); }
00344 
00345 //some compilers choke on pow(float,double) in single precision. also atan2
00346 
00347 inline float pow (float x, double y) {return pow(double(x),y);}
00348 inline float pow (double x, float y) {return pow(x,double(y));}
00349 inline float atan2 (float x, double y) {return atan2(double(x),y);}
00350 inline float atan2 (double x, float y) {return atan2(x,double(y));}
00351 #endif /* _NR_UTIL_H_ */

Generated on Thu Nov 1 11:51:54 2007 for loon by  doxygen 1.3.9.1