8 #ifndef IMPALGEBRA_VECTOR_D_H
9 #define IMPALGEBRA_VECTOR_D_H
11 #include <IMP/algebra/algebra_config.h>
20 #include <boost/random/variate_generator.hpp>
21 #include <boost/random/normal_distribution.hpp>
22 #include <boost/range.hpp>
23 #include "internal/vector.h"
27 #include <boost/random/normal_distribution.hpp>
28 #include <boost/static_assert.hpp>
30 #if IMP_HAS_CHECKS >= IMP_USAGE
31 #define IMP_ALGEBRA_VECTOR_CHECK check_vector()
32 #define IMP_ALGEBRA_VECTOR_CHECK_INDEX(i) check_index(i)
33 #define IMP_ALGEBRA_VECTOR_CHECK_COMPATIBLE(o) \
34 check_compatible_vector(o); \
37 #define IMP_ALGEBRA_VECTOR_CHECK
38 #define IMP_ALGEBRA_VECTOR_CHECK_INDEX(i)
39 #define IMP_ALGEBRA_VECTOR_CHECK_COMPATIBLE(o)
42 IMPALGEBRA_BEGIN_NAMESPACE
55 IMP_ALGEBRA_VECTOR_METHODS(D);
60 std::vector<double> get_range(
double x0,
double x1,
double x2,
double x3,
61 double x4,
double x5) {
64 std::vector<double> ret;
66 if (x1 != std::numeric_limits<double>::max()) ret.push_back(x1);
67 if (x2 != std::numeric_limits<double>::max()) ret.push_back(x2);
68 if (x3 != std::numeric_limits<double>::max()) ret.push_back(x3);
69 if (x4 != std::numeric_limits<double>::max()) ret.push_back(x4);
70 if (x5 != std::numeric_limits<double>::max()) ret.push_back(x5);
75 IMP_ALGEBRA_VECTOR_METHODS(-1);
76 explicit VectorD(
double x0,
double x1 = std::numeric_limits<double>::max(),
77 double x2 = std::numeric_limits<double>::max(),
78 double x3 = std::numeric_limits<double>::max(),
79 double x4 = std::numeric_limits<double>::max(),
80 double x5 = std::numeric_limits<double>::max())
81 : P(get_range(x0, x1, x2, x3, x4, x5)) {}
85 class VectorD<1> :
public VectorBaseD<1> {
87 IMP_ALGEBRA_VECTOR_METHODS(1);
90 VectorD(
double x) { P::operator[](0) = x; }
93 class VectorD<2> :
public VectorBaseD<2> {
95 IMP_ALGEBRA_VECTOR_METHODS(2);
97 VectorD(
double x,
double y) {
103 class VectorD<3> :
public VectorBaseD<3> {
105 IMP_ALGEBRA_VECTOR_METHODS(3);
107 VectorD(
double x,
double y,
double z) {
108 P::operator[](0) = x;
109 P::operator[](1) = y;
110 P::operator[](2) = z;
114 class VectorD<4> :
public VectorBaseD<4> {
116 IMP_ALGEBRA_VECTOR_METHODS(4);
118 VectorD(
double x0,
double x1,
double x2,
double x3) {
119 P::operator[](0) = x0;
120 P::operator[](1) = x1;
121 P::operator[](2) = x2;
122 P::operator[](3) = x3;
126 class VectorD<5> :
public VectorBaseD<5> {
128 IMP_ALGEBRA_VECTOR_METHODS(5);
130 VectorD(
double x0,
double x1,
double x2,
double x3,
double x4) {
131 P::operator[](0) = x0;
132 P::operator[](1) = x1;
133 P::operator[](2) = x2;
134 P::operator[](3) = x3;
135 P::operator[](4) = x4;
139 class VectorD<6> :
public VectorBaseD<6> {
141 IMP_ALGEBRA_VECTOR_METHODS(6);
143 VectorD(
double x0,
double x1,
double x2,
double x3,
double x4,
double x5) {
144 P::operator[](0) = x0;
145 P::operator[](1) = x1;
146 P::operator[](2) = x2;
147 P::operator[](3) = x3;
148 P::operator[](4) = x4;
149 P::operator[](5) = x5;
156 inline std::ostream &operator<<(std::ostream &out, const VectorD<D> &v) {
164 inline std::istream &operator>>(std::istream &in, VectorD<D> &v) {
165 for (
unsigned int i = 0; i < D; ++i) {
181 "Dimensions don't match.");
182 for (
unsigned int i = 0; i < a.get_dimension(); ++i) {
185 else if (a[i] > b[i])
202 return (v1 - v2).get_squared_magnitude();
223 IMP_USAGE_CHECK(coordinate < D,
"There are only " << D <<
" basis vectors");
225 for (
unsigned int i = 0; i < D; ++i) {
239 return get_basis_vector_d<D>(coordinate);
247 "There are only " << D <<
" basis vectors");
248 boost::scoped_array<double> vs(
new double[D]);
249 for (
int i = 0; i < D; ++i) {
250 if (i == static_cast<int>(coordinate))
255 return VectorD<-1>(vs.get(), vs.get() + D);
268 for (
int i = 0; i < D; ++i) {
279 return get_zero_vector_d<D>();
287 return VectorD<-1>(vs.begin(), vs.end());
300 for (
unsigned int i = 0; i < D; ++i) {
312 return get_ones_vector_d<D>(v);
319 boost::scoped_array<double> vv(
new double[D]);
320 for (
unsigned int i = 0; i < D; ++i) {
323 return VectorD<-1>(vv.get(), vv.get() + D);
342 inline double get_l2_norm(
const VectorD<D> &v) {
343 return v.get_magnitude();
347 inline double get_l1_norm(
const VectorD<D> &v) {
348 double n = std::abs(v[0]);
349 for (
unsigned int i = 1; i < v.get_dimension(); ++i) {
356 inline double get_linf_norm(
const VectorD<D> &v) {
357 double n = std::abs(v[0]);
358 for (
unsigned int i = 1; i < v.get_dimension(); ++i) {
359 n = std::max(n, std::abs(v[i]));
370 const VectorD<D> &v_;
371 SpacesIO(
const VectorD<D> &v) : v_(v) {}
376 const VectorD<D> &v_;
377 CommasIO(
const VectorD<D> &v) : v_(v) {}
380 inline std::ostream &operator<<(std::ostream &out, const SpacesIO<D> &s) {
381 s.v_.show(out,
" ",
false);
385 inline std::ostream &operator<<(std::ostream &out, const CommasIO<D> &s) {
386 s.v_.show(out,
", ",
false);
396 inline SpacesIO<D> spaces_io(
const VectorD<D> &v) {
397 return SpacesIO<D>(v);
406 inline CommasIO<D> commas_io(
const VectorD<D> &v) {
407 return CommasIO<D>(v);
448 template <
class C,
class E>
460 for (
unsigned int i = 0; i < ret.get_dimension(); ++i) {
471 IMP_USAGE_CHECK(a.size() == b.get_dimension(),
"Dimensions don't match,");
473 for (
unsigned int i = 0; i < ret.get_dimension(); ++i) {
479 IMPALGEBRA_END_NAMESPACE
Vector< VectorD< 1 > > Vector1Ds
Vector< VectorD< 3 > > Vector3Ds
double get_squared_distance(const VectorD< D > &v1, const VectorD< D > &v2)
Compute the squared distance between two vectors.
Vector< VectorD< 5 > > Vector5Ds
Exception definitions and assertions.
Vector< VectorD< 2 > > Vector2Ds
const VectorD< C::DIMENSION > & get_vector_geometry(const C &g)
A Cartesian vector in D-dimensions.
#define IMP_UNUSED(variable)
VectorD< D > get_elementwise_product(const Ints &a, const algebra::VectorD< D > &b)
Return the vector that is the elementwise product of the two.
int compare(const VectorD< D > &a, const VectorD< D > &b)
lexicographic comparison of two vectors
VectorD< D > get_zero_vector_d()
Return a vector of zeros.
Vector< VectorD<-1 > > VectorKDs
VectorD< D > get_basis_vector_d(unsigned int coordinate)
Return the basis vector for the given coordinate.
void set_vector_geometry(C &g, const E &v)
Vector< VectorD< 6 > > Vector6Ds
For backwards compatibility.
Vector< VectorD< 4 > > Vector4Ds
VectorD<-1 > get_ones_vector_kd(unsigned int D, double v)
Return a vector of ones (or another constant)
VectorD< D > get_ones_vector_d(double v=1)
Return a vector of ones (or another constant)
Helper macros for throwing and handling exceptions.
VectorD<-1 > get_basis_vector_kd(int D, unsigned int coordinate)
Return a dynamically sized basis vector.
#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)
double get_distance(const VectorD< D > &v1, const VectorD< D > &v2)
Compute the distance between two vectors.
Random number generators used by IMP.
A Cartesian vector in D-dimensions.
VectorD<-1 > get_zero_vector_kd(int D)
Return a dynamically sized vector of zeros.