8 #ifndef IMPALGEBRA_VECTOR_D_H
9 #define IMPALGEBRA_VECTOR_D_H
11 #include <IMP/algebra/algebra_config.h>
19 #include "internal/vector.h"
23 #include <boost/random/normal_distribution.hpp>
24 #include <boost/static_assert.hpp>
26 #if IMP_HAS_CHECKS >= IMP_USAGE
27 #define IMP_VECTOR_CHECK check_vector()
28 #define IMP_VECTOR_CHECK_INDEX(i) check_index(i)
29 #define IMP_VECTOR_CHECK_COMPATIBLE(o) \
30 check_compatible_vector(o); \
33 #define IMP_VECTOR_CHECK
34 #define IMP_VECTOR_CHECK_INDEX(i)
35 #define IMP_VECTOR_CHECK_COMPATIBLE(o)
38 IMPALGEBRA_BEGIN_NAMESPACE
49 void check_vector()
const {
51 "Attempt to use uninitialized vector.");
54 void check_compatible_vector(
const VectorD<OD> &o)
const {
57 "Dimensions don't match: " << get_dimension() <<
" vs "
58 << o.get_dimension());
60 void check_index(
unsigned int i)
const {
61 #if IMP_HAS_CHECKS < IMP_INTERNAL
65 "Invalid component of vector requested: "
66 << i <<
" of " << get_dimension());
70 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
73 if (D != -1 && static_cast<int>(f.size()) != D) {
74 IMP_THROW(
"Expected " << D <<
" but got " << f.size(),
77 data_.set_coordinates(f.begin(), f.end());
81 BOOST_STATIC_ASSERT(D == -1 || OD == -1 || D == OD);
83 D == -1 || o.get_dimension() ==
static_cast<unsigned int>(D),
84 "Dimensions don't match in conversion");
85 data_.set_coordinates(o.coordinates_begin(), o.coordinates_end());
89 BOOST_STATIC_ASSERT(D == -1 || OD == -1 || D == OD);
91 "Dimensions don't match in conversion");
92 data_.set_coordinates(o.coordinates_begin(), o.coordinates_end());
99 IMP_DEPRECATED_ATTRIBUTE
102 if (D != -1 && static_cast<int>(f.size()) != D) {
103 IMP_THROW(
"Expected " << D <<
" but got " << f.size(),
106 data_.set_coordinates(f.begin(), f.end());
113 data_.set_coordinates(b, e);
121 #if defined(IMP_SWIG_WRAPPER) || defined(_MSC_VER)
122 IMP_USAGE_CHECK(D == 1 || D == -1,
"Need " << D <<
" to construct a " << D
125 BOOST_STATIC_ASSERT(D == 1);
127 data_.set_coordinates(&x, &x + 1);
132 #if defined(IMP_SWIG_WRAPPER) || defined(_MSC_VER)
133 IMP_USAGE_CHECK(D == 2 || D == -1,
"Need " << D <<
" to construct a " << D
136 BOOST_STATIC_ASSERT(D == 2);
139 data_.set_coordinates(d, d + 2);
144 #ifdef IMP_SWIG_WRAPPER
145 IMP_USAGE_CHECK(D == 3 || D == -1,
"Need " << D <<
" to construct a " << D
148 BOOST_STATIC_ASSERT(D == 3);
150 double d[] = {x, y, z};
151 data_.set_coordinates(d, d + 3);
155 VectorD(
double x0,
double x1,
double x2,
double x3) {
156 #if defined(IMP_SWIG_WRAPPER) || defined(_MSC_VER)
157 IMP_USAGE_CHECK(D == 4 || D == -1,
"Need " << D <<
" to construct a " << D
160 BOOST_STATIC_ASSERT(D == 4);
162 double d[] = {x0, x1, x2, x3};
163 data_.set_coordinates(d, d + 4);
172 IMP_VECTOR_CHECK_INDEX(i);
174 return data_.get_data()[i];
179 IMP_VECTOR_CHECK_INDEX(i);
180 return data_.get_data()[i];
183 double get_scalar_product(
const VectorD<D> &o)
const {
184 IMP_VECTOR_CHECK_COMPATIBLE(o);
187 for (
unsigned int i = 0; i < get_dimension(); ++i) {
188 ret += operator[](i) * o.operator[](i);
193 double get_squared_magnitude()
const {
return get_scalar_product(*
this); }
195 double get_magnitude()
const {
return std::sqrt(get_squared_magnitude()); }
205 const double tiny_double = 1e-12;
206 double mag = get_magnitude();
207 if (mag > tiny_double) {
208 return operator/(mag);
214 boost::variate_generator<boost::rand48, boost::normal_distribution<> >
216 ::boost::normal_distribution<>(0, 1.0));
217 for (
unsigned int i = 0; i < get_dimension(); ++i) {
218 ret[i] = generator();
226 IMP_VECTOR_CHECK_COMPATIBLE(o);
227 return get_scalar_product(o);
237 VectorD operator/(
double s)
const {
244 VectorD operator-()
const {
247 for (
unsigned int i = 0; i < get_dimension(); ++i) {
253 VectorD operator-(
const VectorD &o)
const {
254 IMP_VECTOR_CHECK_COMPATIBLE(o);
261 VectorD operator+(
const VectorD &o)
const {
262 IMP_VECTOR_CHECK_COMPATIBLE(o);
269 VectorD &operator+=(
const VectorD &o) {
270 IMP_VECTOR_CHECK_COMPATIBLE(o);
272 for (
unsigned int i = 0; i < get_dimension(); ++i) {
273 operator[](i) += o[i];
278 VectorD &operator-=(
const VectorD &o) {
279 IMP_VECTOR_CHECK_COMPATIBLE(o);
281 for (
unsigned int i = 0; i < get_dimension(); ++i) {
282 operator[](i) -= o[i];
287 VectorD &operator/=(
double f) {
289 for (
unsigned int i = 0; i < get_dimension(); ++i) {
295 VectorD &operator*=(
double f) {
297 for (
unsigned int i = 0; i < get_dimension(); ++i) {
303 void show(std::ostream &out, std::string delim,
bool parens =
true)
const {
305 if (parens) out <<
"(";
306 for (
unsigned int i = 0; i < get_dimension(); ++i) {
307 out << operator[](i);
308 if (i != get_dimension() - 1) {
312 if (parens) out <<
")";
318 typedef double *CoordinateIterator;
319 CoordinateIterator coordinates_begin() {
return data_.get_data(); }
320 CoordinateIterator coordinates_end() {
321 return data_.get_data() + get_dimension();
323 typedef const double *CoordinateConstIterator;
324 CoordinateConstIterator coordinates_begin()
const {
return data_.get_data(); }
325 CoordinateConstIterator coordinates_end()
const {
326 return data_.get_data() + get_dimension();
333 Floats get_coordinates()
const {
334 return Floats(coordinates_begin(), coordinates_end());
338 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
339 const double *get_data()
const {
return data_.get_data(); }
341 unsigned int get_dimension()
const {
return data_.get_dimension(); }
345 internal::VectorData<double, D, false> data_;
351 inline std::ostream &operator<<(std::ostream &out, const VectorD<D> &v) {
357 inline std::istream &operator>>(std::istream &in, VectorD<D> &v) {
358 for (
unsigned int i = 0; i < D; ++i) {
373 "Dimensions don't match.");
374 for (
unsigned int i = 0; i < a.get_dimension(); ++i) {
377 else if (a[i] > b[i])
394 return (v1 - v2).get_squared_magnitude();
415 IMP_USAGE_CHECK(coordinate < D,
"There are only " << D <<
" basis vectors");
417 for (
unsigned int i = 0; i < D; ++i) {
430 "There are only " << D <<
" basis vectors");
431 boost::scoped_array<double> vs(
new double[D]);
432 for (
int i = 0; i < D; ++i) {
433 if (i == static_cast<int>(coordinate))
438 return VectorD<-1>(vs.get(), vs.get() + D);
446 for (
int i = 0; i < D; ++i) {
457 return get_zero_vector_d<D>();
464 return VectorD<-1>(vs.begin(), vs.end());
472 for (
unsigned int i = 0; i < D; ++i) {
484 return get_ones_vector_d<D>(v);
490 boost::scoped_array<double> vv(
new double[D]);
491 for (
unsigned int i = 0; i < D; ++i) {
494 return VectorD<-1>(vv.get(), vv.get() + D);
508 inline double get_l2_norm(
const VectorD<D> &v) {
509 return v.get_magnitude();
513 inline double get_l1_norm(
const VectorD<D> &v) {
514 double n = std::abs(v[0]);
515 for (
unsigned int i = 1; i < v.get_dimension(); ++i) {
522 inline double get_linf_norm(
const VectorD<D> &v) {
523 double n = std::abs(v[0]);
524 for (
unsigned int i = 1; i < v.get_dimension(); ++i) {
525 n = std::max(n, std::abs(v[i]));
536 const VectorD<D> &v_;
537 SpacesIO(
const VectorD<D> &v) : v_(v) {}
542 const VectorD<D> &v_;
543 CommasIO(
const VectorD<D> &v) : v_(v) {}
546 inline std::ostream &operator<<(std::ostream &out, const SpacesIO<D> &s) {
547 s.v_.show(out,
" ",
false);
551 inline std::ostream &operator<<(std::ostream &out, const CommasIO<D> &s) {
552 s.v_.show(out,
", ",
false);
562 inline SpacesIO<D> spaces_io(
const VectorD<D> &v) {
563 return SpacesIO<D>(v);
572 inline CommasIO<D> commas_io(
const VectorD<D> &v) {
573 return CommasIO<D>(v);
625 for (
unsigned int i = 0; i < ret.get_dimension(); ++i) {
637 IMP_USAGE_CHECK(a.size() == b.get_dimension(),
"Dimensions don't match,");
639 for (
unsigned int i = 0; i < ret.get_dimension(); ++i) {
696 IMPALGEBRA_END_NAMESPACE
VectorD(double x)
Initialize the 1-vector from its value.
base::Vector< VectorInputD< 1 > > VectorInput1Ds
VectorD< D > get_elementwise_product(const algebra::VectorD< D > &a, const algebra::VectorD< D > &b)
VectorInputD< 3 > VectorInput3D
base::Vector< VectorInputD<-1 > > VectorInputKDs
VectorInputD< 2 > VectorInput2D
void set_vector_d_geometry(VectorD< D > &g, const VectorD< D > &v)
double operator[](unsigned int i) const
VectorD< D > get_zero_vector_kd(int Di)
Return a dynamically sized vector of zeros.
RandomNumberGenerator random_number_generator
A shared random number generator.
base::Vector< VectorD< 1 > > Vector1Ds
base::Vector< VectorInputD< 6 > > VectorInput6Ds
VectorInputD<-1 > VectorInputKD
base::Vector< VectorD< 2 > > Vector2Ds
#define IMP_UNUSED(variable)
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
double get_squared_distance(const VectorD< D > &v1, const VectorD< D > &v2)
compute the squared distance between two vectors
Random number generators used by IMP.
VectorD(double x, double y)
Initialize a 2-vector from separate x,y values.
VectorD()
Default constructor.
VectorInputD< 5 > VectorInput5D
base::Vector< VectorD< 5 > > Vector5Ds
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
VectorD< D > get_ones_vector_kd(unsigned int Di, double v=1)
Return a vector of ones (or another constant)
VectorD<-1 > get_basis_vector_kd(int D, unsigned int coordinate)
Return a dynamically sized basis vector.
VectorD(double x0, double x1, double x2, double x3)
Initialize a 4-vector from separate w,x,y,z values.
#define IMP_USAGE_CHECK_VARIABLE(variable)
base::Vector< VectorD< 3 > > Vector3Ds
double get_distance(const Plane3D &pln, const Vector3D &p)
Return the distance between a plane and a point in 3D.
base::Vector< VectorInputD< 4 > > VectorInput4Ds
base::Vector< VectorInputD< 2 > > VectorInput2Ds
base::Vector< VectorD< 4 > > Vector4Ds
VectorD< D > operator*(double s, const VectorD< D > &o)
base::Vector< VectorInputD< 3 > > VectorInput3Ds
A Cartesian vector in D-dimensions.
int compare(const VectorD< D > &a, const VectorD< D > &b)
lexicographic comparison of two vectors
base::Vector< VectorD< 6 > > Vector6Ds
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown.
VectorD< D > get_zero_vector_d()
Return a vector of zeros.
VectorD(double x, double y, double z)
Initialize a 3-vector from separate x,y,z values.
VectorD< D > get_basis_vector_d(unsigned int coordinate)
Return the basis vector for the given coordinate.
Various general useful functions for IMP.
base::Vector< VectorD<-1 > > VectorKDs
Exception definitions and assertions.
VectorD< D > get_ones_vector_d(double v=1)
Return a vector of ones (or another constant)
void show(Hierarchy h, std::ostream &out=std::cout)
Print out a molecular hierarchy.
IMP::base::Vector< Float > Floats
Standard way to pass a bunch of Float values.
#define IMP_THROW(message, exception_name)
Throw an exception with a message.
VectorD get_unit_vector() const
VectorInputD< 4 > VectorInput4D
Exception definitions and assertions.
VectorInputD< 1 > VectorInput1D
VectorInputD< 6 > VectorInput6D
An exception for an invalid value being passed to IMP.
base::Vector< VectorInputD< 5 > > VectorInput5Ds
double & operator[](unsigned int i)