/*********************************************************************** * M_Vector.h * * Header file for an implementation of mathematical vectors of doubles. * Features overloading of basic arithmetic and comparison operators. * * Written by Paul Bonamy - 30 October 2009 ************************************************************************/ #ifndef M_VECTOR_H #define M_VECTOR_H #include using namespace std; /*********************************************************************** * Relatively simple mathematical vector class ***********************************************************************/ template class M_Vector { public: // constructors M_Vector(); // default constructor - vector of size 0 M_Vector(int s); // vector of given size M_Vector(const M_Vector &v); // copy constructor M_Vector(T a[], int s); // vector from array and size // destructor ~M_Vector(); // support functions int getSize(); // returns size of vector // operators overloaded as global functions template friend ostream& operator<< ( ostream & out, const M_Vector & v); // output operator // operators overloaded as member functions M_Vector& operator= ( const M_Vector & v); // assignment const M_Vector operator+ ( const M_Vector & v) const; // vector addition M_Vector operator+= ( const M_Vector & v); // vector addition const M_Vector operator- ( const M_Vector & v) const; // vector subtraction M_Vector operator-= ( const M_Vector & v); // vector subtraction const T operator* ( const M_Vector & v) const; // dot product const M_Vector operator* ( const T & d) const; // scalar multiplication M_Vector operator*= ( const T & d); // scalar multiplication const M_Vector operator/ ( const T & d) const; // scalar division M_Vector operator/= ( const T & d); // scalar division bool operator== (const M_Vector &v) const; // equality bool operator!= (const M_Vector &v) const; // inequality T & operator[]( const int & i ); // subscript private: T *array; // array in which to store vector values int size; // size of the vector }; /*********************************************************************** * M_Vector::M_Vector() * * default constructor for the M_Vector class. * Creates a vector of size 0 * * no parameters / no return ***********************************************************************/ template M_Vector::M_Vector() { array = 0; size = 0; } /*********************************************************************** * M_Vector::M_Vector(int s) * * Create an M_Vector of given size, with values set to 0 * * s -> size of M_Vector to create ***********************************************************************/ template M_Vector::M_Vector(int s) { size = s; array = new T[size]; for(int i = 0; i < size; i++) { array[i] = 0; } } /*********************************************************************** * M_Vector::M_Vector(const M_Vector &v) * * copy constructor for M_Vector class. * creates a functional duplicate of the given M_Vector * * v -> M_Vector to duplicate ***********************************************************************/ template M_Vector::M_Vector(const M_Vector &v) { size = v.size; array = new T[size]; for(int i = 0; i < size; i++) { array[i] = v.array[i]; } } /*********************************************************************** * M_Vector::M_Vector(double a[], int s) * * Create an M_Vector from an array of double and the size of same * * a -> array of doubles with which to populate M_Vector * s -> size of M_Vector to create ***********************************************************************/ template M_Vector::M_Vector(T a[], int s) { size = s; array = new T[size]; for(int i = 0; i < size; i++) { array[i] = a[i]; } } /*********************************************************************** * M_Vector::~M_Vector() * * Destroy the M_Vector, preventing memory leakage * * no parameters / no return ***********************************************************************/ template M_Vector::~M_Vector() { delete[] array; } /*********************************************************************** * int M_Vector::getSize() * * Retrieve size of an M_Vector * * return: size of M_Vector ***********************************************************************/ template int M_Vector::getSize() { return size; } /*********************************************************************** * ostream& operator<< ( ostream & out, const M_Vector & v) * * Overload of the << operator. Provides stream output capability. * Implemented as a global function, as required. * * out -> stream to which will should write * v -> M_Vector to be written out * return: stream to which we wrote ***********************************************************************/ template ostream& operator<< ( ostream & out, const M_Vector & v) { out << "("; if(v.size > 0) { // no need to print an empty vector for(int i = 0; i < v.size; i++) { cout << v.array[i] << ", "; } cout << "\b\b"; // \b is the equivalent to a backspace } out << ")"; return out; } /*********************************************************************** * M_Vector& M_Vector::operator= ( const M_Vector & v) * * Overload of the = operator. Provides the ability to copy * one M_Vector into another, existing M_Vector * * v -> M_Vector we're duplicating * return: M_Vector resulting from the assignment ***********************************************************************/ template M_Vector& M_Vector::operator= ( const M_Vector & v) { if(this == &v) // make sure we don't copy ourselves { return *this; } size = v.size; // get the new size delete[] array; // create the new array array = new T[size]; for(int i = 0; i < size; i++) { array[i] = v.array[i]; } // do the copy return *this; } /*********************************************************************** * const M_Vector M_Vector::operator+ ( const M_Vector & v) const * * Overload of the + operator. Adds the value of the received * M_Vector to the value of this vector and returns a new * vector containing the sum * * v -> one of the M_Vectors we're adding * return: result of the addition ***********************************************************************/ template const M_Vector M_Vector::operator+ ( const M_Vector & v) const { // figure out an appropriate size int newSize = (size > v.size) ? size : v.size; // copy this vector's values over M_Vector sum(newSize); for(int i = 0; i < size; i++) { sum.array[i] = array[i]; } // add in the other vector's values for(int i = 0; i < v.size; i++) { sum.array[i] += v.array[i]; } return sum; } /*********************************************************************** * M_Vector M_Vector::operator+= ( const M_Vector & v) * * Overload of the += operator. Adds the value of the received * M_Vector to the value of the this vector, changing this vector. * * v -> M_Vector to add to this one * return: Reference to this M_Vector ***********************************************************************/ template M_Vector M_Vector::operator+= ( const M_Vector & v) { if(size < v.size) {// we need to extend the current vector T *temp = new T[v.size]; for(int i = 0; i < size; i++) { temp[i] = array[i]; } delete array; array = temp; } for(int i = 0; i < v.size; i++) { array[i] += v.array[i]; } return *this; } /*********************************************************************** * const M_Vector M_Vector::operator- ( const M_Vector & v) const * * Overload of the - operator. Subtracts the value of the received * M_Vector from the value of this vector and returns a new * vector containing the difference * * v -> M_Vector we're substracting from this one * return: result of the subtraction ***********************************************************************/ template const M_Vector M_Vector::operator- ( const M_Vector & v) const { // figure out an appropriate size int newSize = (size > v.size) ? size : v.size; // copy this vector's values over M_Vector difference(newSize); for(int i = 0; i < size; i++) { difference.array[i] = array[i]; } // add in the other vector's values for(int i = 0; i < v.size; i++) { difference.array[i] -= v.array[i]; } return difference; } /*********************************************************************** * M_Vector M_Vector::operator-= ( const M_Vector & v) * * Overload of the -= operator. Subtracts the value of the received * M_Vector from the value of the this vector, changing this vector. * * v -> M_Vector to subtract from this one * return: Reference to this M_Vector ***********************************************************************/ template M_Vector M_Vector::operator-= ( const M_Vector & v) { if(size < v.size) { // we need to extend the current vector T *temp = new T[v.size]; for(int i = 0; i < size; i++) { temp[i] = array[i]; } delete array; array = temp; } for(int i = 0; i < size; i++) { array[i] -= v.array[i]; } return *this; } /*********************************************************************** * const double M_Vector::operator* ( const M_Vector & v) const * * Overload of the * operator. Take the dot product (sum of * products) of this vector and the received vector and return * the result as a double * * v -> other M_Vector to be used in dot product * return: result of the dot product calculation ***********************************************************************/ template const T M_Vector::operator* ( const M_Vector & v) const { double dp = 0; // figure out an endpoint int endPoint = (size > v.size) ? size : v.size; // compute dot product for(int i = 0; i < endPoint; i++) { dp += array[i] * v.array[i]; } return dp; } /*********************************************************************** * const M_Vector M_Vector::operator* ( const double & d) const * * Overload of the * operator. Multiply this vector by the received * double value and returns a new vector containing the product * * d -> double value by which to multiply this vector * return: result of the multiplication ***********************************************************************/ template const M_Vector M_Vector::operator* ( const T & d) const { // compute the product and return M_Vector product(*this); for(int i = 0; i < size; i++) { product.array[i] *= d; } return product; } /*********************************************************************** * M_Vector M_Vector::operator*= ( const double & d) * * Overload of the *= operator. Multiply this M_Vector by the received * double value, changing the value of the this M_Vector * * d -> double value by which to multiply this vector * return: reference to this vector ***********************************************************************/ template M_Vector M_Vector::operator*= ( const T & d) { // compute the product and return for(int i = 0; i < size; i++) { array[i] *= d; } return *this; } /*********************************************************************** * const M_Vector M_Vector::operator/ ( const double & d) const * * Overload of the / operator. Divide this vector by the received * double value and returns a new vector containing the dividend * * d -> double value by which to divide this vector * return: result of the division ***********************************************************************/ template const M_Vector M_Vector::operator/ ( const T & d) const { // compute the dividend and return M_Vector dividend(*this); for(int i = 0; i < size; i++) { dividend.array[i] /= d; } return dividend; } /*********************************************************************** * M_Vector M_Vector::operator/= ( const double & d) * * Overload of the /= operator. Divide this M_Vector by the received * double value, changing the value of the this M_Vector * * d -> double value by which to divide this vector * return: reference to this vector ***********************************************************************/ template M_Vector M_Vector::operator/= ( const T & d) { // compute the dividend and return for(int i = 0; i < size; i++) { array[i] /= d; } return *this; } /*********************************************************************** * bool M_Vector::operator== (const M_Vector &v) const * * Overload of the == operator. Determine whether two vectors contain * the same value, and return a boolean value with the result of the * comparison * * v -> M_Vector to which we're comparing this M_Vector * return: boolean indicating the result of the comparison ***********************************************************************/ template bool M_Vector::operator== (const M_Vector &v) const { if(size != v.size) // different size == different { return false; } for(int i = 0; i < size; i++) { if(array[i] != v.array[i]) // different value { return false; } // == different } return true; } /*********************************************************************** * bool M_Vector::operator!= (const M_Vector &v) const * * Overload of the != operator. Determine whether two vectors contain * different values, and return a boolean value with the result of the * comparison * * v -> M_Vector to which we're comparing this M_Vector * return: boolean indicating the result of the comparison ***********************************************************************/ template bool M_Vector::operator!= (const M_Vector &v) const { if(size != v.size) // different size == different { return true; } for(int i = 0; i < size; i++) { if(array[i] != v.array[i]) // different value { return true; } // == different } return false; } /*********************************************************************** * M_Vector & M_Vector::operator[]( const int & i ) * * Overload of the [] operator. Provides array-like access to the * M_Vector to allow for reading or writing individual values in the * M_Vector directly. * * i -> value to be accessed in the M_Vector * return: reference to the appropriate entry in the M_Vector ***********************************************************************/ template T & M_Vector::operator[]( const int & i ) { return array[i]; // note that this does no bounds checking } #endif