8 #ifndef IMPALGEBRA_VECTOR_BASE_D_H 
    9 #define IMPALGEBRA_VECTOR_BASE_D_H 
   11 #include <IMP/algebra/algebra_config.h> 
   18 #include <boost/random/variate_generator.hpp> 
   19 #include <boost/random/normal_distribution.hpp> 
   20 #include <boost/range.hpp> 
   21 #include <cereal/access.hpp> 
   22 #include "internal/vector.h" 
   26 #include <boost/random/normal_distribution.hpp> 
   28 #if IMP_HAS_CHECKS >= IMP_INTERNAL 
   29 #define IMP_ALGEBRA_VECTOR_CHECK check_vector() 
   30 #define IMP_ALGEBRA_VECTOR_CHECK_OTHER(o) o.check_vector() 
   32 #define IMP_ALGEBRA_VECTOR_CHECK 
   33 #define IMP_ALGEBRA_VECTOR_CHECK_OTHER(o) 
   39 #if IMP_HAS_CHECKS >= IMP_USAGE 
   40 #define IMP_ALGEBRA_VECTOR_CHECK_INDEX(i) check_index(i) 
   41 #define IMP_ALGEBRA_VECTOR_CHECK_COMPATIBLE(o) \ 
   42   if (D == -1) { check_compatible_vector(o); } 
   44 #define IMP_ALGEBRA_VECTOR_CHECK_INDEX(i) 
   45 #define IMP_ALGEBRA_VECTOR_CHECK_COMPATIBLE(o) 
   48 IMPALGEBRA_BEGIN_NAMESPACE
 
   59   friend class cereal::access;
 
   61   template<
class Archive>
 
   62   void serialize(Archive &ar) {
 
   66   void check_vector()
 const {
 
   68                        "Attempt to use uninitialized vector.");
 
   74                     "Dimensions don't match: " << get_dimension() << 
" vs " 
   75                                                << o.get_dimension());
 
   77   void check_index(
unsigned int i)
 const {
 
   78 #if IMP_HAS_CHECKS < IMP_INTERNAL 
   82                        "Invalid component of vector requested: " 
   83                            << i << 
" of " << get_dimension());
 
   88   template <
