/* 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