home *** CD-ROM | disk | FTP | other *** search
- //===================================================================
- // vector.hpp
- //
- // Version 1.0
- //
- // Written by:
- // Brent Worden
- // WordenWare
- // email: Brent@Worden.org
- //
- // Copyright (c) 1999 WordenWare
- //
- // Created: April 10, 1999
- // Revised:
- //===================================================================
-
- #ifndef _VECTOR_HPP_
- #define _VECTOR_HPP_
-
- #include <algorithm>
- #include <cstdlib>
- #include <functional>
- #include <numeric>
-
- #include "funcobj.hpp"
- #include "numerror.h"
-
- NUM_BEGIN
-
- template<class T>
- class Vector
- //-------------------------------------------------------------------
- // mathematical vector object
- //-------------------------------------------------------------------
- {
- public:
- typedef T* iterator;
- typedef const T* const_iterator;
- typedef size_t size_type;
-
- Vector()
- //---------------------------------------------------------------
- // Create an empty vector.
- //---------------------------------------------------------------
- : _capacity(0), _size(0), _data(NULL) {}
-
- Vector(size_type sz)
- //---------------------------------------------------------------
- // Create a vector with size sz.
- //---------------------------------------------------------------
- : _capacity(sz), _size(sz) { _data = _allocate(sz, T(0)); }
-
- Vector(const Vector<T>& other)
- //---------------------------------------------------------------
- // Create a vector by copying other.
- //---------------------------------------------------------------
- : _capacity(other.size()), _size(_capacity) {
- _data = _allocate(capacity(), T(0));
- std::copy(other.begin(), other.end(), _data);
- }
-
- Vector(const_iterator first, const_iterator last)
- //---------------------------------------------------------------
- // Create a vector with initial values [first, last).
- //---------------------------------------------------------------
- : _capacity(_length(first, last)), _size(_capacity)
- {
- _data = _allocate(capacity(), T(0));
- std::copy(first, last, _data);
- }
-
- ~Vector()
- //---------------------------------------------------------------
- // Destroy this vector.
- //---------------------------------------------------------------
- { _destroy(); }
-
- const_iterator begin() const
- //---------------------------------------------------------------
- // An iterator positioned at the first element of this vector.
- //---------------------------------------------------------------
- { return (const_iterator)_data; }
-
- const_iterator end() const
- //---------------------------------------------------------------
- // An interator positioned one position past the last element of
- // this vector.
- //---------------------------------------------------------------
- { return (const_iterator)(_data + _size); }
-
- iterator begin()
- //---------------------------------------------------------------
- // An iterator positioned at the first element of this vector.
- //---------------------------------------------------------------
- { return _data; }
-
- iterator end()
- //---------------------------------------------------------------
- // An interator positioned one position past the last element of
- // this vector.
- //---------------------------------------------------------------
- { return _data + _size; }
-
- size_type size() const
- //---------------------------------------------------------------
- // Access the size of this vector.
- //---------------------------------------------------------------
- { return _size; }
-
- size_type capacity() const
- //---------------------------------------------------------------
- // Access the capacity of this vector.
- //---------------------------------------------------------------
- { return _capacity; }
-
- const Vector<T>& operator=(const Vector<T>& rhs)
- //---------------------------------------------------------------
- // Assign this vector the value of rhs.
- //---------------------------------------------------------------
- {
- if(this != &rhs){
- size_type sz = rhs.size();
- if(sz <= capacity()){
- std::copy(rhs.begin(), rhs.end(), _data);
- } else {
- _destroy();
- _data = _allocate(sz, T(0));
- std::copy(rhs.begin(), rhs.end(), _data);
- _capacity = sz;
- }
- _size = sz;
- }
- return *this;
- }
-
- const Vector<T>& operator+=(const Vector<T>& rhs)
- //---------------------------------------------------------------
- // Assign the vector sum of this vector and rhs to this vector.
- //---------------------------------------------------------------
- {
- if(size() != rhs.size()){
- throw Exception("Vector<T>::operator+=", "Incompatible vector sizes");
- }
- std::transform(begin(), end(), rhs.begin(), begin(), std::plus<T>());
- return *this;
- }
-
- const Vector<T>& operator-=(const Vector<T>& rhs)
- //---------------------------------------------------------------
- // Assign the vector difference of this vector and rhs to this
- // vector.
- //---------------------------------------------------------------
- {
- if(size() != rhs.size()){
- throw Exception("Vector<T>::operator-=", "Incompatible vector sizes");
- }
- std::transform(begin(), end(), rhs.begin(), begin(), std::minus<T>());
- return *this;
- }
-
- const Vector<T>& operator*=(const T& scale)
- //---------------------------------------------------------------
- // Assign the scalar procuct of this vector and scale to this
- // vector.
- //---------------------------------------------------------------
- {
- std::transform(begin(), end(), begin(), ScaleValue<T>(scale));
- return *this;
- }
-
- T& operator[](size_type index)
- //---------------------------------------------------------------
- // Access the index-th element of this vector.
- //---------------------------------------------------------------
- {
- if(index < 0 || index >= size()){
- throw Exception("Vector<T>::operator[]", "invalid index parameter");
- }
- return *(_data + index);
- }
-
- void resize(size_type sz)
- //---------------------------------------------------------------
- // Resize this vector to sz
- //---------------------------------------------------------------
- {
- if(sz > capacity()){
- iterator tmp = _allocate(sz, T(0));
- std::copy(_data, _data + size(), tmp);
- _destroy();
- _data = tmp;
- _capacity = sz;
- }
- _size = sz;
- }
-
- double length() const
- //---------------------------------------------------------------
- // Magnitude of this vector.
- //---------------------------------------------------------------
- { return sqrt(std::inner_product(begin(), end(), begin(), 0.0)); }
-
- private:
- iterator _allocate(size_type sz, const T& init = T(0))
- //---------------------------------------------------------------
- // Create sz elements all initialized to init.
- //---------------------------------------------------------------
- {
- iterator ret = new T[sz];
- std::fill(ret, ret + sz, init);
- return ret;
- }
-
- void _destroy()
- //---------------------------------------------------------------
- // Destroy all the elements in this vector.
- //---------------------------------------------------------------
- {
- delete [] _data;
- _capacity = 0;
- _size = 0;
- _data = NULL;
- }
-
- size_type _length(const_iterator first, const_iterator last)
- //---------------------------------------------------------------
- // Return the number of elements in [first, last).
- //---------------------------------------------------------------
- {
- size_type ret;
- for(ret = 0; first != last; ++ret, ++first);
- return ret;
- }
-
- size_type _capacity; // capacity of this vector
- size_type _size; // size of this vector
- iterator _data; // vector elements
- };
-
- template<class T>
- Vector<T> operator+(const Vector<T>& lhs, const Vector<T>& rhs)
- //-------------------------------------------------------------------
- // Vector sum of lhs and rhs.
- //-------------------------------------------------------------------
- {
- if(lhs.size() != rhs.size()){
- throw Exception("operator+(Vector<T>, Vector<T>)", "Incompatible vector sizes");
- }
- Vector<T> ret(lhs);
- return ret += rhs;
- }
-
- template<class T>
- Vector<T> operator-(const Vector<T>& lhs, const Vector<T>& rhs)
- //-------------------------------------------------------------------
- // Vector difference of lhs and rhs.
- //-------------------------------------------------------------------
- {
- if(lhs.size() != rhs.size()){
- throw Exception("operator-(Vector<T>, Vector<T>)", "Incompatible vector sizes");
- }
- Vector<T> ret(lhs);
- return ret -= rhs;
- }
-
- template<class T>
- Vector<T> operator*(const Vector<T>& lhs, const T& rhs)
- //-------------------------------------------------------------------
- // Scalar product of lhs and rhs.
- //-------------------------------------------------------------------
- {
- Vector<T> ret(lhs);
- return ret *= rhs;
- }
-
- template<class T>
- Vector<T> operator*(const T& lhs, const Vector<T>& rhs)
- //-------------------------------------------------------------------
- // Scalar product of lhs and rhs.
- //-------------------------------------------------------------------
- {
- return rhs * lhs;
- }
-
- template<class T>
- double operator*(const Vector<T>& lhs, const Vector<T>& rhs)
- //-------------------------------------------------------------------
- // Dot product of lhs and rhs.
- //-------------------------------------------------------------------
- {
- if(lhs.size() != rhs.size()){
- throw Exception("operator*(Vector<T>, Vector<T>)", "Incompatible vector sizes");
- }
- return std::inner_product(lhs.begin(), lhs.end(), rhs.begin(), 0.0);
- }
-
- NUM_END
-
- #endif
-
- //===================================================================
- // Revision History
- //
- // Version 1.0 - 04/10/1999 - New.
- //===================================================================
-