CARMA C++
Vector.h
Go to the documentation of this file.
1 #ifndef CARMA_SERVICES_VECTOR_H
2 #define CARMA_SERVICES_VECTOR_H
3 
12 
13 #include <cmath>
14 #include <iostream>
15 #include <iomanip>
16 #include <sstream>
17 #include <vector>
18 
19 namespace carma {
20  namespace services {
21 
22  template <class type>
23  class Matrix;
24 
25  template <class type>
26  class Vector;
27 
28  template <class type>
29  std::ostream& operator<<(std::ostream& os,
30  const Vector<type>& vec);
31  template <class type>
32  std::ostringstream& operator<<(std::ostringstream& os,
33  const Vector<type>& vec);
34 
38  template<class type>
39  class Vector {
40 
41  public:
42 
46  Vector(unsigned n);
47 
51  Vector(unsigned n, type initializer);
52 
56  Vector(type el0, type el1, type el2);
57 
61  Vector(const Vector<type>& vec);
62 
66  virtual ~Vector();
67 
71  unsigned size() const {
72  return nEl_;
73  }
74 
78  double magnitude();
79 
83  type& operator[](unsigned i);
84 
85  type operator[](unsigned i) const;
86 
95  const Vector<type> cross(const Vector<type>& vec);
96 
100  const type operator*(const Vector<type>& vec);
101 
105  const Vector<type> operator+(const Vector<type>& vec);
106 
110  const Vector<type> operator-(const Vector<type>& vec);
111 
115  const Vector<type> operator*(const type factor);
116 
120  const Vector<type> operator/(const type factor);
121 
125  const Vector<type> operator+(const type offset);
126 
130  const Vector<type> operator-(const type offset);
131 
132  //------------------------------------------------------------
133  // Non-member friends
134  //------------------------------------------------------------
135 
139  friend std::ostream& carma::services::operator << <>
140  (std::ostream& os, const Vector<type>& vec);
141 
145  friend std::ostringstream& carma::services::operator << <>
146  (std::ostringstream& os, const Vector<type>& vec);
147 
151  Vector();
152 
156  inline void resize(unsigned n) {
157  data_.resize(n);
158  nEl_ = n;
159  }
160 
161  protected:
162 
163  // Privately, Vector is implemented as a std::vector
164 
165  std::vector<type> data_;
166 
170  unsigned nEl_;
171 
175  friend class Matrix< type >;
176 
177 
178  }; // End class Vector
179 
183  template<class type>
185  {
186  nEl_ = 0;
187  }
188 
192  template<class type>
193  Vector<type>::Vector(type el0, type el1, type el2)
194  {
195  data_.resize(3);
196  nEl_ = 3;
197 
198  data_[0] = el0;
199  data_[1] = el1;
200  data_[2] = el2;
201  }
202 
206  template<class type>
207  Vector<type>::Vector(unsigned n)
208  {
209  data_.resize(n);
210  nEl_ = n;
211  }
212 
216  template<class type>
217  Vector<type>::Vector(unsigned n, type initializer)
218  : data_(n, initializer)
219  {
220  nEl_ = n;
221  }
222 
226  template<class type>
228  : data_(vec.data_)
229  {
230  nEl_ = vec.data_.size();
231  }
232 
252  template<class type>
254 
258  template <class type>
260  {
261  double sum=0.0;
262 
263  for(unsigned iel=0; iel < data_.size(); iel++)
264  sum += data_[iel]*data_[iel];
265 
266  return sqrt(sum);
267  }
268 
269  template <class type>
271  {
272  unsigned dsize = data_.size();
273  unsigned vsize = vec.data_.size();
274  if(dsize ==0 || vsize ==0) {
276  "Vector::cross - Vector has zero size.");
277  }
278 
279  if( dsize != vsize ) {
281  "Vector::cross - Vectors must have the same size");
282  }
283 
284  // return size is always 3.
285  Vector<type> product(3);
286 
287  switch (dsize) {
288  case 2:
289  // crossing xy vector returns a vector perpendicular
290  // to both, i.e. parallel to z.
291  product.data_[0] = 0.0;
292  product.data_[1] = 0.0;
293  product.data_[2] = data_[0]*vec.data_[1]
294  - data_[1]*vec.data_[0];
295  break;
296  case 3:
297  product.data_[0] = data_[1]*vec.data_[2]
298  - data_[2]*vec.data_[1];
299  product.data_[1] = data_[2]*vec.data_[0]
300  - data_[0]*vec.data_[2];
301  product.data_[2] = data_[0]*vec.data_[1]
302  - data_[1]*vec.data_[0];
303  break;
304  default:
305  // ok, technically, it is also defined for 7 dimensions,
306  // but i bet we'll never use that!
308  "Vector::cross - Cross product defined only for 2 and 3 dimensions"
309  );
310  }
311  return product;
312  }
313 
317  template<class type>
318  type& Vector<type>::operator[](unsigned i)
319  {
320  if(i > data_.size()-1) {
321  std::ostringstream os;
322  os << "Vector::operator[] - Vector has no element: " << i;
324  }
325 
326  return data_[i];
327  }
328 
329  template<class type>
330  type Vector<type>::operator[](const unsigned i) const
331  {
332  if(i > data_.size()-1) {
333  std::ostringstream os;
334  os << "Vector::operator[] - Vector has no element: " << i;
336  }
337 
338  return data_[i];
339  }
340 
344  template<class type>
345  const type Vector<type>::operator*(const Vector<type>& vec)
346  {
347  if(data_.size()==0 || vec.data_.size()==0) {
349  "Vector::operator* : Received vector size of zero");
350  }
351 
352  if( data_.size() != vec.data_.size() ) {
354  "Vector::operator* : Vectors must have the same size");
355  }
356 
357  type sum = data_[0] * vec.data_[0];
358 
359  for(unsigned i=1; i < data_.size(); i++)
360  sum += data_[i] * vec.data_[i];
361 
362  return sum;
363  }
364 
368  template<class type>
369  const Vector<type>
371  {
372 
373  if(data_.size()==0 || vec.data_.size()==0) {
375  "Vector::operator+ : Received vector size of zero"
376  );
377  }
378 
379  if(data_.size() != vec.data_.size()) {
381  "Vector::operator+ : Vectors must have the same size"
382  );
383  }
384 
385  Vector<type> result(nEl_);
386 
387  for(unsigned i=0; i < data_.size(); i++)
388  result.data_[i] = (data_[i] + vec.data_[i]);
389 
390  return result;
391  }
392 
396  template<class type>
397  const Vector<type>
399  {
400  if(nEl_==0 || vec.nEl_==0) {
402  "Vector::operator- : Received vector size of zero"
403  );
404  }
405 
406  if(nEl_ != vec.nEl_) {
408  "Vector::operator- : Vectors must have the same size"
409  );
410  }
411 
412  Vector<type> result(nEl_);
413 
414  for(unsigned i=0; i < nEl_; i++)
415  result.data_[i] = (data_[i] - vec.data_[i]);
416 
417  return result;
418  }
419 
423  template<class type>
424  const Vector<type>
425  Vector<type>::operator*(const type factor)
426  {
427  if(nEl_==0) {
429  "Vector::operator*(scalar) : Vector has zero size."
430  );
431  }
432 
433  Vector<type> result(nEl_);
434 
435  for(unsigned i=0; i < nEl_; i++)
436  result.data_[i] = (data_[i] * factor);
437 
438  return result;
439  }
440 
444  template<class type>
445  const Vector<type>
446  Vector<type>::operator/(const type factor)
447  {
448  if(nEl_==0) {
450  "Vector::operator/(scalar) : Vector has zero size."
451  );
452  }
453 
454  Vector<type> result(nEl_);
455 
456  for(unsigned i=0; i < nEl_; i++)
457  result.data_[i] = (data_[i] / factor);
458 
459  return result;
460  }
461 
465  template<class type>
466  const Vector<type>
467  Vector<type>::operator+(const type offset)
468  {
469  if(nEl_==0) {
471  "Vector::operator+(scalar) : Vector has zero size."
472  );
473  }
474 
475  Vector<type> result(nEl_);
476 
477  for(unsigned i=0; i < nEl_; i++)
478  result.data_[i] = (data_[i] + offset);
479 
480  return result;
481  }
482 
486  template<class type>
487  const Vector<type>
488  Vector<type>::operator-(const type offset)
489  {
490  if(nEl_==0) {
492  "Vector::operator-(scalar) : Vector has zero size."
493  );
494  }
495 
496  Vector<type> result(nEl_);
497 
498  for(unsigned i=0; i < nEl_; i++)
499  result.data_[i] = (data_[i] - offset);
500 
501  return result;
502  }
503 
507  template <class type>
508  std::ostream& operator<<(std::ostream& os,
509  const Vector<type>& vec)
510  {
511  os << "(";
512  for(unsigned i=0; i < vec.data_.size(); i++) {
513  if(i != 0)
514  os << ", ";
515  os << ::std::setw(18) << ::std::setprecision(12) << vec.data_[i];
516  }
517  os << ")";
518  return os;
519  }
520 
524  template <class type>
525  std::ostringstream& operator<<(std::ostringstream& os,
526  const Vector<type>& vec)
527  {
528  os << "(";
529  for(unsigned i=0; i < vec.data_.size(); i++) {
530  if(i != 0)
531  os << ", ";
532  os << ::std::setw(18) << ::std::setprecision(12) << vec.data_[i];
533  }
534  os << ")";
535  return os;
536  }
537 
538  } // End namespace services
539 } // End namespace carma
540 
541 #endif // End #ifndef CARMA_SERVICES_VECTOR_H
virtual ~Vector()
Destructor.
Definition: Vector.h:253
This class handles standard mathematical vector operations.
Definition: Location.h:21
Exception class for errors.
const type operator*(const Vector< type > &vec)
Vector multiplication, aka dot product.
Definition: Vector.h:345
unsigned nEl_
Store the length.
Definition: Vector.h:170
Vector()
Private constructor with no arguments.
Definition: Vector.h:184
const Vector< type > operator/(const type factor)
......................................................................
Definition: Vector.h:446
const Vector< type > cross(const Vector< type > &vec)
Assignment void operator=(const Vector&lt;type&gt;&amp; vec);.
Definition: Vector.h:270
This class handles standard mathematical matrix operations.
Definition: Matrix.h:26
unsigned size() const
Query the size of the vector.
Definition: Vector.h:71
Exception class for errors The exception comes with a text string that can be printed or logged...
const Vector< type > operator-(const Vector< type > &vec)
......................................................................
Definition: Vector.h:398
#define CARMA_EXCEPTION(x, y)
Trick to get the file name and line number passed to the exception handler.
std::ostream & operator<<(std::ostream &os, const carma::services::Angle &angle)
Define the &lt;&lt; operator to allow, e.g.
void resize(unsigned n)
Private resize operator.
Definition: Vector.h:156
double magnitude()
Get the magnitude of a vector.
Definition: Vector.h:259
type & operator[](unsigned i)
Define an operator for accessing elements of the vector.
Definition: Vector.h:318
const Vector< type > operator+(const Vector< type > &vec)
Vector addition.
Definition: Vector.h:370