[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[IMP-dev] move random functions



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 &center,
-                                       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 &center, 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 &center, 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 &center, 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 &center=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 &center=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