Gamma  0.9.5
Generic Synthesis Library
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
/Users/ljp/code/gamma/trunk/Gamma/Types.h
00001 #ifndef GAMMA_TYPES_H_INC
00002 #define GAMMA_TYPES_H_INC
00003 
00004 /*  Gamma - Generic processing library
00005     See COPYRIGHT file for authors and license information 
00006 
00007     File Description: 
00008     Static (fixed size) POD types including complex numbers, quaternions, 
00009     2,3,4-vectors, 3x3 matrix, and fixed-size array.
00010     
00011 */
00012 
00013 
00014 #include "Gamma/pstdint.h"      // for cross-platform uint32_t, uint16_t, etc...
00015 #include <math.h>
00016 #include <stdlib.h>
00017 
00018 namespace gam{
00019 
00020 typedef float           real;   // default real number type
00021 
00022 
00023 template<class T> class Complex;
00024 template<uint32_t N, class T> class Vec;
00025 
00026 typedef Vec<2,float > float2;
00027 typedef Vec<2,double> double2;
00028 
00029 //typedef Polar<float > Polarf;
00030 //typedef Polar<double> Polard;
00031 //typedef Complex<float > Complexf;
00032 //typedef Complex<double> Complexd;
00033 //typedef Vec2<float> Vec2f;
00034 //typedef Vec2<double> Vec2d;
00035 //typedef Vec3<float> Vec3f;
00036 //typedef Vec3<double> Vec3d;
00037 //typedef Vec4<float> Vec4f;
00038 //typedef Vec4<double> Vec4d;
00039 
00040 
00042 template <class T>
00043 struct Polar{
00044 
00045     union{
00046         struct{ T m, p; };  
00047         T elems[2];         
00048     };
00049 
00050     Polar(const T& p=0): m(1.), p(p){}
00051     Polar(const T& m, const T& p): m(m), p(p){}
00052     Polar(const Complex<T>& v){ *this = v; }
00053 
00054     T& operator[](uint32_t i){ return elems[i];}
00055     const T& operator[](uint32_t i) const { return elems[i]; }
00056 
00057     Polar& operator = (const Complex<T>& v){ m=v.norm(); p=v.arg(); return *this; }
00058 };
00059 
00060 
00062 template <class T=gam::real>
00063 struct Complex{
00064 
00065     typedef Complex<T> C;
00066 
00067     union{
00068         struct{ T r, i; };  
00069         T elems[2];         
00070     };
00071     
00072     Complex(const Complex& v): r(v.r), i(v.i){}
00073     Complex(const Polar<T>& v){ *this = v; }
00074     Complex(const T& r=(T)1, const T& i=(T)0): r(r), i(i){}
00075     Complex(const T& m, const T& p, int fromPolar){ (*this) = Polar<T>(m,p); }
00076 
00077 
00078     // Accessors compatible with std::complex
00079     T& real(){return r;}
00080     const T& real() const {return r;}
00081     T& imag(){return i;}
00082     const T& imag() const {return i;}
00083 
00084 
00085     C& arg(const T& v){ return fromPolar(norm(), v); }                  
00086     C& fromPhase(const T& v){ r=::cos(v); i=::sin(v); return *this; }   
00087     C& fromPolar(const T& m, const T& p){ return (*this)(Polar<T>(m,p)); }  
00088     C& mag(const T& v){ return norm(v); }
00089     C& norm(const T& v){ return fromPolar(v, arg()); }                  
00090     
00091 
00092     C& operator()(const T& vr, const T& vi){ r=vr; i=vi; return *this; }
00093     C& operator()(const Polar<T>& p){ return *this = p; }
00094     T& operator[](uint32_t i){ return elems[i];}
00095     const T& operator[](uint32_t i) const { return elems[i]; }
00096 
00097     bool operator ==(const C& v) const { return (r==v.r) && (i==v.i); }     
00098     bool operator ==(const T& v) const { return (r==v  ) && (i==T(0));}     
00099     bool operator !=(const C& v) const { return (r!=v.r) || (i!=v.i); }     
00100     bool operator > (const C& v) const { return norm2() > v.norm2(); }      
00101     bool operator < (const C& c) const { return norm2() < c.norm2(); }      
00102 
00103     C& operator = (const Polar<T>& v){ r=v.m*::cos(v.p); i=v.m*::sin(v.p); return *this; }
00104     C& operator = (const C& v){ r=v.r; i=v.i; return *this; }
00105     C& operator = (const T& v){ r=v;   i=T(0); return *this; }
00106     C& operator -=(const C& v){ r-=v.r; i-=v.i; return *this; }
00107     C& operator -=(const T& v){ r-=v; return *this; }
00108     C& operator +=(const C& v){ r+=v.r; i+=v.i; return *this; }
00109     C& operator +=(const T& v){ r+=v; return *this; }
00110     C& operator *=(const C& v){ return (*this)(r*v.r - i*v.i, i*v.r + r*v.i); }
00111     C& operator *=(const T& v){ r*=v; i*=v; return *this; }
00112     C& operator /=(const C& v){ return (*this) *= v.recip(); }
00113     C& operator /=(const T& v){ r/=v; i/=v; return *this; }
00114 
00115     C operator - () const { return C(-r, -i); }
00116     C operator - (const C& v) const { return C(*this) -= v; }
00117     C operator - (const T& v) const { return C(*this) -= v; }
00118     C operator + (const C& v) const { return C(*this) += v; }
00119     C operator + (const T& v) const { return C(*this) += v; }
00120     C operator * (const C& v) const { return C(*this) *= v; }
00121     C operator * (const T& v) const { return C(*this) *= v; }
00122     C operator / (const C& v) const { return C(*this) /= v; }
00123     C operator / (const T& v) const { return C(*this) /= v; }
00124     
00125     T arg() const { return atan2(i, r); }                   
00126     C conj() const { return C(r,-i); }                      
00127     T dot(const C& v) const { return r*v.r + i*v.i; }       
00128     C exp() const { return Polar<T>(::exp(r), i); }         
00129     C log() const { return Complex<T>(T(0.5)*::log(norm2()), arg()); } 
00130     T norm() const { return ::sqrt(norm2()); }              
00131     T norm2() const { return dot(*this); }                  
00132     C& normalize(){ return *this /= norm(); }               
00133     C pow(const C& v) const { return ((*this).log()*v).exp(); } 
00134     C pow(const T& v) const { return ((*this).log()*v).exp(); } 
00135     C recip() const { return conj()/norm2(); }              
00136     C sgn() const { return C(*this).normalize(); }          
00137     C sqr() const { return C(r*r-i*i, T(2)*r*i); }          
00138 
00140     C sqrt() const {
00141         static const T c = T(1)/::sqrt(T(2));
00142         T n = norm();
00143         T a = ::sqrt(n+r) * c;
00144         T b = ::sqrt(n-r) * (i<T(0) ? -c : c);      
00145         return C(a,b);
00146     }
00147 
00148     C cos() const { return C(::cos(r)*::cosh(i),-::sin(r)*::sinh(i)); } 
00149     C sin() const { return C(::sin(r)*::cosh(i), ::cos(r)*::sinh(i)); } 
00150 
00151     T abs() const { return norm(); }                        
00152     T mag() const { return norm(); }                        
00153     T magSqr() const { return norm2(); }                    
00154     T phase() const { return arg(); }                       
00155 };
00156 
00157 #define TEM template <class T>
00158 TEM Complex<T> abs(const Complex<T>& c){ return c.abs(); }
00159 TEM Complex<T> exp(const Complex<T>& c){ return c.exp(); }
00160 TEM Complex<T> log(const Complex<T>& c){ return c.log(); }
00161 TEM Complex<T> pow(const Complex<T>& b, const Complex<T>& e){ return b.pow(e); }
00162 TEM Complex<T> operator + (T r, const Complex<T>& c){ return  c+r; }
00163 TEM Complex<T> operator - (T r, const Complex<T>& c){ return -c+r; }
00164 TEM Complex<T> operator * (T r, const Complex<T>& c){ return  c*r; }
00165 TEM Complex<T> operator / (T r, const Complex<T>& c){ return  c.conj()*(r/c.norm()); }
00166 #undef TEM
00167 
00168 
00169 
00171 
00176 template <uint32_t N, class T>
00177 struct Multi{
00178     typedef Multi M;
00179 
00180     T elems[N];
00181     
00183     T& operator[](uint32_t i){ return elems[i];}
00184     
00186     const T& operator[](uint32_t i) const { return elems[i]; }
00187 
00188     #define IT for(uint32_t i=0; i<N; ++i)
00189 
00190     bool operator !=(const M& v){ IT{ if((*this)[i] == v[i]) return false; } return true; }
00191     bool operator !=(const T& v){ IT{ if((*this)[i] == v   ) return false; } return true; }
00192     M& operator   = (const M& v){ IT{ (*this)[i] = v[i]; } return *this; }
00193     M& operator   = (const T& v){ IT{ (*this)[i] = v;    } return *this; }
00194     bool operator ==(const M& v){ IT{ if((*this)[i] != v[i]) return false; } return true; }
00195     bool operator ==(const T& v){ IT{ if((*this)[i] != v   ) return false; } return true; }
00196 
00197     #undef IT
00198 
00200     static uint32_t size(){ return N; }
00201 
00203     void zero(){ memset(elems, 0, N * sizeof(T)); }
00204 };
00205 
00206 
00207 
00209 template <class T=double>
00210 struct ValPower{
00211     ValPower(const T& base=2, const T& expo=0){ (*this)(base, expo); }
00212     
00213     T operator()() const { return mVal; }
00214     T base() const { return mBase; }
00215     T expo() const { return mExpo; }
00216     
00217     void operator()(const T& base, const T& expo){ mBase=base; mExpo=expo; computeVal(); }
00218     void base(const T& v){ mBase=v; computeVal(); }
00219     void expo(const T& v){ mExpo=v; computeVal(); }
00220     void expoAdd(const T& v){ expo(mExpo+v); }
00221 
00222 private:
00223     T mBase, mExpo, mVal;
00224     void computeVal(){ mVal=::pow(mBase, mExpo); }
00225 };
00226 
00227 
00228 
00230 
00234 template <class T>
00235 class Interval{
00236 public:
00237 
00238     Interval()
00239     :   mMin(0), mMax(1){}
00240 
00241     Interval(const T& min, const T& max)
00242     { endpoints(min,max); }
00243 
00244     T center() const { return (max()+min())/T(2); } 
00245 
00247     bool contains(const T& v) const { return v>=min() && v<=max(); }
00248 
00249     bool degenerate() const { return min()==max(); }
00250     T diameter() const { return max()-min(); }      
00251     const T& max() const { return mMax; }           
00252     const T& min() const { return mMin; }           
00253     bool proper() const { return min()!=max(); }    
00254     T radius() const { return diameter()/T(2); }    
00255 
00257     T toUnit(const T& v) const { return (v-min())/diameter(); }
00258     
00259     template <class U>
00260     bool operator == (const Interval<U>& v){ return min()==v.min() && max()==v.max(); }
00261 
00262     template <class U>
00263     bool operator != (const Interval<U>& v){ return !(*this == v); }
00264     
00265     template <class U>
00266     Interval& operator +=(const Interval<U>& v){ endpoints(min()+v.min(), max()+v.max()); return *this; }
00267 
00268     template <class U>
00269     Interval& operator -=(const Interval<U>& v){ endpoints(min()-v.max(), max()-v.min()); return *this; }
00270     
00271     template <class U>
00272     Interval& operator *=(const Interval<U>& v){
00273         T a=min()*v.min(), b=min()*v.max(), c=max()*v.min(), d=max()*v.max();
00274         mMin = min(min(a,b),min(c,d));
00275         mMax = max(max(a,b),max(c,d));
00276         return *this;
00277     }
00278 
00279     template <class U>
00280     Interval& operator /=(const Interval<U>& v){
00281         T a=min()/v.min(), b=min()/v.max(), c=max()/v.min(), d=max()/v.max();
00282         mMin = min(min(a,b),min(c,d));
00283         mMax = max(max(a,b),max(c,d));
00284         return *this;
00285     }
00286 
00288     Interval& center(const T& v){ return centerDiameter(v, diameter()); }
00289 
00291     Interval& diameter(const T& v){ return centerDiameter(center(), v); }
00292 
00294     Interval& centerDiameter(const T& c, const T& d){
00295         mMin = c - d*T(0.5);
00296         mMax = mMin + d;
00297         return *this;
00298     }
00299 
00301     Interval& endpoints(const T& min, const T& max){
00302         mMax=max; mMin=min;
00303         if(mMin > mMax){ T t=mMin; mMin=mMax; mMax=t; }
00304         return *this;
00305     }
00306 
00308     Interval& translate(const T& v){ mMin+=v; mMax+=v; return *this; }
00309 
00311     Interval& max(const T& v){ return endpoints(min(), v); }
00312     
00314     Interval& min(const T& v){ return endpoints(v, max()); }
00315 
00316 private:
00317     T mMin, mMax;
00318 
00319     const T& min(const T& a, const T& b){ return a<b?a:b; }
00320     const T& max(const T& a, const T& b){ return a>b?a:b; }
00321 };
00322 
00323 
00325 
00328 template <class T>
00329 class ValWrap : public Interval<T>{
00330 public:
00331     typedef Interval<T> I;
00332     typedef ValWrap<T> V;
00333 
00334     ValWrap(): I(), mVal(0){}
00335 
00336     ValWrap(const T& max, const T& min=T(0), const T& v=T(0))
00337     : I(min, max), mVal(v)
00338     {}
00339     
00340     ValWrap& operator= (const T& v){ return val(v); }               
00341     ValWrap& operator+=(const T& v){ return val(mVal+v); }          
00342     //ValWrap& operator+=(const ValWrap& v){ return (*this)+=v(); } ///< Add wrapped value
00343     ValWrap& operator-=(const T& v){ return val(mVal-v); }          
00344     //ValWrap& operator-=(const ValWrap& v){ return (*this)-=v(); } ///< Subtract wrapped value
00345 
00346     ValWrap& operator*=(const T& v){ return val(mVal*v); }          
00347     //ValWrap& operator*=(const ValWrap& v){ return (*this)*=v(); } ///< Multiply wrapped value
00348     ValWrap& operator/=(const T& v){ return val(mVal/v); }          
00349     //ValWrap& operator/=(const ValWrap& v){ return (*this)/=v(); } ///< Divide wrapped value
00350     
00351     ValWrap  operator+ (const T& v) const { return V(*this)+=v; }
00352     ValWrap  operator- (const T& v) const { return V(*this)-=v; }
00353     ValWrap  operator* (const T& v) const { return V(*this)*=v; }
00354     ValWrap  operator/ (const T& v) const { return V(*this)/=v; }
00355     
00356     ValWrap  operator++(int){ V r=*this; ++(*this); return r; }     
00357     ValWrap  operator--(int){ V r=*this; --(*this); return r; }     
00358     ValWrap& operator++(){ return val(++mVal); }                    
00359     ValWrap& operator--(){ return val(--mVal); }                    
00360 
00362     ValWrap& endpoints(const T& min, const T& max){
00363         I::endpoints(min,max);
00364         return val(val());
00365     }
00366 
00367     ValWrap& max(const T& v){ I::max(v); return val(val()); }
00368     ValWrap& min(const T& v){ I::min(v); return val(val()); }
00369 
00370     ValWrap& val(T v){
00371     
00372         if(I::proper()){
00373             if(!(v < I::max())){
00374                 T d = I::diameter();
00375                 v -= d;
00376                 if(!(v < I::max())) v -= d * (T)(uint32_t)((v - I::min())/d);
00377             }
00378             else if(v < I::min()){
00379                 T d = I::diameter();
00380                 v += d;
00381                 if(v < I::min()) v += d * (T)(uint32_t)(((I::min() - v)/d) + 1);
00382             }
00383             mVal = v;
00384         }
00385         else{
00386             mVal = I::min();
00387         }
00388         return *this;
00389     }
00390 
00391 
00392     const T& operator()() const { return mVal; }
00393 
00395     double fraction() const {
00396         return I::proper() ? double(val())/I::diameter() : 0.;
00397     }
00398 
00399     const T& val() const { return mVal; }
00400     
00401     operator T() const { return mVal; }
00402     
00403 protected:
00404     T mVal;
00405 };
00406 
00407 
00408 
00409 
00411 template <uint32_t N, class T>
00412 struct Vec : public Multi<N,T> {
00413 
00414     typedef Vec<N,T> V;
00415 
00416     Vec(const T& v=T()){ set(v); }
00417     Vec(const T& v1, const T& v2){ set(v1,v2); }
00418     Vec(const T& v1, const T& v2, const T& v3){ set(v1,v2,v3); }
00419     Vec(const T& v1, const T& v2, const T& v3, const T& v4){ set(v1,v2,v3,v4); }
00420 
00421     template <uint32_t N2, class T2>
00422     Vec(const Vec<N2, T2>& v){ set(v); }
00423 
00425     Vec<2,T> get(int i0, int i1) const {
00426         return Vec<2,T>((*this)[i0], (*this)[i1]); }
00427 
00429     Vec<3,T> get(int i0, int i1, int i2) const {
00430         return Vec<3,T>((*this)[i0], (*this)[i1], (*this)[i2]); }
00431 
00433     Vec<4,T> get(int i0, int i1, int i2, int i3) const {
00434         return Vec<4,T>((*this)[i0], (*this)[i1], (*this)[i2], (*this)[i3]); }
00435 
00436     #define IT(n) for(uint32_t i=0; i<n; ++i)
00437 
00438     bool operator !=(const V& v){ IT(N){ if((*this)[i] == v[i]) return false; } return true; }
00439     bool operator !=(const T& v){ IT(N){ if((*this)[i] == v   ) return false; } return true; }
00440     V& operator = (const V& v){ IT(N) (*this)[i] = v[i]; return *this; }
00441     V& operator = (const T& v){ IT(N) (*this)[i] = v;    return *this; }
00442     bool operator ==(const V& v){ IT(N){ if((*this)[i] != v[i]) return false; } return true; }
00443     bool operator ==(const T& v){ IT(N){ if((*this)[i] != v   ) return false; } return true; }
00444     V  operator * (const V& v) const { V r; IT(N) r[i] = (*this)[i] * v[i]; return r; }
00445     V  operator * (const T& v) const { V r; IT(N) r[i] = (*this)[i] * v;    return r; }
00446     V& operator *=(const V& v){ IT(N) (*this)[i] *= v[i]; return *this; }
00447     V& operator *=(const T& v){ IT(N) (*this)[i] *= v;    return *this; }
00448     V  operator / (const V& v) const { V r; IT(N) r[i] = (*this)[i] / v[i]; return r; }
00449     V  operator / (const T& v) const { V r; IT(N) r[i] = (*this)[i] / v;    return r; }
00450     V& operator /=(const V& v){ IT(N) (*this)[i] /= v[i]; return *this; }
00451     V& operator /=(const T& v){ IT(N) (*this)[i] /= v;    return *this; }
00452     V  operator - (          ) const { V r; IT(N) r[i] = -(*this)[i]; return r; }
00453     V  operator - (const V& v) const { V r; IT(N) r[i] = (*this)[i] - v[i]; return r; }
00454     V  operator - (const T& v) const { V r; IT(N) r[i] = (*this)[i] - v;    return r; }
00455     V& operator -=(const V& v){ IT(N) (*this)[i] -= v[i]; return *this; }
00456     V& operator -=(const T& v){ IT(N) (*this)[i] -= v;    return *this; }
00457     V  operator + (const V& v) const { V r; IT(N) r[i] = (*this)[i] + v[i]; return r; }
00458     V  operator + (const T& v) const { V r; IT(N) r[i] = (*this)[i] + v;    return r; }
00459     V& operator +=(const V& v){ IT(N) (*this)[i] += v[i]; return *this; }
00460     V& operator +=(const T& v){ IT(N) (*this)[i] += v;    return *this; }
00461 
00462 
00463     T dot(const V& v) const { T r=T(0); IT(N) r+=(*this)[i]*v[i]; return r; }
00464     T sum() const { T r=T(0); IT(N) r+=(*this)[i]; return r; }
00465     T mag() const { return sqrt(magSqr()); }
00466     T magSqr() const { return dot(*this); }
00467     
00468     //T norm() const { return sqrt(norm2()); }
00469     //T norm2() const { return dot(*this); }
00470     Vec sgn() const { return V(*this).normalize(); }
00471 
00472     Vec& normalize(){
00473         T msqr = magSqr();
00474         if(msqr > 0) return (*this) /= sqrt(msqr);
00475         return Vec().setIdentity();
00476     }
00477 
00478     template <int N2, class T2>
00479     Vec& set(const Vec<N2, T2> &v){ IT(N<N2?N:N2){ (*this)[i] = T(v[i]); } return *this; }
00480 
00482     Vec& set(const T& v){ return (*this = v); }
00483 
00485     Vec& set(const T& v1, const T& v2){
00486         return set(v1,v2,v1,v1,v1,v1); }
00487 
00489     Vec& set(const T& v1, const T& v2, const T& v3){
00490         return set(v1,v2,v3,v1,v1,v1); }
00491 
00493     Vec& set(const T& v1, const T& v2, const T& v3, const T& v4){
00494         return set(v1,v2,v3,v4,v1,v1); }
00495 
00497     Vec& set(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5){
00498         return set(v1,v2,v3,v4,v5,v1); }
00499 
00501     Vec& set(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6){     
00502         switch(N){
00503         default:(*this)[5] = v6;
00504         case 5: (*this)[4] = v5;
00505         case 4: (*this)[3] = v4;
00506         case 3: (*this)[2] = v3;
00507         case 2: (*this)[1] = v2;
00508         case 1: (*this)[0] = v1;
00509         }
00510         return *this;
00511     }
00512     
00513     Vec& setIdentity(){
00514         (*this)[0] = T(1);
00515         for(uint32_t i=1; i<N; ++i) (*this)[i] = T(0);
00516         return *this;
00517     }
00518 
00519     #undef IT
00520 };
00521 
00522 namespace scl{
00523 
00524 template<uint32_t N, class T>
00525 inline Vec<N,T> abs(Vec<N,T> a){
00526     Vec<N,T> r;
00527     for(uint32_t i=0; i<N; ++i) r[i] = abs(a[i]);
00528     return r;
00529 }
00530 
00531 template<uint32_t N, class T, class U>
00532 inline Vec<N,T> max(Vec<N,T> a, Vec<N,U> b){
00533     Vec<N,T> r;
00534     for(uint32_t i=0; i<N; ++i) r[i] = max(a[i], b[i]);
00535     return r;
00536 }
00537 
00538 template<uint32_t N, class T, class U>
00539 inline Vec<N,T> min(Vec<N,T> a, Vec<N,U> b){
00540     Vec<N,T> r;
00541     for(uint32_t i=0; i<N; ++i) r[i] = min(a[i], b[i]);
00542     return r;
00543 }
00544 
00545 }
00546 
00547 
00549 template <class T>
00550 inline Vec<3,T> cross(const Vec<3,T>& a, const Vec<3,T>& b){
00551     return Vec<3,T>(
00552         a[1]*b[2] - a[2]*b[1],
00553         a[2]*b[0] - a[0]*b[2],
00554         a[0]*b[1] - a[1]*b[0]
00555     );
00556 }
00557 
00559 template <class T>
00560 Vec<3,T> productZXZ(const Complex<T>& a, const Complex<T>& b, const Complex<T>& c){
00561     return Vec<3,T>(
00562         a.r*b.i - a.i*b.r*c.i,
00563         a.i*b.i + a.r*b.r*c.i,
00564         b.r*c.r
00565     );
00566 }
00567 
00569 template <int N, class T>
00570 Vec<N,T> rotate(const Vec<N,T>& v, const Vec<N,T>& p, const Complex<T>& a){
00571     return v*a.r + p*a.i;
00572 }
00573 
00574 template <class VecN, class T>
00575 VecN rotate(const VecN& v, const VecN& p, const Complex<T>& a){
00576     return v*a.r + p*a.i;
00577 }
00578 
00580 template <class VecN, class T>
00581 void rotatePlane(VecN& v1, VecN& v2, const Complex<T>& a){
00582     VecN t = gam::rotate(v1, v2, a);
00583     v2 = gam::rotate(v2, VecN(-v1), a);
00584     v1 = t;
00585 }
00586 
00587 
00588 template <class T>
00589 Vec<3,T> rotateX(const Vec<3,T>& v, const Complex<T>& a){
00590     Complex<T> t(v[1], v[2]); t*=a; return Vec<3,T>(v[0], t[0], t[1]);
00591 }
00592 
00593 template <class T>
00594 Vec<3,T> rotateY(const Vec<3,T>& v, const Complex<T>& a){
00595     Complex<T> t(v[2], v[0]); t*=a; return Vec<3,T>(t[1], v[1], t[0]);
00596 }
00597 
00598 template <class T>
00599 Vec<3,T> rotateZ(const Vec<3,T>& v, const Complex<T>& a){
00600     Complex<T> t(v[0], v[1]); t*=a; return Vec<3,T>(t[0], t[1], v[2]);
00601 }
00602 
00603 
00604 
00605 template<class T> inline double norm(const Complex<T>& v){ return v.norm(); }
00606 template<class T> inline double normCompare(const Complex<T>& v){ return v.norm2(); }
00607 template<int N,class T> inline double norm(const Vec<N,T>& v){ return v.norm(); }
00608 template<int N,class T> inline double normCompare(const Vec<N,T>& v){ return v.norm2(); }
00609 
00610 } // gam::
00611 
00612 #endif