template class Vec; template class SysVector; template class FlatVector; template class Vector; extern void CheckVecRange(int s, int i); extern void CheckVecRange(int s, int i, int j); /* Static base class for \Ref{FlatVector}. Provides size, range check methods. */ /* class BaseFlatVector { protected: unsigned int s; BaseFlatVector (int as) : s(as) { ; } void CheckRange(int i) const; void CheckRange(int i, int j) const; }; */ /** A simple vector. Has size and generic data-pointer. No memory allocation/deallocation. User must provide memory. */ template class FlatVector : public MatExpr > { protected: /// vector size int s; /// the data T * data; public: typedef T TELEM; typedef typename mat_traits::TSCAL TSCAL; /// FlatVector () { ; } /// set size and mem FlatVector (unsigned int as, T * adata) : s(as), data(adata) { ; } /// set size and mem FlatVector (unsigned int as, void * adata) : s(as), data(static_cast (adata)) { ; } /// useful to put FlatVector over Vec template explicit FlatVector (const MatExpr & v) : s(v.Height()), data(const_cast(&v.Spec()(0))) { ; } template FlatVector (Vec & v) : s(v.Size()), data(const_cast(&v(0))) { ; } FlatVector (int as, LocalHeap & lh) : s(as), data((T*)lh.Alloc(s*sizeof(T))) { ; } /* template FlatVector (ExprAndMemory e) : s(e.Exp().Height()), data(e.Memory()) { for (int i = 0; i < s; i++) data[i] = e.Exp()(i); } */ FlatVector (const SysVector & sv) : s(sv.Size()*sv.BlockSize() / mat_traits::VDIM), data (sv(0)) { ; } void AssignMemory (int as, LocalHeap & lh) { s = as; data = (T*)lh.Alloc(s*sizeof(T)); } void AssignMemory (int as, T * mem) { s = as; data = mem; } FlatVector & operator= (const FlatVector & v) { for (int i = 0; i < s; i++) data[i] = v(i); return *this; } template FlatVector & operator= (const Expr & v) { return MatExpr::operator= (v); } FlatVector & operator= (TSCAL scal) { for (int i = 0; i < s; i++) data[i] = scal; return *this; } TELEM & operator() (int i) { #ifdef CHECK_RANGE CheckVecRange(s,i); #endif return data[i]; } const TELEM & operator() (int i) const { #ifdef CHECK_RANGE CheckVecRange(s,i); #endif return data[i]; } const TELEM & operator() (int i, int j) const { #ifdef CHECK_RANGE CheckVecRange(s,i); #endif return data[i]; } TELEM & operator[] (int i) { #ifdef CHECK_RANGE CheckVecRange(s,i); #endif return data[i]; } const TELEM & operator[] (int i) const { #ifdef CHECK_RANGE CheckVecRange(s,i); #endif return data[i]; } FlatVector Range(int first, int last) { return FlatVector (last-first+1, data+first); } const FlatVector Range(int first, int last) const { return FlatVector (last-first+1, data+first); } int Size () const { return s; } int Height () const { return s; } int Width () const { return 1; } const void * Data () const { return static_cast(data); } void * Data () { return static_cast(data); } }; /** A Vector class with memory allocation/deallocation */ template class Vector : public FlatVector { public: typedef typename mat_traits::TSCAL TSCAL; explicit Vector (int as) : FlatVector (as, new T[as]) { ; } ~Vector() { delete [] this->data; } Vector & operator= (TSCAL scal) { FlatVector::operator= (scal); return *this; } void SetSize(int as) { if (this->s == as) return; delete [] this->data; this->s = as; this->data = new T[this->s]; } template Vector & operator= (const Expr & v) { MatExpr >::operator= (v); return *this; } }; // A system vector (non completely functional) template class FlatSysVector : public MatExpr > { protected: int s; int blocksize; T * data; public: typedef FlatVector TELEM; typedef typename mat_traits::TSCAL TSCAL; FlatSysVector (int as, int bs, T * adata) : s(as), blocksize(bs), data(adata) { ; } FlatSysVector (int as, int bs, LocalHeap & lh) : s(as), blocksize(bs), data (new (lh) T[as*bs]) { ; } FlatSysVector (const FlatSysVector & sv) : s(sv.Size()), blocksize(sv.BlockSize()), data (sv(0)) { ; } FlatSysVector & operator= (const FlatSysVector & v) { for (int i = 0; i < this->s * this->bs; i++) data[i] = v.data[i]; return *this; } template FlatSysVector & operator= (const Expr & v) { return MatExpr::operator= (v); } FlatSysVector & operator= (TSCAL s) { for (int i = 0; i < this->s*this->bs; i++) data[i] = s; return *this; } TELEM operator() (int i) { return FlatVector (blocksize, &data[i*blocksize]); } const TELEM operator() (int i) const { return FlatVector (blocksize, &data[i*blocksize]); } const TELEM operator() (int i, int j) const { return FlatVector (blocksize, &data[i*blocksize]); } FlatSysVector Range(int first, int last) { return FlatSysVector (last-first+1, blocksize, data+(first*blocksize)); } const FlatSysVector Range(int first, int last) const { return FlatSysVector (last-first+1, blocksize, data+(first*blocksize)); } int Size () const { return s; } int Height () const { return s; } int Width () const { return 1; } }; /** A vector of fixed size. Useful as entry type in system vectors. */ template class Vec : public MatExpr > // , protected BaseVec { /// the values T data[S]; public: /// type of the elements typedef T TELEM; /// is the element double or complex ? typedef typename mat_traits::TSCAL TSCAL; /// a vec is a S times 1 matrix, the according colume vector typedef Vec::TV_COL> TV_COL; /// a vec is a S times 1 matrix, the according row vector typedef Vec<1, typename mat_traits::TV_ROW> TV_ROW; enum { SIZE = S }; /// height of matrix enum { HEIGHT = S }; /// with of matrix enum { WIDTH = 1 }; /// constructor, no initialization Vec () { ; } /// copy vector Vec (const Vec & v) : MatExpr () { for (int i = 0; i < S; i++) data[i] = v.data[i]; } /// initialize with values Vec (const TSCAL & scal) { for (int i = 0; i < S; i++) data[i] = scal; } /// initialize with expression template Vec (const Expr & v) { (*this) = v; } /// initialize zeroth and first elements Vec (const T & s1, const T & s2) { data[0] = s1; data[1] = s2; } /// initialize zeroth, first, and second elements Vec (const T & s1, const T & s2, const T & s3) { data[0] = s1; data[1] = s2; data[2] = s3; } /// copy vector Vec & operator= (const Vec & v) { for (int i = 0; i < S; i++) data[i] = v.data[i]; return *this; } /// assign scalar value Vec & operator= (TSCAL scal) { for (int i = 0; i < S; i++) data[i] = scal; return *this; } /// assign expression template Vec & operator= (const Expr & v) { MatExpr::operator= (v); return *this; } /// access vector TELEM & operator() (int i) { #ifdef CHECK_RANGE CheckVecRange(S,i); #endif return data[i]; } /// access vector const TELEM & operator() (int i) const { #ifdef CHECK_RANGE CheckVecRange(S,i); #endif return data[i]; } /// access vector const TELEM & operator() (int i, int j) const { #ifdef CHECK_RANGE CheckVecRange(S,i); #endif return data[i]; } /// vector size int Size () const { return S; } /// corresponding matrix height int Height () const { return S; } /// corresponding matrix with int Width () const { return 1; } }; /// cross product inline Vec<3> Cross (const Vec<3> & a, const Vec<3> & b) { Vec<3> prod; prod(0) = a(1) * b(2) - a(2) * b(1); prod(1) = a(2) * b(0) - a(0) * b(2); prod(2) = a(0) * b(1) - a(1) * b(0); return prod; } /// output vector template inline ostream & operator<< (ostream & ost, const Vec & v) { for (int i = 0; i < S; i++) ost << " " << setw(7) << v(i); return ost; }