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.