KrisLibrary  1.0.0
VectorTemplate.h
1 #ifndef MATH_VECTOR_TEMPLATE_H
2 #define MATH_VECTOR_TEMPLATE_H
3 
4 #include "math.h"
5 #include "infnan.h"
6 #include <assert.h>
7 #include <iosfwd>
8 #include <vector>
9 class File;
10 
11 namespace Math {
12 
18 template <class T>
20 {
21 public:
22  typedef VectorIterator<T> MyT;
23  typedef T value_type;
24  typedef T* pointer;
25  typedef T& reference;
26  typedef size_t difference_type;
27  typedef std::random_access_iterator_tag iterator_category;
28 
29  inline VectorIterator() :ptr(NULL),stride(0) {}
30  inline VectorIterator(const MyT& i) :ptr(i.ptr),stride(i.stride) {}
31  inline VectorIterator(T* _ptr,int _stride) :ptr(_ptr),stride(_stride) {}
32  inline T& operator*() { return *ptr; }
33  inline T* operator->() { return ptr; }
34  inline MyT& operator ++() { ptr+=stride; return *this; }
35  inline MyT& operator --() { ptr-=stride; return *this; }
36  inline MyT& operator ++(int) { ptr+=stride; return *this; }
37  inline MyT& operator --(int) { ptr-=stride; return *this; }
38  //inline MyT& operator +=(int i) { ptr+=i*stride; return *this; }
39  //inline MyT& operator -=(int i) { ptr-=i*stride; return *this; }
40  inline MyT operator +(int i) const { return MyT(ptr+i*stride,stride); }
41  inline MyT operator -(int i) const { return MyT(ptr-i*stride,stride); }
42  inline bool operator !=(const MyT& i) { return ptr!=i.ptr; }
43  inline bool operator ==(const MyT& i) { return ptr==i.ptr; }
44  inline bool operator < (const MyT& i) { return ptr<i.ptr; }
45  inline bool operator > (const MyT& i) { return ptr>i.ptr; }
46  inline size_t operator - (const MyT& i) const { return (ptr-i.ptr)/stride; }
47 
48  T *ptr;
49  int stride;
50 };
51 
123 template <class T>
124 class VectorTemplate
125 {
126 public:
127  typedef VectorTemplate<T> MyT;
128  typedef VectorIterator<T> ItT;
129 
130  VectorTemplate();
131  VectorTemplate(const MyT&);
132  VectorTemplate(MyT&&);
133  VectorTemplate(int n);
134  VectorTemplate(int n, T initval);
135  VectorTemplate(int n, const T* vals);
136  VectorTemplate(const std::vector<T>& vals);
137  ~VectorTemplate();
138 
139  inline T* getPointer() const { return vals; }
140  inline int getCapacity() const { return capacity; }
141  inline T* getStart() const { return vals+base; }
142  inline ItT begin() const { return ItT(vals+base,stride); }
143  inline ItT end() const { return ItT(vals+base+n*stride,stride); }
144  inline int size() const { return n; }
145  inline bool empty() const { return n==0; }
146 
147  void resize(int size);
148  void resize(int size, T initval);
149  void resizePersist(int size);
150  void resizePersist(int size, T initval);
151  void clear();
152 
153  MyT& operator = (const MyT& v);
154  MyT& operator = (MyT&& v);
155  bool operator == (const MyT&) const;
156  inline bool operator != (const MyT& a) const { return !operator==(a); }
157  inline operator T* ();
158  inline operator const T* () const;
159  operator std::vector<T> () const;
160  inline MyT& operator = (const std::vector<T>& v) { copy(v); return *this; }
161  inline const T& operator() (int i) const { return operator[](i); }
162  inline T& operator() (int i) { return operator[](i); }
163  inline const T& operator[] (int i) const;
164  inline T& operator[] (int i);
165  inline void operator += (const MyT& a) { inc(a); }
166  inline void operator -= (const MyT& a) { dec(a); }
167  inline void operator *= (T c) { inplaceMul(c); }
168  inline void operator /= (T c) { inplaceDiv(c); }
169 
170  void copy(const MyT&);
171  template <class T2> void copy(const VectorTemplate<T2>&);
172  void copy(const T* vals);
173  template <class T2> void copy(const std::vector<T2>& vals);
174  void copySubVector(int i,const MyT&);
175  void swap(MyT&);
176  void swapCopy(MyT&);
177  void add(const MyT&, const MyT&);
178  void sub(const MyT&, const MyT&);
179  void mul(const MyT&, T);
180  void div(const MyT&, T);
181  void axpby(T a,const MyT& x,T b,const MyT& y);
182  //the following are increment-type methods
183  void inc(const T&);
184  void inc(const MyT&);
185  void dec(const MyT&);
186  void madd(const MyT&, T);
187 
188  void setRef(const MyT&,int base=0,int stride=1,int size=-1);
189  void setRef(T* vals,int length,int base=0,int stride=1,int size=-1);
190  void set(T);
191  void setZero();
192  void setNegative(const MyT&);
193  void setNormalized(const MyT&);
194  void setConjugate(const MyT&);
195 
196  void inplaceNegative();
197  void inplaceMul(T);
198  void inplaceDiv(T);
199  void inplaceNormalize();
200  void inplaceConjugate();
201 
202  void getCopy(MyT&) const;
203  void getCopy(T* vals) const;
204  void getSubVectorCopy(int i,MyT&) const;
205  void getRef(MyT&,int base=0,int stride=1,int size=-1) const;
206  inline void getNegative(MyT& v) const { v.setNegative(*this); }
207  inline void getNormalized(MyT& v) const { v.setNormalized(*this); }
208  inline void getConjugate(MyT& v) const { v.setConjugate(*this); }
209 
210  inline bool isReference() const { return !allocated; }
211  inline bool isUninitialized() const { return vals==NULL; }
212  inline bool isValidIndex(int i) const { return i>=0 && i<n; }
213  inline bool isCompact() const { return (stride==1); }
214  bool isValid() const;
215  bool isZero(T eps=0) const;
216  bool isEqual(const MyT&,T eps=0) const;
217 
218  T dot(const MyT&) const;
219  T dotSelf() const;
220  T norm() const;
221  T normSquared() const;
222  T distance(const MyT&) const;
223  T distanceSquared(const MyT&) const;
224  T minElement(int* index=NULL) const;
225  T maxElement(int* index=NULL) const;
226  T minAbsElement(int* index=NULL) const;
227  T maxAbsElement(int* index=NULL) const;
228 
229  bool Read(File&);
230  bool Write(File&) const;
231 
232  void componentMul(const MyT& a,const MyT& b);
233  void componentDiv(const MyT& a,const MyT& b);
234  void componentMadd(const MyT& a,const MyT& b);
235  void inplaceComponentMul(const MyT& c);
236  void inplaceComponentDiv(const MyT& c);
237 
239  template <class UnaryOp>
240  void componentOp(const MyT& a,UnaryOp& f);
242  template <class BinaryOp>
243  void componentOp(const MyT& a,const MyT& b,BinaryOp& f);
245  template <class BinaryOp>
246  void componentOp(const MyT& a,T c,BinaryOp& f);
247 
249  template <class UnaryOp>
250  void inplaceComponentOp(UnaryOp& f);
252  template <class BinaryOp>
253  void inplaceComponentOp(const MyT& c,BinaryOp& f);
255  template <class BinaryOp>
256  void inplaceComponentOp(T c,BinaryOp& f);
257 
258 private:
259  //read only
260  T* vals;
261  int capacity;
262  bool allocated;
263 
264 public:
265  //alterable
266  int base,stride,n;
267 };
268 
269 class Complex;
270 typedef class VectorTemplate<float> fVector;
271 typedef class VectorTemplate<double> dVector;
272 typedef class VectorTemplate<Complex> cVector;
273 
274 template <class T>
275 std::ostream& operator << (std::ostream&, const VectorTemplate<T>&);
276 template <class T>
277 std::istream& operator >> (std::istream&, VectorTemplate<T>&);
278 
279 
280 
281 template <class T>
282 template <class UnaryOp>
283 void VectorTemplate<T>::componentOp(const MyT& a,UnaryOp& f)
284 {
285  if(empty()) resize(a.n);
286  else assert(size() == a.size());
287  T* v=getStart();
288  T* va=a.getStart();
289  for(int i=0;i<n;i++,v+=stride,va+=a.stride)
290  *v = f(*va);
291 }
292 
293 template <class T>
294 template <class BinaryOp>
295 void VectorTemplate<T>::componentOp(const MyT& a,const MyT& b,BinaryOp& f)
296 {
297  assert(a.size()==b.size());
298  if(empty()) resize(a.n);
299  else assert(size() == a.size());
300  T* v=getStart();
301  T* va=a.getStart();
302  T* vb=b.getStart();
303  for(int i=0;i<n;i++,v+=stride,va+=a.stride,vb+=b.stride)
304  *v = f(*va,*vb);
305 }
306 
307 template <class T>
308 template <class BinaryOp>
309 void VectorTemplate<T>::componentOp(const MyT& a,T c,BinaryOp& f)
310 {
311  if(empty()) resize(a.n);
312  else assert(size() == a.size());
313  T* v=getStart();
314  T* va=a.getStart();
315  for(int i=0;i<n;i++,v+=stride,va+=a.stride)
316  *v = f(*va,c);
317 }
318 
319 template <class T>
320 template <class UnaryOp>
322 {
323  assert(!empty());
324  T* v=getStart();
325  for(int i=0;i<n;i++,v+=stride)
326  *v = f(*v);
327 }
328 
329 template <class T>
330 template <class BinaryOp>
331 void VectorTemplate<T>::inplaceComponentOp(const MyT& c,BinaryOp& f)
332 {
333  assert(!empty());
334  assert(size() == c.size());
335  T* v=getStart();
336  T* vc=c.getStart();
337  for(int i=0;i<n;i++,v+=stride,vc+=c.stride)
338  *v = f(*v,*vc);
339 }
340 
341 template <class T>
342 template <class BinaryOp>
344 {
345  assert(!empty());
346  T* v=getStart();
347  for(int i=0;i<n;i++,v+=stride)
348  *v = f(*v,c);
349 }
350 
351 //VectorTemplate inlined methods
352 template <class T>
353 inline const T& VectorTemplate<T>::operator[](int i) const
354 {
355  return vals[i*stride+base];
356 }
357 
358 template <class T>
359 inline T& VectorTemplate<T>::operator[](int i)
360 {
361  return vals[i*stride+base];
362 }
363 
364 template <class T>
365 inline VectorTemplate<T>::operator T* ()
366 {
367  assert(isCompact());
368  return vals+base;
369 }
370 
371 template <class T>
372 inline VectorTemplate<T>::operator const T* () const
373 {
374  assert(isCompact());
375  return vals+base;
376 }
377 
378 template <class T>
379 inline bool FuzzyEquals(const VectorTemplate<T>& a, const VectorTemplate<T>& b,T eps)
380 {
381  return a.isEqual(b,eps);
382 }
383 
384 template <class T>
385 inline bool FuzzyZero(const VectorTemplate<T>& a,T eps)
386 {
387  return a.isZero(eps);
388 }
389 
390 template <class T>
391 inline T dot(const VectorTemplate<T>& a, const VectorTemplate<T>& b)
392 {
393  return a.dot(b);
394 }
395 
396 template <class T>
397 inline T norm(const VectorTemplate<T>& a)
398 {
399  return a.norm();
400 }
401 
403 template <class T>
404 inline bool IsFinite(const VectorTemplate<T>& x)
405 {
406  for(int i=0;i<x.n;i++)
407  if(!IsFinite(x(i))) return false;
408  return true;
409 }
410 
412 template <class T>
413 inline bool HasNaN(const VectorTemplate<T>& x)
414 {
415  for(int i=0;i<x.n;i++)
416  if(IsNaN(x(i))) return true;
417  return false;
418 }
419 
421 template <class T>
422 inline int HasInf(const VectorTemplate<T>& x)
423 {
424  for(int i=0;i<x.n;i++)
425  if(IsInf(x(i))) return IsInf(x(i));
426  return 0;
427 }
428 
429 
430 
433 template <class T>
434 inline VectorTemplate<T> operator + (const VectorTemplate<T>& a, const VectorTemplate<T>& b)
435 {
437  v.add(a,b);
438  return v;
439 }
440 
441 template <class T>
442 inline VectorTemplate<T> operator - (const VectorTemplate<T>& a, const VectorTemplate<T>& b)
443 {
445  v.sub(a,b);
446  return v;
447 }
448 
449 template <class T>
450 inline VectorTemplate<T> operator * (const VectorTemplate<T>& a, T c)
451 {
453  v.mul(a,c);
454  return v;
455 }
456 
457 template <class T>
458 inline VectorTemplate<T> operator * (T c, const VectorTemplate<T>& a)
459 {
461  v.mul(a,c);
462  return v;
463 }
464 
465 template <class T>
466 inline VectorTemplate<T> operator / (const VectorTemplate<T>& a, T c)
467 {
469  v.div(a,c);
470  return v;
471 }
472 
473 template <class T>
474 inline VectorTemplate<T> operator / (T c, const VectorTemplate<T>& a)
475 {
477  v.div(a,c);
478  return v;
479 }
480 
481 } //namespace Math
482 
483 namespace std
484 {
485  template<class T> inline void swap(Math::VectorTemplate<T>& a, Math::VectorTemplate<T>& b)
486  {
487  a.swap(b);
488  }
489 } //namespace std
490 
491 
492 #endif
Common math typedefs, constants, functions.
int IsInf(double x)
Returns +1 if x is +inf, -1 if x is -inf, and 0 otherwise.
Definition: infnan.cpp:40
Cross-platform infinity and not-a-number routines.
Definition: rayprimitives.h:132
void inplaceComponentOp(UnaryOp &f)
for each element xi, sets xi = f(xi)
Definition: VectorTemplate.h:321
int HasInf(const MatrixTemplate< T > &A)
returns nonzero if any element of A is infinite
Definition: MatrixTemplate.h:262
void componentOp(const MyT &a, UnaryOp &f)
for each element xi, sets xi = f(ai)
Definition: VectorTemplate.h:283
double dot(double a, double b)
Dot product of a scalar as a 1-d vector.
Definition: math.h:220
bool FuzzyZero(double a, double eps=dEpsilon)
Returns true if a is zero within +/- eps.
Definition: math.h:224
Complex number class (x + iy).
Definition: complex.h:17
bool HasNaN(const MatrixTemplate< T > &A)
returns true if any element of A is NaN
Definition: MatrixTemplate.h:252
An iterator through VectorTemplate elements.
Definition: VectorTemplate.h:19
void copy(const T &a, T *out, int n)
Definition: arrayutils.h:34
int IsNaN(double x)
Returns nonzero if x is not-a-number (NaN)
Definition: infnan.cpp:9
Contains all definitions in the Math package.
Definition: WorkspaceBound.h:12
A vector over the field T.
Definition: function.h:9
bool FuzzyEquals(double a, double b, double eps=dEpsilon)
Returns true if a and b are within +/- eps.
Definition: math.h:222
A cross-platform class for reading/writing binary data.
Definition: File.h:47
int IsFinite(double x)
Returns nonzero unless x is infinite or a NaN.
Definition: infnan.cpp:23