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