/* This file is part of MAUS: http:// micewww.pp.rl.ac.uk:8080/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . */ /* Author: Peter Lane * * Based off of MVector by Chris Rogers which is a C++ wrapper for the GSL * vector C library (double and gsl_complex element types only). * * The main differences between MVector and Vector are as follows: * a) Vector avoids using void pointers by using a base class which is templated * by both element type and GSL vector type. The GSL types are then hidden by * templating the derived type only by element type. * c) In general, if a function can be implemented using only the public * interface it is provided as a free function instead of a member * function. Exceptions are functions which are associated with vector * space properties such as subsets and algebraic operators. * d) Use of the MAUS namespace obviates the use of the initial 'M' in the class * name (which presumably stood for MAUS). * * From MVector.hh: * * Maths operators and a few others are defined, but maths operators * don't allow operations between types - i.e. you can't multiply * a complex matrix by a double matrix. Instead use interface methods * like real() and complex() to convert between types first. */ #ifndef COMMON_CPP_MATHS_VECTOR_HH #define COMMON_CPP_MATHS_VECTOR_HH #include #include #include #include "gsl/gsl_complex_math.h" #include "gsl/gsl_vector.h" #include "gsl/gsl_vector_complex_double.h" #include "Maths/Complex.hh" namespace CLHEP { class HepVector; } namespace MAUS { // ************************* // Forward Declarations // ************************* template class MatrixBase; template class Matrix; template class VectorBase; template class Vector; template Vector operator*( const Matrix& lhs, const Vector& rhs); /** @class VectorBase A templated wrapper for GSL's C vector types and functions. * Currently only gsl_vector and gsl_vector_complex are * implemented. */ template class VectorBase { public: // ************************* // Constructors // ************************* VectorBase(); VectorBase(const VectorBase& original_instance); /** @brief Copy constructor for CLHEP::HepMatrix */ explicit VectorBase(const ::CLHEP::HepVector& hep_vector); explicit VectorBase(const size_t i); VectorBase(const size_t i, const StdType value); /** @brief Create an instance from an array of data. The size is the number * of elements in the array. */ VectorBase(const StdType* data, const size_t size); VectorBase(const std::vector >& std_vector); ~VectorBase(); // ************************* // Indexing Operators // ************************* // Indexing starting with 1 StdType& operator()(const size_t i); const StdType& operator()(const size_t i) const; // Indexing starting with 0 StdType& operator[](const size_t i); const StdType& operator[](const size_t i) const; // ************************* // Size Functions // ************************* // return number of elements const size_t size() const; // ************************* // Subvector Functions // ************************* /** @brief Create a vector that contains a subset of the elements. The subset * begins with the element at index begin_index and * extends to the element at index end_index - 1. Thus * the size of the new vector is simply * end_index - begin_index. * @params begin_index the index of the first element in the subset * @params end_index the index of the last element in the subset plus 1 */ VectorBase subvector(size_t begin_index, size_t end_index) const; // ************************* // Assignment Operators // ************************* VectorBase& operator =( const VectorBase& rhs); VectorBase& operator+=( const VectorBase& rhs); VectorBase& operator-=( const VectorBase& rhs); VectorBase& operator*=( const VectorBase& rhs); VectorBase& operator/=( const VectorBase& rhs); VectorBase& operator+=(const StdType& rhs); VectorBase& operator-=(const StdType& rhs); VectorBase& operator*=(const StdType& rhs); VectorBase& operator/=(const StdType& rhs); // ************************* // Algebraic Operators // ************************* const VectorBase operator+( const VectorBase& rhs) const; const VectorBase operator-( const VectorBase& rhs) const; const VectorBase operator*( const VectorBase& rhs) const; const VectorBase operator/( const VectorBase& rhs) const; const VectorBase operator+(const StdType& rhs) const; const VectorBase operator-(const StdType& rhs) const; const VectorBase operator*(const StdType& rhs) const; const VectorBase operator/(const StdType& rhs) const; // ************************* // Comparison Operators // ************************* const bool operator==(const VectorBase& rhs) const; const bool operator!=(const VectorBase& rhs) const; // ************************* // Befriending // ************************* // These operations could be done using solely the public interface, but // we want to use the optimised GSL matrix/vector, low-level functions. friend VectorBase real( const VectorBase& complex_vector); friend VectorBase imag( const VectorBase& complex_vector); friend typename MAUS::Vector MAUS::operator*<>( const MAUS::Matrix& lhs, const MAUS::Vector& rhs); protected: /** @brief delete the GSL vector member */ void delete_vector(); /** @brief copy data from an array and put it into the GSL vector member */ void build_vector(const size_t size, const StdType* data); /** @brief create the GSL vector member of the given size */ void build_vector(const size_t size, const bool initialize = true); GslType * vector(); GslType * vector_; }; // ***************************** // Specialization Declarations // ***************************** // These are put here instead of Vector.cc to maintain the order of // function definitions. template <> VectorBase::VectorBase( const VectorBase& original_instance); template <> VectorBase::VectorBase( const VectorBase& original_instance); template <> VectorBase::VectorBase( const ::CLHEP::HepVector& hep_vector); template <> VectorBase::VectorBase( const ::CLHEP::HepVector& hep_matrix); template <> VectorBase& VectorBase::operator=( const VectorBase& rhs); template <> VectorBase& VectorBase::operator=( const VectorBase& rhs); template <> void VectorBase::delete_vector(); template <> void VectorBase::delete_vector(); template <> void VectorBase::build_vector( const size_t size, const bool initialize); template <> void VectorBase::build_vector( const size_t size, const bool initialize); /** @class Vector Defines the association between GSL and standard C++ types. */ template class Vector {}; template<> class Vector : public VectorBase { public: Vector(const Vector& original_instance) : VectorBase(original_instance) {} // *** VectorBase functions *** Vector() : VectorBase() {} explicit Vector(const ::CLHEP::HepVector& hep_vector) : VectorBase(hep_vector) {} Vector(size_t i, double value) : VectorBase(i, value) {} explicit Vector(size_t i) : VectorBase(i) {} Vector(const double* data, const size_t size) : VectorBase(data, size) {} Vector(const std::vector >& std_vector) : VectorBase(std_vector) {} const Vector operator+(const Vector& rhs) const; const Vector operator-(const Vector& rhs) const; const Vector operator*(const Vector& rhs) const; const Vector operator/(const Vector& rhs) const; const Vector operator+(const double& rhs) const; const Vector operator-(const double& rhs) const; const Vector operator*(const double& rhs) const; const Vector operator/(const double& rhs) const; // *** Vector functions *** Vector(const VectorBase& base_vector) : VectorBase(base_vector) {} friend Matrix QR_least_squares( const Matrix& design_matrix, const Matrix& value_matrix); }; template<> class Vector : public VectorBase { public: Vector(const Vector& original_instance) : VectorBase(original_instance) {} // *** VectorBase functions *** Vector() : VectorBase() {} explicit Vector(const ::CLHEP::HepVector& hep_vector) : VectorBase(hep_vector) {} Vector(size_t i, complex value) : VectorBase(i, value) {} explicit Vector(size_t i) : VectorBase(i) {} Vector(const complex* data, const size_t size) : VectorBase(data, size) { } Vector(const std::vector >& std_vector) : VectorBase(std_vector) {} const Vector operator+(const Vector& rhs) const; const Vector operator-(const Vector& rhs) const; const Vector operator*(const Vector& rhs) const; const Vector operator/(const Vector& rhs) const; const Vector operator+(const complex& rhs) const; const Vector operator-(const complex& rhs) const; const Vector operator*(const complex& rhs) const; const Vector operator/(const complex& rhs) const; // *** Vector functions *** Vector(const VectorBase& base_vector) : VectorBase(base_vector) {} }; // ************************* // Conversion Functions // ************************* // return vector of doubles filled with either real or imaginary part of vector VectorBase real( const VectorBase& complex_vector); VectorBase imag( const VectorBase& complex_vector); // ************************* // Unitary Operators // ************************* template Vector operator-( const Vector& vector); // ************************* // Scalar Operators // ************************* template Vector operator*( const StdType& value, const Vector& vector); // ************************* // Stream Operators // ************************* template std::ostream& operator<<(std::ostream& out, const VectorBase& vector); template std::istream& operator>>(std::istream& in, VectorBase& vector); } // namespace MAUS #endif