This patch moves the functions which create random vectors from
XYZDecorator to Vector3D.h so they can be used outside of the context of
an existing particle. XYZDecorator.randomize_in_box(lb, ub) goes to
XYZDecorator.set_coordinates(IMP.random_vector_in_box(lb,ub)).
Index: kernel/src/decorators/XYZDecorator.cpp
===================================================================
--- kernel/src/decorators/XYZDecorator.cpp (revision 672)
+++ kernel/src/decorators/XYZDecorator.cpp (working copy)
@@ -6,9 +6,7 @@
*/
#include "IMP/decorators/XYZDecorator.h"
-#include "IMP/random.h"
-#include <boost/random/uniform_real.hpp>
#include <cmath>
@@ -26,35 +24,6 @@
}
-void XYZDecorator::randomize_in_sphere(const Vector3D ¢er,
- float radius)
-{
- IMP_check(radius > 0, "Radius in randomize must be postive",
- ValueException);
- Vector3D min(center[0]-radius, center[1]-radius, center[2]-radius);
- Vector3D max(center[0]+radius, center[1]+radius, center[2]+radius);
- float norm;
- do {
- randomize_in_box(min, max);
- norm=0;
- for (int i=0; i< 3; ++i) {
- norm+= square(center[i]-get_coordinate(i));
- }
- norm = std::sqrt(norm);
- } while (norm > radius);
-}
-
-void XYZDecorator::randomize_in_box(const Vector3D &min,
- const Vector3D &max)
-{
- for (unsigned int i=0; i< 3; ++i) {
- IMP_check(min[i] < max[i], "Box for randomize must be non-empty",
- ValueException);
- ::boost::uniform_real<> rand(min[i], max[i]);
- set_coordinate(i, rand(random_number_generator));
- }
-}
-
IMP_DECORATOR_INITIALIZE(XYZDecorator, DecoratorBase,
{
key_[0] = FloatKey("x");
@@ -62,16 +31,9 @@
key_[2] = FloatKey("z");
})
-namespace {
- template <class T>
- T d(T a, T b){T d=a-b; return d*d;}
-}
-
Float distance(XYZDecorator a, XYZDecorator b)
{
- double d2= d(a.get_x(), b.get_x()) + d(a.get_y(), b.get_y())
- + d(a.get_z(), b.get_z());
- return std::sqrt(d2);
+ return (a.get_vector()-b.get_vector()).get_magnitude();
}
} // namespace IMP
Index: kernel/src/Vector3D.cpp
===================================================================
--- kernel/src/Vector3D.cpp (revision 0)
+++ kernel/src/Vector3D.cpp (revision 0)
@@ -0,0 +1,63 @@
+/**
+ * \file Vector3D.cpp \brief Classes to handle individual a vector.
+ *
+ * Copyright 2007-8 Sali Lab. All rights reserved.
+ *
+ */
+
+#include "IMP/Vector3D.h"
+#include "IMP/random.h"
+#include "IMP/internal/constants.h"
+#include "IMP/utility.h"
+
+#include <boost/random/uniform_real.hpp>
+
+namespace IMP
+{
+
+Vector3D random_vector_in_box(const Vector3D &min, const Vector3D &max)
+{
+ Vector3D ret;
+ for (unsigned int i=0; i< 3; ++i) {
+ IMP_check(min[i] < max[i], "Box for randomize must be non-empty",
+ ValueException);
+ ::boost::uniform_real<> rand(min[i], max[i]);
+ ret[i]=rand(random_number_generator);
+ }
+ return ret;
+}
+
+
+Vector3D random_vector_in_sphere(const Vector3D ¢er, Float radius) {
+ IMP_check(radius > 0, "Radius in randomize must be postive",
+ ValueException);
+ Vector3D min(center[0]-radius, center[1]-radius, center[2]-radius);
+ Vector3D max(center[0]+radius, center[1]+radius, center[2]+radius);
+ float norm;
+ Vector3D ret;
+ do {
+ ret=random_vector_in_box(min, max);
+ norm= (center- ret).get_magnitude();
+ } while (norm > radius);
+ return ret;
+}
+
+Vector3D random_vector_on_sphere(const Vector3D ¢er, Float radius) {
+ IMP_check(radius > 0, "Radius in randomize must be postive",
+ ValueException);
+ ::boost::uniform_real<> rand(-1,1);
+ Vector3D up;
+ up[2]= rand(random_number_generator);
+ ::boost::uniform_real<> trand(0, 2*internal::PI);
+ Float theta= trand(random_number_generator);
+ // radius of circle
+ Float r= std::sqrt(1-square(up[2]));
+ up[0]= std::sin(theta)*r;
+ up[1]= std::cos(theta)*r;
+ IMP_assert(std::abs(up.get_magnitude() -1) < .1,
+ "Error generating unit vector on sphere");
+ IMP_LOG(VERBOSE, "Random vector on sphere is " << up << std::endl);
+ return center+ up*radius;
+}
+
+} // namespace IMP
Index: kernel/include/IMP/decorators/XYZDecorator.h
===================================================================
--- kernel/include/IMP/decorators/XYZDecorator.h (revision 672)
+++ kernel/include/IMP/decorators/XYZDecorator.h (working copy)
@@ -8,16 +8,13 @@
#ifndef __IMP_XYZ_DECORATOR_H
#define __IMP_XYZ_DECORATOR_H
-#include <vector>
-#include <deque>
-#include <limits>
-
-#include "../Particle.h"
-#include "../Model.h"
#include "../DecoratorBase.h"
#include "../Vector3D.h"
#include "utility.h"
+#include <vector>
+#include <limits>
+
namespace IMP
{
@@ -67,19 +64,19 @@
return get_particle()->get_derivative(get_coordinate_key(i));
}
//! Add something to the derivative of the ith coordinate
- void add_to_coordinate_derivative(int i, Float v,
+ void add_to_coordinate_derivative(int i, Float v,
DerivativeAccumulator &d) {
get_particle()->add_to_derivative(get_coordinate_key(i), v, d);
}
//! Add something to the derivative of the coordinates
- void add_to_coordinates_derivative(const Vector3D& v,
+ void add_to_coordinates_derivative(const Vector3D& v,
DerivativeAccumulator &d) {
add_to_coordinate_derivative(0, v[0], d);
add_to_coordinate_derivative(1, v[1], d);
add_to_coordinate_derivative(2, v[2], d);
}
//! Get whether the coordinates are optimized
- /** \return true only if all of them are optimized.
+ /** \return true only if all of them are optimized.
*/
bool get_coordinates_are_optimized() const {
return get_particle()->get_is_optimized(get_coordinate_key(0))
@@ -104,23 +101,23 @@
/** Somewhat suspect based on wanting a Point/Vector differentiation
but we don't have points */
Vector3D get_vector() const {
- return Vector3D(get_x(), get_y(), get_z());
+ return Vector3D(get_x(), get_y(), get_z());
}
+ //! Get the vector of derivatives.
+ /** Somewhat suspect based on wanting a Point/Vector differentiation
+ but we don't have points */
+ Vector3D get_derivative_vector() const {
+ return Vector3D(get_coordinate_derivative(0),
+ get_coordinate_derivative(1),
+ get_coordinate_derivative(2));
+ }
+
//! Get a vector containing the keys for x,y,z
/** This is quite handy for initializing movers and things.
*/
- static const FloatKeys get_xyz_keys() {
- decorator_initialize_static_data();
- return key_;
- }
+ IMP_DECORATOR_GET_KEY(FloatKeys, xyz_keys, key_)
- //! Generate random coordinates in a sphere centered at the vector
- void randomize_in_sphere(const Vector3D ¢er, float radius);
-
- //! Generate random coordinates in a box defined by the vectors
- void randomize_in_box(const Vector3D &lower_corner,
- const Vector3D &upper_corner);
protected:
static FloatKey get_coordinate_key(unsigned int i) {
IMP_check(i <3, "Out of range coordinate",
Index: kernel/include/IMP/Vector3D.h
===================================================================
--- kernel/include/IMP/Vector3D.h (revision 672)
+++ kernel/include/IMP/Vector3D.h (working copy)
@@ -11,6 +11,7 @@
#include "IMP_config.h"
#include "base_types.h"
#include "macros.h"
+#include "exception.h"
#include <cmath>
@@ -22,7 +23,11 @@
*/
class IMPDLLEXPORT Vector3D
{
+ bool is_default() const {return false;}
public:
+ // public for swig
+ typedef Vector3D This;
+
//! Initialize the vector from separate x,y,z values.
Vector3D(Float x, Float y, Float z) {
vec_[0] = x;
@@ -33,6 +38,8 @@
//! Default constructor
Vector3D() {}
+ IMP_COMPARISONS_3(vec_[0], vec_[1], vec_[2]);
+
//! \return A single component of this vector (0-2).
Float operator[](unsigned int i) const {
IMP_assert(i < 3, "Invalid component of vector requested");
@@ -60,23 +67,23 @@
//! product with scalar
Vector3D operator*(Float s) const {
- return Vector3D(operator[](0) * s,
+ return Vector3D(operator[](0) * s,
operator[](1) * s,
- operator[](2) * s);
+ operator[](2) * s);
}
//! divide by a scalar
Vector3D operator/(Float s) const {
- return Vector3D(operator[](0) / s,
+ return Vector3D(operator[](0) / s,
operator[](1) / s,
- operator[](2) / s);
+ operator[](2) / s);
}
//! negation
Vector3D operator-() const {
- return Vector3D(-operator[](0),
+ return Vector3D(-operator[](0),
-operator[](1),
- -operator[](2));
+ -operator[](2));
}
//! \return the vector product of two vectors.
@@ -149,14 +156,6 @@
<< operator[](2) << ")";
}
- bool operator<(const Vector3D &o) const {
- for (unsigned int i=0; i< 3; ++i) {
- if (operator[](i) < o[i]) return true;
- else if (operator[](i) > o[i]) return false;
- }
- return false;
- }
-
private:
Float vec_[3];
};
@@ -166,11 +165,58 @@
//! product with scalar
inline Vector3D operator*(Float s, const Vector3D &o) {
- return Vector3D(o[0]*s,
+ return Vector3D(o[0]*s,
o[1]*s,
- o[2]*s);
+ o[2]*s);
}
+//! Generate a random vector in a box with uniform density
+/**
+ \ingroup uncommitted
+ */
+IMPDLLEXPORT Vector3D
+random_vector_in_box(const Vector3D &lb=Vector3D(0,0,0),
+ const Vector3D &ub=Vector3D(10,10,10));
+
+//! Generate a random vector in a sphere with uniform density
+/**
+ \ingroup uncommitted
+ */
+IMPDLLEXPORT Vector3D
+random_vector_in_sphere(const Vector3D ¢er=Vector3D(0,0,0),
+ Float radius=1);
+
+//! Generate a random vector on a sphere with uniform density
+/**
+ \ingroup uncommitted
+ */
+IMPDLLEXPORT Vector3D
+random_vector_on_sphere(const Vector3D ¢er=Vector3D(0,0,0),
+ Float radius=1);
+
+
+struct SpacesIO {
+ const Vector3D &v_;
+ SpacesIO(const Vector3D &v): v_(v){}
+};
+
+
+inline std::ostream &operator<<(std::ostream &out, const SpacesIO &s) {
+ out << s.v_[0] << " " << s.v_[1] << " " << s.v_[2];
+ return out;
+}
+
+struct CommasIO {
+ const Vector3D &v_;
+ CommasIO(const Vector3D &v): v_(v){}
+};
+
+
+inline std::ostream &operator<<(std::ostream &out, const CommasIO &s) {
+ out << s.v_[0] << ", " << s.v_[1] << ", " << s.v_[2];
+ return out;
+}
+
} // namespace IMP
#endif /* __IMP_VECTOR_3D_H */
Index: kernel/test/states/test_nonbonded_list.py
===================================================================
--- kernel/test/states/test_nonbonded_list.py (revision 672)
+++ kernel/test/states/test_nonbonded_list.py (working copy)
@@ -86,7 +86,8 @@
for i in range(0,10):
score= m.evaluate(False)
for d in ds:
- d.randomize_in_sphere(d.get_vector(), 2.0)
+ d.set_coordinates(IMP.random_vector_in_sphere(d.get_vector(),
+ 2.0))
def do_test_bl(self, ss):
"""Test the bond decorator list"""
@@ -148,8 +149,8 @@
print "Index is " +str(p.get_index().get_index())
d=IMP.XYZDecorator.create(p)
d.set_coordinates_are_optimized(True)
- d.randomize_in_box(IMP.Vector3D(0,0,0),
- IMP.Vector3D(10,10,10));
+ d.set_coordinates(IMP.random_vector_in_box(IMP.Vector3D(0,0,0),
+ IMP.Vector3D(10,10,10)))
nps= IMP.Particles([p])
s.add_particles(nps)
score= m.evaluate(False)
@@ -193,10 +194,12 @@
score= m.evaluate(False)
for p in ps0:
d= IMP.XYZDecorator.cast(p)
- d.randomize_in_sphere(d.get_vector(), 1)
+ d.set_coordinates(IMP.random_vector_in_sphere(d.get_vector(),
+ 1))
for p in ps1:
d= IMP.XYZDecorator.cast(p)
- d.randomize_in_sphere(d.get_vector(), 1)
+ d.set_coordinates(IMP.random_vector_in_sphere(d.get_vector(),
+ 1))
def do_test_spheres(self, ss):
Index: kernel/test/states/test_cover_bonds.py
===================================================================
--- kernel/test/states/test_cover_bonds.py (revision 672)
+++ kernel/test/states/test_cover_bonds.py (working copy)
@@ -15,8 +15,8 @@
p= IMP.Particle()
m.add_particle(p)
d= IMP.XYZDecorator.create(p)
- d.randomize_in_box(IMP.Vector3D(0,0,0),
- IMP.Vector3D(10,10,10))
+ d.set_coordinates(IMP.random_vector_in_box(IMP.Vector3D(0,0,0),
+ IMP.Vector3D(10,10,10)))
ps.append(p)
bds= []
bb= IMP.BondedDecorator.create(ps[0])
Index: kernel/doc/examples/chain.py
===================================================================
--- kernel/doc/examples/chain.py (revision 672)
+++ kernel/doc/examples/chain.py (working copy)
@@ -17,8 +17,8 @@
p= IMP.Particle()
pi= m.add_particle(p)
d= IMP.XYZDecorator.create(p)
- d.randomize_in_box(IMP.Vector3D(0,0,0),
- IMP.Vector3D(10,10,10))
+ d.set_coordinates(IMP.random_vector_in_box(IMP.Vector3D(0,0,0),
+ IMP.Vector3D(10,10,10)))
d.set_coordinates_are_optimized(True)
p.add_attribute(rk, radius, False)
chain.append(p)
Index: kernel/pyext/IMP/test.py
===================================================================
--- kernel/pyext/IMP/test.py (revision 672)
+++ kernel/pyext/IMP/test.py (working copy)
@@ -84,7 +84,7 @@
p= IMP.Particle()
model.add_particle(p)
d= IMP.XYZDecorator.create(p)
- d.randomize_in_box(lbv, ubv)
+ d.set_coordinates(IMP.random_vector_in_box(lbv, ubv))
ps.append(p)
d.set_coordinates_are_optimized(True)
return ps