arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

vec.h

Go to the documentation of this file.
00001 /*
00002 * $Id: vec.h,v 1.5 2003/09/15 17:15:31 jmk Exp $
00003 */
00004 ///////////////////////////////////////////////////////////////////////////
00005 //              _____________  ______________________    __   __  _____
00006 //             /  ________  |  |   ___   ________   /   |  \ /  \   |
00007 //            |  |       |  |_ |  |_ |  |       /  /    \__  |      |
00008 //            |  |  ___  |  || |  || |  |      /  /        | |      |
00009 //            |  | |   \ |  || |  || |  |     /  /      \__/ \__/ __|__
00010 //            |  | |_@  ||  || |  || |  |    /  /          Institute
00011 //            |  |___/  ||  ||_|  || |  |   /  /_____________________
00012 //             \_______/  \______/ | |__|  /___________________________
00013 //                        |  |__|  |
00014 //                         \______/
00015 //                    University of Utah       
00016 //                           2002
00017 ///////////////////////////////////////////////////////////////////////////
00018 
00019 // vec.h
00020 
00021 
00022 #ifndef GUTZ_VEC_BASE_H
00023 #define GUTZ_VEC_BASE_H
00024 
00025 // using alloc policies declared in this file...
00026 #include "mathExt.h"
00027 #include <assert.h>
00028 
00029 namespace gutz {
00030 
00031 /////////////////////////////////////////////////////////////////////////
00032 /////////////////////////////////////////////////////////////////////////
00033 /// a vector templated in type and dimension, plus delete policy, but 
00034 ///  you can ignore this in 99% of normal use
00035 /// a generic vector, with constructors up to length 10
00036 /// bridges the gap between vectors and arrays, very similar to 
00037 /// an array1 but, supports smaller 1D arrays that are used like
00038 /// N Dimensional vectors.
00039 /////////////////////////////////////////////////////////////////////////
00040 /////////////////////////////////////////////////////////////////////////
00041 
00042 template<class T, int V_DIM>
00043 class vec {
00044 public:
00045 
00046   //typedef typename T Type;
00047    enum THE_DIM {
00048       DIM = V_DIM
00049    };
00050 
00051    vec() : v(new T[V_DIM]) {}
00052    vec(const vec &vee);
00053    /// the last value in a constructor gets replicated to the
00054    /// end of the vec if there are more values in the vector
00055    /// than specified by the constructor.
00056    vec(T v1);
00057    vec(T v1, T v2); 
00058    vec(T v1, T v2, T v3);
00059    vec(T v1, T v2, T v3, T v4);
00060    vec(T v1, T v2, T v3, T v4, T v5);
00061    vec(T v1, T v2, T v3, T v4, T v5, T v6);
00062    vec(T v1, T v2, T v3, T v4, T v5, T v6, T v7);
00063    vec(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8);
00064    vec(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9);
00065    vec(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9, T v10);
00066    /// copy data array, will depend on AllocPolicy used...
00067    /// when numVals == -1 you indicate that the "vee" array
00068    /// is at least as big as the dimension of this vec
00069    vec(T *vee, int numVals=-1);
00070 
00071    virtual ~vec() { if(v) delete[] v; }
00072 
00073    ///////////////////////////////////////
00074    /// Public data Member
00075    T *v;
00076    ///////////////////////////////////////
00077 
00078    /// element accessor
00079    T &operator[](int i)            { return v[i]; }
00080    const T operator[](int i) const { return v[i]; }
00081 
00082    //// these are all the same, preference/symantics really :)
00083    int len()  { return DIM; }
00084    int dim()  { return DIM; }
00085    int size() { return DIM; }
00086 
00087    /// assignment =
00088    vec &operator=(const vec &v)
00089    { for(int i=0; i<DIM; ++i) this->v[i] = v.v[i]; return *this;}
00090    //vec &operator=(const T& val)
00091    //{ for(int i=0; i<DIM; ++i) this->v[i] = val; return *this;}
00092    /// +=
00093    vec &operator+=(const T& v)
00094    { for(int i=0; i<DIM; ++i) this->v[i] += v; return *this;}
00095    vec &operator+=(const vec &v)
00096    { for(int i=0; i<DIM; ++i) this->v[i] += v.v[i]; return *this;}
00097    /// -=
00098    vec &operator-=(const T& v)
00099    { for(int i=0; i<DIM; ++i) this->v[i] -= v; return *this;}
00100    vec &operator-=(const vec &v)
00101    { for(int i=0; i<DIM; ++i) this->v[i] += v.v[i]; return *this;}
00102    /// *=
00103    vec &operator*=(const T& v)
00104    { for(int i=0; i<DIM; ++i) this->v[i] *= v; return *this;}
00105    vec &operator*=(const vec &v)
00106    { for(int i=0; i<DIM; ++i) this->v[i] *= v.v[i]; return *this;}
00107    /// /=
00108    vec &operator/=(const T& v)
00109    { for(int i=0; i<DIM; ++i) this->v[i] /= v; return *this;}
00110    vec &operator/=(const vec &v)
00111    { for(int i=0; i<DIM; ++i) this->v[i] /= v.v[i]; return *this;}
00112 
00113    /// negate -
00114    vec operator-() const
00115    {
00116       T *vee = new T[DIM];
00117       for(int i=0; i<DIM; ++i) vee[i] = -this->v[i];
00118       return vec(vee, true);
00119    }
00120    /// subtract
00121    vec operator-(const T& v) const
00122    {
00123       T *vee = new T[DIM];
00124       for(int i=0; i<DIM; ++i) vee[i] = this->v[i] - v;
00125       return vec(vee, true);
00126    }
00127    vec operator-(const vec &v) const
00128    {
00129       T *vee = new T[DIM];
00130       for(int i=0; i<DIM; ++i) vee[i] = this->v[i] - v.v[i];
00131       return vec(vee, true);
00132    }
00133    /// add
00134    vec operator+(const T& v) const
00135    {
00136       T *vee = new T[DIM];
00137       for(int i=0; i<DIM; ++i) vee[i] = this->v[i] + v;
00138       return vec(vee, true);
00139    }
00140    vec operator+(const vec &v) const
00141    {
00142       T *vee = new T[DIM];
00143       for(int i=0; i<DIM; ++i) vee[i] = this->v[i] + v.v[i];
00144       return vec(vee, true);
00145    }
00146    /// multiply
00147    vec operator*(const T& v) const
00148    {
00149       T *vee = new T[DIM];
00150       for(int i=0; i<DIM; ++i) vee[i] = this->v[i] * v;
00151       return vec<T,DIM>(vee, true);
00152    }
00153    vec operator*(const vec &v) const
00154    {
00155       T *vee = new T[DIM];
00156       for(int i=0; i<DIM; ++i) vee[i] = this->v[i] * v.v[i];
00157       return vec(vee, true);
00158    }
00159    /// divide
00160    vec operator/(const T& v) const
00161    {
00162       T *vee = new T[DIM];
00163       for(int i=0; i<DIM; ++i) vee[i] = this->v[i] / v;
00164       return vec(vee, true);
00165    }
00166    vec operator/(const vec &v) const
00167    {
00168       T *vee = new T[DIM];
00169       for(int i=0; i<DIM; ++i) vee[i] = this->v[i] / v.v[i];
00170       return vec(vee, true);
00171    }
00172 
00173    /// comparison ops ===================
00174    /// equal
00175    bool operator==(const vec &v) const
00176    {
00177       for(int i=0; i<DIM; ++i)
00178          if(this->v[i] != v[i]) return false;
00179       return true;
00180    }
00181    bool operator==(T val) const
00182    {
00183       for(int i=0; i<DIM; ++i)
00184          if(this->v[i] != val) return false;
00185       return true;
00186    }
00187    /// not equal
00188    bool operator!=(const vec &v) const
00189    { return !(operator==(v)); }
00190    /// less
00191    bool operator< (const vec &v) const
00192    {    
00193       for(int i=0; i<DIM; ++i)
00194          if(this->v[i] >= v.v[i]) return false;
00195       return true;
00196    }
00197    /// less equal
00198    bool operator<=(const vec &v) const
00199    {
00200       for(int i=0; i<DIM; ++i)
00201          if(this->v[i] > v.v[i]) return false;
00202       return true;
00203    }
00204    /// greater
00205    bool operator> (const vec &v) const
00206    { return !(operator<=(v)); }
00207    /// greater equal
00208    bool operator>=(const vec &v) const
00209    { return !(operator<(v)); }
00210 
00211    /// other ops ===========================
00212    /// L1 norm
00213    T normL1() const
00214    {
00215       T tmp = 0;
00216       for(int i=0; i<DIM; ++i)
00217          tmp += this->v[i];
00218       return tmp;
00219    }
00220    /// L2 norm squared
00221    T norm2() const
00222    {
00223       T tmp=0;
00224       for(int i=0; i<DIM; ++i)
00225          tmp += this->v[i] * this->v[i];
00226       return tmp;
00227    }
00228    /// L2 norm
00229    T norm() const 
00230    {
00231       return T(sqrt(norm2()));
00232    }
00233    /// Normalize, side-effect op, normalizes this vector!
00234    T normalize()
00235    {
00236       T tmp = norm();
00237       (*this) *= 1.0/tmp;
00238       return tmp;
00239    }
00240 
00241    /// dot product
00242    T dot(const vec &v)
00243    {
00244       return ((*this) * v).normL1;
00245    }
00246    /// abs of all elements
00247    vec abs()
00248    {
00249       T *tmp = new T[DIM];
00250       for(int i=0; i<DIM; ++i)
00251          tmp[i] = g_abs(this->v[i]);
00252       return vec(tmp,true);
00253    }
00254 
00255 protected:
00256    /// do not copy data, just pointer (always shallow copy)
00257    /// the "vee" array MUST be at least as long as this array
00258    /// and created using NEW.  The array will be deleted with
00259    /// this class. Not public cuz it's a little confusing.
00260    vec(T *vee, bool noCpy);
00261 };
00262 
00263 /////////////////////////////////////////////////////////////////////////
00264 /////////////////////////////////////////////////////////////////////////
00265 /// typedefs
00266 /////////////////////////////////////////////////////////////////////////
00267 /////////////////////////////////////////////////////////////////////////
00268 
00269 /// there are specific classes for vectors 2-4
00270 
00271 typedef vec<float, 5>  vec5f;
00272 typedef vec<float, 6>  vec6f;
00273 typedef vec<float, 7>  vec7f;
00274 typedef vec<float, 8>  vec8f;
00275 typedef vec<float, 9>  vec9f;
00276 typedef vec<float, 10> vec10f;
00277 
00278 typedef vec<double, 5>  vec5d;
00279 typedef vec<double, 6>  vec6d;
00280 typedef vec<double, 7>  vec7d;
00281 typedef vec<double, 8>  vec8d;
00282 typedef vec<double, 9>  vec9d;
00283 typedef vec<double, 10> vec10d;
00284 
00285 
00286 /////////////////////////////////////////////////////////////////////////
00287 /////////////////////////////////////////////////////////////////////////
00288 /// auxillary ops
00289 /////////////////////////////////////////////////////////////////////////
00290 /////////////////////////////////////////////////////////////////////////
00291 
00292 ///////////////////////////////////////
00293 /// side-effect min (no temporary created) alters the first vec
00294 /// in parameter list to be the min (for each element) of the 
00295 /// two vectors
00296 template<class T, int D> inline
00297 vec<T,D> vs_min(vec<T,D> &v1, const vec<T,D> &v2)
00298 {
00299    for(int i=0; i<D; ++i)
00300    {
00301       v1[i] = v1[i] < v2[i] ? v1[i] : v2[i];
00302    }
00303    return v1;
00304 }
00305 
00306 ///////////////////////////////////////
00307 /// side-effect max (no temporary created) alters the first vec
00308 /// in parameter list to be the max (for each element) of the 
00309 /// two vectors
00310 template<class T, int D> inline
00311 vec<T,D> vs_max(vec<T,D> &v1, const vec<T,D> &v2)
00312 {
00313    for(int i=0; i<D; ++i)
00314    {
00315       v1[i] = v1[i] > v2[i] ? v1[i] : v2[i];
00316    }
00317    return v1;
00318 }
00319 
00320 ///////////////////////////////////////
00321 /// <<
00322 template<class T, int D>
00323 std::ostream&
00324 operator<<(std::ostream &os, const vec<T,D> &v)
00325 {
00326    for(int i=0; i<D; ++i)
00327       os << v[i] << " ";
00328    return os;
00329 }
00330 
00331 /////////////////////////////////////////////////////////////////////////
00332 /////////////////////////////////////////////////////////////////////////
00333 /// implementation of vec_base
00334 /////////////////////////////////////////////////////////////////////////
00335 /////////////////////////////////////////////////////////////////////////
00336 
00337 /////////////////////////////////////////////////////////////////////////
00338 /// more operators
00339 template<class T, int D>
00340 vec<T,D> operator+(const T &val, const vec<T,D> &v)
00341 {
00342    T *vee = new T[D];
00343    for(int i=0; i<D; ++i) vee[i] = val + v.v[i];
00344    return vec<T,D>(vee,true);
00345 }
00346 
00347 template<class T, int D>
00348 vec<T,D> operator-(const T &val, const vec<T,D> &v)
00349 {
00350    T *vee = new T[D];
00351    for(int i=0; i<D; ++i) vee[i] = val - v.v[i];
00352    return vec<T,D>(vee,true);
00353 }
00354 
00355 template<class T, int D>
00356 vec<T,D> operator*(const T &val, const vec<T,D> &v)
00357 {
00358    T *vee = new T[D];
00359    for(int i=0; i<D; ++i) vee[i] = val * v.v[i];
00360    return vec<T,D>(vee,true);
00361 }
00362 
00363 template<class T,  int D>
00364 vec<T,D> operator/(const T &val, const vec<T,D> &v)
00365 {
00366    T *vee = new T[D];
00367    for(int i=0; i<D; ++i) vee[i] = val / v.v[i];
00368    return vec<T,D>(vee,true);
00369 }
00370 
00371 
00372 /////////////////////////////////////////////////////////////////////////
00373 /// constructors 
00374 
00375 template<class T, int D>
00376 vec<T,D>::vec(const vec<T,D> &vee)
00377 : v(new T[D])
00378 {
00379    for(int i=0; i<D; ++i)
00380    {
00381       this->v[i] = vee.v[i];
00382    }
00383 }
00384 
00385 template<class T, int D>
00386 vec<T,D>::vec(T *vee, int numVals)
00387 : v(new T[D])
00388 {
00389    if(numVals == -1)
00390    {
00391       for(int i=0; i<D; ++i)
00392       {
00393          this->v[i] = vee[i];
00394       }
00395    }
00396    else
00397    {
00398       for(int i=0; i<g_min(D,numVals); ++i)
00399       {
00400          this->v[i] = vee[i];
00401       }
00402    }
00403 }
00404 
00405 template<class T, int D>
00406 vec<T,D>::vec(T *vee, bool noCpy)
00407 : v(vee)
00408 {
00409 }
00410 
00411 
00412 template<class T, int D>
00413 vec<T,D>::vec(T v1)
00414 : v(new T[D])
00415 {
00416    assert(D >= 1);
00417    for(int i=0; i<D; ++i)
00418       v[i] = v1;
00419 }
00420 
00421 template<class T, int D>
00422 vec<T,D>::vec(T v1, T v2)
00423 : v(new T[D])
00424 {
00425    assert(D >= 2);
00426    v[0] = v1; v[1] = v2;
00427    for(int i=2; i<D; ++i)
00428       v[i] = v2;
00429 }
00430 
00431 template<class T, int D>
00432 vec<T,D>::vec(T v1, T v2, T v3)
00433 : v(new T[D])
00434 {
00435    assert(D >= 3);
00436    v[0] = v1; v[1] = v2; v[2] = v3;
00437    for(int i=3; i<D; ++i)
00438       v[i] = v3;
00439 }
00440 
00441 template<class T, int D>
00442 vec<T,D>::vec(T v1, T v2, T v3, T v4)
00443 : v(new T[D])
00444 {
00445    assert(D >= 4);
00446    v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4;
00447    for(int i=4; i<D; ++i)
00448       v[i] = v4;
00449 }
00450 
00451 template<class T, int D>
00452 vec<T,D>::vec(T v1, T v2, T v3, T v4, T v5)
00453 : v(new T[D])
00454 {
00455    assert(D >= 5);
00456    v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; v[4] = v5;
00457    for(int i=5; i<D; ++i)
00458       v[i] = v5;
00459 }
00460 
00461 template<class T, int D>
00462 vec<T,D>::vec(T v1, T v2, T v3, T v4, T v5, T v6)
00463 : v(new T[D])
00464 {
00465    assert(D >= 6);
00466    v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; v[4] = v5; v[5] = v6;
00467    for(int i=6; i<D; ++i)
00468       v[i] = v6;
00469 }
00470 
00471 template<class T, int D>
00472 vec<T,D>::vec(T v1, T v2, T v3, T v4, T v5, T v6, T v7)
00473 : v(new T[D])
00474 {
00475    assert(D >= 7);
00476    v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; v[4] = v5; v[5] = v6;
00477    v[6] = v7;
00478    for(int i=7; i<D; ++i)
00479       v[i] = v7;
00480 }
00481 
00482 template<class T, int D>
00483 vec<T,D>::vec(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8)
00484 : v(new T[D])
00485 {
00486    assert(D >= 8);
00487    v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; v[4] = v5; v[5] = v6;
00488    v[6] = v7; v[7] = v8;
00489    for(int i=8; i<D; ++i)
00490       v[i] = v8;
00491 }
00492 
00493 template<class T, int D>
00494 vec<T,D>::vec(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9)
00495 : v(new T[D])
00496 {
00497    assert(D >= 9);
00498    v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; v[4] = v5; v[5] = v6;
00499    v[6] = v7; v[7] = v8; v[8] = v9;
00500    for(int i=9; i<D; ++i)
00501       v[i] = v9;
00502 }
00503 
00504 template<class T, int D>
00505 vec<T,D>::vec(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9, T v10)
00506 : v(new T[D])
00507 {
00508    assert(D >= 10);
00509    v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4; v[4] = v5; v[5] = v6;
00510    v[6] = v7; v[7] = v8; v[8] = v9; v[9] = v[10];
00511    for(int i=10; i<D; ++i)
00512       v[i] = v10;
00513 }
00514 
00515 
00516 
00517 }//end namespace gutz
00518 
00519 
00520 #endif
00521 
00522 

Send questions, comments, and bug reports to:
jmk