home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 41 / IOPROG_41.ISO / soft / c++ / NUMCPP11.ZIP / vector.hpp < prev   
Encoding:
C/C++ Source or Header  |  1999-05-09  |  9.6 KB  |  306 lines

  1. //===================================================================
  2. // vector.hpp
  3. //
  4. // Version 1.0
  5. //
  6. // Written by:
  7. //   Brent Worden
  8. //   WordenWare
  9. //   email:  Brent@Worden.org
  10. //
  11. // Copyright (c) 1999 WordenWare
  12. //
  13. // Created:  April 10, 1999
  14. // Revised:  
  15. //===================================================================
  16.  
  17. #ifndef _VECTOR_HPP_
  18. #define _VECTOR_HPP_
  19.  
  20. #include <algorithm>
  21. #include <cstdlib>
  22. #include <functional>
  23. #include <numeric>
  24.  
  25. #include "funcobj.hpp"
  26. #include "numerror.h"
  27.  
  28. NUM_BEGIN
  29.  
  30. template<class T>
  31. class Vector
  32. //-------------------------------------------------------------------
  33. // mathematical vector object
  34. //-------------------------------------------------------------------
  35. {
  36. public:
  37.     typedef T* iterator;
  38.     typedef const T* const_iterator;
  39.     typedef size_t size_type;
  40.  
  41.     Vector()
  42.     //---------------------------------------------------------------
  43.     // Create an empty vector.
  44.     //---------------------------------------------------------------
  45.     : _capacity(0), _size(0), _data(NULL) {}
  46.  
  47.     Vector(size_type sz)
  48.     //---------------------------------------------------------------
  49.     // Create a vector with size sz.
  50.     //---------------------------------------------------------------
  51.     : _capacity(sz), _size(sz) { _data = _allocate(sz, T(0)); }
  52.  
  53.     Vector(const Vector<T>& other)
  54.     //---------------------------------------------------------------
  55.     // Create a vector by copying other.
  56.     //---------------------------------------------------------------
  57.     : _capacity(other.size()), _size(_capacity) {
  58.         _data = _allocate(capacity(), T(0));
  59.         std::copy(other.begin(), other.end(), _data);
  60.     }
  61.  
  62.     Vector(const_iterator first, const_iterator last)
  63.     //---------------------------------------------------------------
  64.     // Create a vector with initial values [first, last).
  65.     //---------------------------------------------------------------
  66.     : _capacity(_length(first, last)), _size(_capacity)
  67.     {
  68.         _data = _allocate(capacity(), T(0));
  69.         std::copy(first, last, _data);
  70.     }
  71.         
  72.     ~Vector()
  73.     //---------------------------------------------------------------
  74.     // Destroy this vector.
  75.     //---------------------------------------------------------------
  76.     { _destroy(); }
  77.  
  78.     const_iterator begin() const
  79.     //---------------------------------------------------------------
  80.     // An iterator positioned at the first element of this vector.
  81.     //---------------------------------------------------------------
  82.     { return (const_iterator)_data; }
  83.  
  84.     const_iterator end() const
  85.     //---------------------------------------------------------------
  86.     // An interator positioned one position past the last element of
  87.     // this vector.
  88.     //---------------------------------------------------------------
  89.     { return (const_iterator)(_data + _size); }
  90.  
  91.     iterator begin()
  92.     //---------------------------------------------------------------
  93.     // An iterator positioned at the first element of this vector.
  94.     //---------------------------------------------------------------
  95.     { return _data; }
  96.  
  97.     iterator end()
  98.     //---------------------------------------------------------------
  99.     // An interator positioned one position past the last element of
  100.     // this vector.
  101.     //---------------------------------------------------------------
  102.     { return _data + _size; }
  103.  
  104.     size_type size() const
  105.     //---------------------------------------------------------------
  106.     // Access the size of this vector.
  107.     //---------------------------------------------------------------
  108.     { return _size; }
  109.  
  110.     size_type capacity() const
  111.     //---------------------------------------------------------------
  112.     // Access the capacity of this vector.
  113.     //---------------------------------------------------------------
  114.     { return _capacity; }
  115.  
  116.     const Vector<T>& operator=(const Vector<T>& rhs)
  117.     //---------------------------------------------------------------
  118.     // Assign this vector the value of rhs.
  119.     //---------------------------------------------------------------
  120.     {
  121.         if(this != &rhs){
  122.             size_type sz = rhs.size();
  123.             if(sz <= capacity()){
  124.                 std::copy(rhs.begin(), rhs.end(), _data);
  125.             } else {
  126.                 _destroy();
  127.                 _data = _allocate(sz, T(0));
  128.                 std::copy(rhs.begin(), rhs.end(), _data);
  129.                 _capacity = sz;
  130.             }
  131.             _size = sz;
  132.         }
  133.         return *this;
  134.     }
  135.  
  136.     const Vector<T>& operator+=(const Vector<T>& rhs)
  137.     //---------------------------------------------------------------
  138.     // Assign the vector sum of this vector and rhs to this vector.
  139.     //---------------------------------------------------------------
  140.     {
  141.         if(size() != rhs.size()){
  142.             throw Exception("Vector<T>::operator+=", "Incompatible vector sizes");
  143.         }
  144.         std::transform(begin(), end(), rhs.begin(), begin(), std::plus<T>());
  145.         return *this;
  146.     }
  147.  
  148.     const Vector<T>& operator-=(const Vector<T>& rhs)
  149.     //---------------------------------------------------------------
  150.     // Assign the vector difference of this vector and rhs to this
  151.     // vector.
  152.     //---------------------------------------------------------------
  153.     {
  154.         if(size() != rhs.size()){
  155.             throw Exception("Vector<T>::operator-=", "Incompatible vector sizes");
  156.         }
  157.         std::transform(begin(), end(), rhs.begin(), begin(), std::minus<T>());
  158.         return *this;
  159.     }
  160.  
  161.     const Vector<T>& operator*=(const T& scale)
  162.     //---------------------------------------------------------------
  163.     // Assign the scalar procuct of this vector and scale to this
  164.     // vector.
  165.     //---------------------------------------------------------------
  166.     {
  167.         std::transform(begin(), end(), begin(), ScaleValue<T>(scale));
  168.         return *this;
  169.     }
  170.  
  171.     T& operator[](size_type index)
  172.     //---------------------------------------------------------------
  173.     // Access the index-th element of this vector.
  174.     //---------------------------------------------------------------
  175.     {
  176.         if(index < 0 || index >= size()){
  177.             throw Exception("Vector<T>::operator[]", "invalid index parameter");
  178.         }
  179.         return *(_data + index);
  180.     }
  181.  
  182.     void resize(size_type sz)
  183.     //---------------------------------------------------------------
  184.     // Resize this vector to sz
  185.     //---------------------------------------------------------------
  186.     {
  187.         if(sz > capacity()){
  188.             iterator tmp = _allocate(sz, T(0));
  189.             std::copy(_data, _data + size(), tmp);
  190.             _destroy();
  191.             _data = tmp;
  192.             _capacity = sz;
  193.         }
  194.         _size = sz;
  195.     }
  196.  
  197.     double length() const
  198.     //---------------------------------------------------------------
  199.     // Magnitude of this vector.
  200.     //---------------------------------------------------------------
  201.     { return sqrt(std::inner_product(begin(), end(), begin(), 0.0)); }
  202.  
  203. private:
  204.     iterator _allocate(size_type sz, const T& init = T(0))
  205.     //---------------------------------------------------------------
  206.     // Create sz elements all initialized to init.
  207.     //---------------------------------------------------------------
  208.     {
  209.         iterator ret = new T[sz];
  210.         std::fill(ret, ret + sz, init);
  211.         return ret;
  212.     }
  213.  
  214.     void _destroy()
  215.     //---------------------------------------------------------------
  216.     // Destroy all the elements in this vector.
  217.     //---------------------------------------------------------------
  218.     {
  219.         delete [] _data;
  220.         _capacity = 0;
  221.         _size = 0;
  222.         _data = NULL;
  223.     }
  224.  
  225.     size_type _length(const_iterator first, const_iterator last)
  226.     //---------------------------------------------------------------
  227.     // Return the number of elements in [first, last).
  228.     //---------------------------------------------------------------
  229.     {
  230.         size_type ret;
  231.         for(ret = 0; first != last; ++ret, ++first);
  232.         return ret;
  233.     }
  234.  
  235.     size_type _capacity; // capacity of this vector
  236.     size_type _size;     // size of this vector
  237.     iterator _data;      // vector elements
  238. };
  239.  
  240. template<class T>
  241. Vector<T> operator+(const Vector<T>& lhs, const Vector<T>& rhs)
  242. //-------------------------------------------------------------------
  243. // Vector sum of lhs and rhs.
  244. //-------------------------------------------------------------------
  245. {
  246.     if(lhs.size() != rhs.size()){
  247.         throw Exception("operator+(Vector<T>, Vector<T>)", "Incompatible vector sizes");
  248.     }
  249.     Vector<T> ret(lhs);
  250.     return ret += rhs;
  251. }
  252.  
  253. template<class T>
  254. Vector<T> operator-(const Vector<T>& lhs, const Vector<T>& rhs)
  255. //-------------------------------------------------------------------
  256. // Vector difference of lhs and rhs.
  257. //-------------------------------------------------------------------
  258. {
  259.     if(lhs.size() != rhs.size()){
  260.         throw Exception("operator-(Vector<T>, Vector<T>)", "Incompatible vector sizes");
  261.     }
  262.     Vector<T> ret(lhs);
  263.     return ret -= rhs;
  264. }
  265.  
  266. template<class T>
  267. Vector<T> operator*(const Vector<T>& lhs, const T& rhs)
  268. //-------------------------------------------------------------------
  269. // Scalar product of lhs and rhs.
  270. //-------------------------------------------------------------------
  271. {
  272.     Vector<T> ret(lhs);
  273.     return ret *= rhs;
  274. }
  275.  
  276. template<class T>
  277. Vector<T> operator*(const T& lhs, const Vector<T>& rhs)
  278. //-------------------------------------------------------------------
  279. // Scalar product of lhs and rhs.
  280. //-------------------------------------------------------------------
  281. {
  282.     return rhs * lhs;
  283. }
  284.  
  285. template<class T>
  286. double operator*(const Vector<T>& lhs, const Vector<T>& rhs)
  287. //-------------------------------------------------------------------
  288. // Dot product of lhs and rhs.
  289. //-------------------------------------------------------------------
  290. {
  291.     if(lhs.size() != rhs.size()){
  292.         throw Exception("operator*(Vector<T>, Vector<T>)", "Incompatible vector sizes");
  293.     }
  294.     return std::inner_product(lhs.begin(), lhs.end(), rhs.begin(), 0.0);
  295. }
  296.  
  297. NUM_END
  298.  
  299. #endif
  300.  
  301. //===================================================================
  302. // Revision History
  303. //
  304. // Version 1.0 - 04/10/1999 - New.
  305. //===================================================================
  306.