/* 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
*/
#include "Maths/Vector.hh"
#include
#include
#include
#include
#include "CLHEP/Matrix/Vector.h"
#include "gsl/gsl_complex_math.h"
#include "gsl/gsl_vector.h"
#include "gsl/gsl_vector_complex_double.h"
#include "Maths/Complex.hh"
#include "Utils/Exception.hh"
namespace MAUS {
// ############################
// VectorBase (public)
// ############################
// *************************
// Constructors
// *************************
template
VectorBase::VectorBase() : vector_(NULL) {}
template VectorBase::VectorBase();
template VectorBase::VectorBase();
template <>
VectorBase::VectorBase(
const VectorBase& original_instance)
: vector_(NULL) {
if (original_instance.vector_ != NULL) {
build_vector(original_instance.vector_->size);
gsl_vector_memcpy(vector_, original_instance.vector_);
}
}
template <>
VectorBase::VectorBase(
const VectorBase& original_instance)
: vector_(NULL) {
if (original_instance.vector_ != NULL) {
build_vector(original_instance.vector_->size);
gsl_vector_complex_memcpy(vector_, original_instance.vector_);
}
}
template <>
VectorBase::VectorBase(
const ::CLHEP::HepVector& hep_vector) : vector_(NULL) {
size_t size = hep_vector.num_row();
build_vector(size);
for (size_t index = 1; index <= size; ++index) {
(*this)(index) = hep_vector(index);
}
}
template <>
VectorBase::VectorBase(
const ::CLHEP::HepVector& hep_vector) : vector_(NULL) {
size_t size = hep_vector.num_row();
build_vector(size);
for (size_t index = 1; index <= size; ++index) {
(*this)(index) = MAUS::Complex::complex(hep_vector(index));
}
}
template
VectorBase::VectorBase(const size_t i) : vector_(NULL) {
build_vector(i);
}
template VectorBase::VectorBase(const size_t i);
template VectorBase::VectorBase(const size_t i);
template
VectorBase::VectorBase(
const size_t size, const StdType value) : vector_(NULL) {
VectorBase::build_vector(size);
for (size_t i = 0; i < size; ++i) {
(*this)[i] = value;
}
}
template VectorBase::VectorBase(
const size_t size, const double value);
template VectorBase::VectorBase(
const size_t size, const complex value);
template
VectorBase::VectorBase(
const StdType* data, const size_t size) : vector_(NULL) {
build_vector(size, data);
}
template VectorBase::VectorBase(
const double* data, const size_t size);
template VectorBase::VectorBase(
const complex* data, const size_t size);
template
VectorBase::VectorBase(
const std::vector >& std_vector)
: vector_(NULL) {
build_vector(std_vector.size());
typename std::vector::const_iterator element;
int index = 0;
for (element = std_vector.begin(); element < std_vector.end(); ++element) {
// TODO(plane1@iit.edu): create a MAUS::Vector iterator
(*this)[index++] = *element;
}
}
template VectorBase::VectorBase(
const std::vector >& std_vector);
template VectorBase::VectorBase(
const std::vector >& std_vector);
template
VectorBase::~VectorBase() {
delete_vector();
}
template VectorBase::~VectorBase();
template VectorBase::~VectorBase();
// *************************
// Indexing Operators
// *************************
template <>
const double& VectorBase::operator[](const size_t i)
const {
if (vector_ == NULL) {
throw(Exception(
Exception::recoverable,
"Attempted to index an empty vector.",
"MAUS::VectorBase::operator[]()"));
}
return *gsl_vector_ptr(vector_, i);
}
template <>
const complex& VectorBase::operator[](
const size_t i) const {
if (vector_ == NULL) {
throw(Exception(
Exception::recoverable,
"Attempted to index an empty vector.",
"MAUS::VectorBase::operator[]()"));
}
return *gsl_vector_complex_ptr(vector_, i);
}
template <>
double& VectorBase::operator[](const size_t i) {
if (vector_ == NULL) {
throw(Exception(
Exception::recoverable,
"Attempted to index an empty vector.",
"MAUS::VectorBase::operator[]()"));
}
return *gsl_vector_ptr(vector_, i);
}
template <>
complex& VectorBase::operator[](const size_t i) {
if (vector_ == NULL) {
throw(Exception(
Exception::recoverable,
"Attempted to index an empty vector.",
"MAUS::VectorBase::operator[]()"));
}
return *gsl_vector_complex_ptr(vector_, i);
}
template
StdType& VectorBase::operator()(const size_t i) {
return (*this)[i-1];
}
template double& VectorBase::operator()(const size_t i);
template complex& VectorBase::operator()(
const size_t i);
template
const StdType& VectorBase::operator()(const size_t i) const {
return (*this)[i-1];
}
template const double& VectorBase::operator()(
const size_t i) const;
template const complex& VectorBase::operator()(
const size_t i) const;
// *************************
// Size Functions
// *************************
template
const size_t VectorBase::size() const {
if (vector_ != NULL) {
return vector_->size;
}
return 0;
}
template const size_t VectorBase::size() const;
template const size_t VectorBase::size() const;
// *************************
// Subvector Functions
// *************************
template <>
VectorBase VectorBase::subvector(
size_t begin_index, size_t end_index) const {
if (vector_ == NULL) {
throw(Exception(
Exception::recoverable,
"Attempted to create a subvector from an empty vector.",
"MAUS::VectorBase::subvector()"));
}
VectorBase subvector;
size_t sub_size = end_index-begin_index;
if (sub_size > 0) {
subvector = VectorBase(sub_size);
for (size_t index = 0; index < sub_size; ++index) {
*gsl_vector_ptr(subvector.vector_, index)
= *gsl_vector_ptr(vector_, begin_index+index);
}
}
return subvector;
}
template <> VectorBase
VectorBase::subvector(
size_t begin_index,
size_t end_index) const {
if (vector_ == NULL) {
throw(Exception(
Exception::recoverable,
"Attempted to create a subvector from an empty vector.",
"MAUS::VectorBase::subvector()"));
}
VectorBase subvector;
size_t sub_size = end_index-begin_index;
if (sub_size > 0) {
subvector = VectorBase(sub_size);
for (size_t index = 0; index < sub_size; ++index) {
*gsl_vector_complex_ptr(subvector.vector_, index)
= *gsl_vector_complex_ptr(vector_, begin_index+index);
}
}
return subvector;
}
// *************************
// Assignment Operators
// *************************
template <>
VectorBase& VectorBase::operator=(
const VectorBase& rhs) {
if (&rhs != this) {
if (vector_ == NULL) {
// special case (like for a copy constructor call) where a non-null
// vector is assigned to a null vector
build_vector(rhs.vector_->size);
} else if ((rhs.vector_ == NULL) || (vector_->size != rhs.vector_->size)) {
throw(Exception(Exception::recoverable,
"Attempted to assign a vector of a different size.",
"VectorBase::operator=()"));
}
gsl_vector_memcpy(vector_, rhs.vector_);
}
return *this;
}
template <> VectorBase&
VectorBase::operator=(
const VectorBase& rhs) {
if (&rhs != this) {
if (vector_ == NULL) {
// special case (like for a copy constructor call) where a non-null
// vector is assigned to a null vector
build_vector(rhs.vector_->size);
} else if ((rhs.vector_ == NULL) || (vector_->size != rhs.vector_->size)) {
throw(Exception(Exception::recoverable,
"Attempted to assign a vector of a different size.",
"VectorBase::operator=()"));
}
gsl_vector_complex_memcpy(vector_, rhs.vector_);
}
return *this;
}
template<>
VectorBase& VectorBase::operator+=(
const VectorBase& rhs) {
if (rhs.vector_ != NULL) {
gsl_vector_add(vector_, rhs.vector_);
}
return *this;
}
template<> VectorBase&
VectorBase::operator+=(
const VectorBase& rhs) {
if (rhs.vector_ != NULL) {
gsl_vector_complex_add(vector_, rhs.vector_);
}
return *this;
}
template<>
VectorBase& VectorBase::operator-=(
const VectorBase& rhs) {
if (rhs.vector_ != NULL) {
gsl_vector_sub(vector_, rhs.vector_);
}
return *this;
}
template<> VectorBase&
VectorBase::operator-=(
const VectorBase& rhs) {
if (rhs.vector_ != NULL) {
gsl_vector_complex_sub(vector_, rhs.vector_);
}
return *this;
}
template<>
VectorBase& VectorBase::operator*=(
const VectorBase& rhs) {
if (rhs.vector_ != NULL) {
size_t size = this->size();
if (rhs.size() != size) {
throw(Exception(
Exception::recoverable,
"Attempted to perform the product of two vectors of different sizes.",
"MAUS::VectorBase::operator*="));
}
gsl_vector_mul(vector_, rhs.vector_);
} else {
throw(Exception(
Exception::recoverable,
"Attempted to multiply a vector by an empty vector.",
"MAUS::VectorBase::operator*="));
}
return *this;
}
template<> VectorBase&
VectorBase::operator*=(
const VectorBase& rhs) {
if (rhs.vector_ != NULL) {
size_t size = this->size();
if (rhs.size() != size) {
throw(Exception(
Exception::recoverable,
"Attempted to perform the product of two vectors of different sizes.",
"MAUS::VectorBase::operator*="));
}
gsl_vector_complex_mul(vector_, rhs.vector_);
} else {
throw(Exception(
Exception::recoverable,
"Attempted to multiply a vector by an empty vector.",
"MAUS::VectorBase::operator*="));
}
return *this;
}
template<>
VectorBase& VectorBase::operator/=(
const VectorBase& rhs) {
if (rhs.vector_ != NULL) {
size_t size = this->size();
if (rhs.size() != size) {
throw(Exception(
Exception::recoverable,
"Attempted to perform the product of two vectors of different sizes.",
"MAUS::VectorBase::operator/="));
}
gsl_vector_div(vector_, rhs.vector_);
} else {
throw(Exception(
Exception::recoverable,
"Attempted to divide a vector by an empty vector.",
"MAUS::VectorBase::operator/="));
}
return *this;
}
template<> VectorBase&
VectorBase::operator/=(
const VectorBase& rhs) {
if (rhs.vector_ != NULL) {
size_t size = this->size();
if (rhs.size() != size) {
throw(Exception(
Exception::recoverable,
"Attempted to perform the product of two vectors of different sizes.",
"MAUS::VectorBase::operator/="));
}
gsl_vector_complex_div(vector_, rhs.vector_);
} else {
throw(Exception(
Exception::recoverable,
"Attempted to divide a vector by an empty vector.",
"MAUS::VectorBase::operator/="));
}
return *this;
}
template<>
VectorBase& VectorBase::operator+=(
const double& rhs) {
if (vector_ != NULL) {
gsl_vector_add_constant(vector_, rhs);
}
return *this;
}
template<>
VectorBase&
VectorBase::operator+=(
const complex& rhs) {
if (vector_ != NULL) {
gsl_vector_complex_add_constant(vector_, rhs);
}
return *this;
}
template<>
VectorBase& VectorBase::operator-=(
const double& rhs) {
if (vector_ != NULL) {
gsl_vector_add_constant(vector_, -rhs);
}
return *this;
}
template<>
VectorBase&
VectorBase::operator-=(
const complex& rhs) {
if (vector_ != NULL) {
gsl_vector_complex_add_constant(vector_, -rhs);
}
return *this;
}
template<>
VectorBase& VectorBase::operator*=(
const double& rhs) {
if (vector_ != NULL) {
gsl_vector_scale(vector_, rhs);
}
return *this;
}
template<>
VectorBase&
VectorBase::operator*=(
const complex& rhs) {
if (vector_ != NULL) {
gsl_vector_complex_scale(vector_, rhs);
}
return *this;
}
template<> VectorBase&
VectorBase::operator/=(const double& rhs) {
if (vector_ != NULL) {
gsl_vector_scale(vector_, 1./rhs);
}
return *this;
}
template<> VectorBase&
VectorBase::operator/=(const complex& rhs) {
if (vector_ != NULL) {
gsl_vector_complex_scale(vector_, 1./rhs);
}
return *this;
}
// *************************
// Algebraic Operators
// *************************
template
const VectorBase VectorBase::operator+(
const VectorBase& rhs) const {
return VectorBase(*this) += rhs;
}
template const VectorBase
VectorBase::operator+(
const VectorBase& rhs) const;
template
const VectorBase
VectorBase::operator+(
const VectorBase& rhs) const;
template
const VectorBase VectorBase::operator-(
const VectorBase& rhs) const {
return VectorBase(*this) -= rhs;
}
template const VectorBase
VectorBase::operator-(
const VectorBase& rhs) const;
template
const VectorBase
VectorBase::operator-(
const VectorBase& rhs) const;
template
const VectorBase VectorBase::operator*(
const VectorBase& rhs) const {
return VectorBase(*this) *= rhs;
}
template const VectorBase
VectorBase::operator*(
const VectorBase& rhs) const;
template const VectorBase
VectorBase::operator*(
const VectorBase& rhs) const;
template
const VectorBase VectorBase::operator/(
const VectorBase& rhs) const {
return VectorBase(*this) /= rhs;
}
template const VectorBase
VectorBase::operator/(
const VectorBase& rhs) const;
template const VectorBase
VectorBase::operator/(
const VectorBase& rhs) const;
template
const VectorBase VectorBase::operator+(
const StdType& rhs) const {
return VectorBase(*this) += rhs;
}
template
const VectorBase VectorBase::operator+(
const double& rhs) const;
template
const VectorBase
VectorBase::operator+(
const complex& rhs) const;
template
const VectorBase VectorBase::operator-(
const StdType& rhs) const {
return VectorBase(*this) -= rhs;
}
template
const VectorBase VectorBase::operator-(
const double& rhs) const;
template
const VectorBase
VectorBase::operator-(
const complex& rhs) const;
template
const VectorBase VectorBase::operator*(
const StdType& rhs) const {
return VectorBase(*this) *= rhs;
}
template
const VectorBase VectorBase::operator*(
const double& rhs) const;
template
const VectorBase
VectorBase::operator*(
const complex& rhs) const;
template
const VectorBase VectorBase::operator/(
const StdType& rhs) const {
return VectorBase(*this) /= rhs;
}
template const VectorBase
VectorBase::operator/(const double& rhs) const;
template const VectorBase
VectorBase::operator/(const complex& rhs) const;
// *************************
// Comparison Operators
// *************************
template <>
const bool VectorBase::operator==(
const VectorBase& rhs) const {
size_t this_size = size();
if (this_size != rhs.size()) {
return false;
}
if (vector_ != NULL) {
for (size_t index = 0; index < this_size; ++index) {
if ( *gsl_vector_ptr(vector_, index)
!= *gsl_vector_ptr(rhs.vector_, index)) {
return false;
}
}
} else if (rhs.vector_ != NULL) {
return false;
}
return true;
}
template <>
const bool VectorBase::operator==(
const VectorBase& rhs) const {
size_t this_size = size();
if (this_size != rhs.size()) {
return false;
}
if (vector_ != NULL) {
for (size_t index = 0; index < this_size; ++index) {
if ( *gsl_vector_complex_ptr(vector_, index)
!= *gsl_vector_complex_ptr(rhs.vector_, index)) {
return false;
}
}
} else if (rhs.vector_ != NULL) {
return false;
}
return true;
}
template
const bool VectorBase::operator!=(
const VectorBase& rhs) const {
return !((*this) == rhs);
}
// ############################
// VectorBase (protected)
// ############################
template <>
void VectorBase::delete_vector() {
if (vector_ != NULL) {
gsl_vector_free(vector_);
}
vector_ = NULL;
}
template <>
void VectorBase::delete_vector() {
if (vector_ != NULL) {
gsl_vector_complex_free(vector_);
}
vector_ = NULL;
}
template <>
void VectorBase::build_vector(const size_t size,
const bool initialize) {
delete_vector();
if (initialize) {
vector_ = gsl_vector_calloc(size);
} else {
vector_ = gsl_vector_alloc(size);
}
}
template <>
void VectorBase::build_vector(
const size_t size, const bool initialize) {
delete_vector();
if (initialize) {
vector_ = gsl_vector_complex_calloc(size);
} else {
vector_ = gsl_vector_complex_alloc(size);
}
}
template
void VectorBase::build_vector(
const size_t size, const StdType* data) {
build_vector(size, false);
for (size_t i = 0; i < this->size(); ++i) {
(*this)[i] = data[i];
}
}
template void VectorBase::build_vector(
const size_t size, const double* data);
template void VectorBase::build_vector(
const size_t size, const complex* data);
template
GslType * VectorBase::vector() {
return vector_;
}
template gsl_vector * VectorBase::vector();
template gsl_vector_complex * VectorBase::vector();
// ############################
// Vector (public)
// ############################
const Vector Vector::operator+(const Vector& rhs)
const {
return VectorBase::operator+(rhs);
}
const Vector Vector::operator-(const Vector& rhs)
const {
return VectorBase::operator-(rhs);
}
const Vector Vector::operator*(const Vector& rhs)
const {
return VectorBase::operator*(rhs);
}
const Vector Vector::operator/(const Vector& rhs)
const {
return VectorBase::operator/(rhs);
}
const Vector Vector::operator+(const double& rhs) const {
return VectorBase::operator+(rhs);
}
const Vector Vector::operator-(const double& rhs) const {
return VectorBase::operator-(rhs);
}
const Vector Vector::operator*(const double& rhs) const {
return VectorBase::operator*(rhs);
}
const Vector Vector::operator/(const double& rhs) const {
return VectorBase::operator/(rhs);
}
const Vector Vector::operator+(const Vector& rhs)
const {
return VectorBase::operator+(rhs);
}
const Vector Vector::operator-(const Vector