class Range>
 
   90     if (D != -1 && static_cast<int>(boost::distance(r)) != D) {
 
   91       IMP_THROW(
"Expected " << D << 
" but got " << boost::distance(r),
 
  100     data_.set_coordinates(boost::begin(r), boost::end(r));
 
  106     if (D != -1 && static_cast<int>(boost::distance(r)) != D) {
 
  107       IMP_THROW(
"Expected " << D << 
" but got " << boost::distance(r),
 
  115     data_.set_coordinates(boost::begin(r), boost::end(r));
 
  120     IMP_ALGEBRA_VECTOR_CHECK_INDEX(i);
 
  121     IMP_ALGEBRA_VECTOR_CHECK;
 
  122     return data_.get_data()[i];
 
  127     IMP_ALGEBRA_VECTOR_CHECK_INDEX(i);
 
  128     return data_.get_data()[i];
 
  135   double get_scalar_product(
const VectorBaseD &o)
 const {
 
  136     IMP_ALGEBRA_VECTOR_CHECK;
 
  137     IMP_ALGEBRA_VECTOR_CHECK_OTHER(o);
 
  138     IMP_ALGEBRA_VECTOR_CHECK_COMPATIBLE(o);
 
  140     for (
unsigned int i = 0; i < get_dimension(); ++i) {
 
  141       ret += operator[](i) * o.operator[](i);
 
  146   double get_squared_magnitude()
 const {
 
  149     IMP_ALGEBRA_VECTOR_CHECK;
 
  151     const double *data = get_data();
 
  152     for (
unsigned int i = 0; i < get_dimension(); ++i) {
 
  153       ret += data[i] * data[i];
 
  158   double get_magnitude()
 const { 
return std::sqrt(get_squared_magnitude()); }
 
  165     IMP_ALGEBRA_VECTOR_CHECK_OTHER(o);
 
  166     IMP_ALGEBRA_VECTOR_CHECK_COMPATIBLE(o);
 
  167     const double *data = get_data(), *odata = o.
get_data();
 
  169     for (
unsigned int i = 0; i < get_dimension(); ++i) {
 
  170       ret += (odata[i] - data[i]) * (odata[i] - data[i]);
 
  172     return std::sqrt(ret);
 
  177     return get_scalar_product(o);
 
  180   VectorBaseD &operator+=(
const VectorBaseD &o) {
 
  181     IMP_ALGEBRA_VECTOR_CHECK;
 
  182     IMP_ALGEBRA_VECTOR_CHECK_OTHER(o);
 
  183     IMP_ALGEBRA_VECTOR_CHECK_COMPATIBLE(o);
 
  184     for (
unsigned int i = 0; i < get_dimension(); ++i) {
 
  185       operator[](i) += o[i];
 
  190   VectorBaseD &operator-=(
const VectorBaseD &o) {
 
  191     IMP_ALGEBRA_VECTOR_CHECK;
 
  192     IMP_ALGEBRA_VECTOR_CHECK_OTHER(o);
 
  193     IMP_ALGEBRA_VECTOR_CHECK_COMPATIBLE(o);
 
  194     for (
unsigned int i = 0; i < get_dimension(); ++i) {
 
  195       operator[](i) -= o[i];
 
  200   VectorBaseD &operator/=(
double f) {
 
  201     IMP_ALGEBRA_VECTOR_CHECK;
 
  202     for (
unsigned int i = 0; i < get_dimension(); ++i) {
 
  208   VectorBaseD &operator*=(
double f) {
 
  209     IMP_ALGEBRA_VECTOR_CHECK;
 
  210     for (
unsigned int i = 0; i < get_dimension(); ++i) {
 
  216   void show(std::ostream &out, std::string delim, 
bool parens = 
true)
 const {
 
  217     IMP_ALGEBRA_VECTOR_CHECK;
 
  218     if (parens) out << 
"(";
 
  219     for (
unsigned int i = 0; i < get_dimension(); ++i) {
 
  220       out << operator[](i);
 
  221       if (i != get_dimension() - 1) {
 
  225     if (parens) out << 
")";
 
  231   typedef double *iterator;
 
  232   typedef const double *const_iterator;
 
  233   iterator begin() { 
return data_.get_data(); }
 
  234   iterator end() { 
return data_.get_data() + get_dimension(); }
 
  235   const_iterator begin()
 const { 
return data_.get_data(); }
 
  236   const_iterator end()
 const { 
return data_.get_data() + get_dimension(); }
 
  238   typedef double value_type;
 
  239   typedef std::random_access_iterator_tag iterator_category;
 
  240   typedef std::ptrdiff_t difference_type;
 
  241   typedef double *pointer;
 
  242   typedef double &reference;
 
  243   typedef const double &const_reference;
 
  245   static const int DIMENSION = D;
 
  251   Floats get_coordinates()
 const {
 
  252     return Floats(begin(), end());
 
  257   const double *
get_data()
 const { 
return data_.get_data(); }
 
  259   unsigned int get_dimension()
 const { 
return data_.get_dimension(); }
 
  262   internal::VectorData<double, D, false> data_;
 
  273   static const double tiny_double =
 
  274     256.0 * std::numeric_limits<double>::epsilon();
 
  275   double mag = vt.get_magnitude();
 
  276   if (mag > tiny_double) {
 
  277     VT ret_value= vt/mag;
 
  278     IMP_USAGE_CHECK(std::abs(ret_value.get_magnitude() - 1.0) < 256.0 * tiny_double,
 
  279                     "returned vector is not unit vector");
 
  285     static boost::variate_generator<RandomNumberGenerator,
 
  286       boost::normal_distribution<> >
 
  288                 ::boost::normal_distribution<>(0, 1.0));
 
  289     for (
unsigned int i = 0; i < vt.get_dimension(); ++i) {
 
  304   const double tiny_double = 1e-12;
 
  305   double mag = vt.get_magnitude();
 
  306   if (mag > tiny_double) {
 
  316 IMPALGEBRA_END_NAMESPACE
 
Base class for geometric types. 
 
#define IMP_USAGE_CHECK_VARIABLE(variable)
 
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed. 
 
#define IMP_IF_CHECK(level)
Execute the code block if a certain level checks are on. 
 
VectorBaseD()
Default constructor. 
 
IMP::Vector< Float > Floats
Standard way to pass a bunch of Float values. 
 
VectorBaseD(const Range &r)
 
VT get_unit_vector(VT vt)
Returns a unit vector pointing at the same direction as this vector. 
 
Exception definitions and assertions. 
 
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown. 
 
double get_magnitude_and_normalize_in_place(VT &vt)
Returns the magnitude of vt and turns it to a unit vector in place. 
 
Base class for geometric types. 
 
#define IMP_UNUSED(variable)
 
double get_distance(const VectorBaseD< D > &o) const 
Return the distance between this and another vector. 
 
Various general useful functions for IMP. 
 
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)
Print the hierarchy using a given decorator to display each node. 
 
#define IMP_THROW(message, exception_name)
Throw an exception with a message. 
 
Helper macros for throwing and handling exceptions. 
 
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method. 
 
VectorD< D > operator*(double s, VectorD< D > o)
 
Random number generators used by IMP. 
 
const double * get_data() const 
Return a pointer to the data stored. 
 
A Cartesian vector in D-dimensions. 
 
An exception for an invalid value being passed to IMP. 
 
double operator[](unsigned int i) const 
Return the ith Cartesian coordinate. 
 
RandomNumberGenerator random_number_generator
A shared non-GPU random number generator. 
 
double & operator[](unsigned int i)
Return the ith Cartesian coordinate.