00001 #ifndef CCTBX_MAPTBX_REAL_SPACE_REFINEMENT_H
00002 #define CCTBX_MAPTBX_REAL_SPACE_REFINEMENT_H
00003
00004
00005 #include <cctbx/maptbx/basic_map.h>
00006 #include <scitbx/array_family/versa_matrix.h>
00007 #if !(defined(__linux__) && defined(__GNUC__) \
00008 && __GNUC__ == 2 && __GNUC_MINOR__ == 96)
00009 #include <limits>
00010 #endif
00011
00012 namespace cctbx { namespace maptbx { namespace real_space_refinement {
00013
00014 static const bool no_assert = true;
00015
00016 template < typename FloatType, typename IntType >
00017 FloatType
00018 residual(
00019 basic_map<FloatType,IntType> const& map,
00020 af::const_ref<scitbx::vec3<FloatType> > const& sites,
00021 af::const_ref<FloatType> const& weights)
00022 {
00023 CCTBX_ASSERT(weights.size()==sites.size());
00024
00025 return -af::matrix_multiply(weights,map.get_cart_values(sites).const_ref()) / af::sum(weights);
00026 }
00027
00028
00029 template < typename FloatType, typename IntType >
00030 scitbx::vec3<FloatType>
00031 gradient (
00032 basic_map<FloatType,IntType> const& map,
00033 scitbx::vec3<FloatType> const& site,
00034 FloatType const& delta_h )
00035 {
00036 scitbx::vec3<FloatType> result;
00037 for ( std::size_t i=0; i<3; ++i )
00038 {
00039 cartesian<FloatType> h_pos(site);
00040 cartesian<FloatType> h_neg(site);
00041 h_pos[i] += delta_h;
00042 h_neg[i] -= delta_h;
00043
00044
00045
00046
00047
00048 result[i] = (map[h_pos] - map[h_neg]) / 2*delta_h;
00049 }
00050
00051
00052 FloatType len = result.length();
00053 if ( len > delta_h )
00054 {
00055 result *= delta_h / len;
00056 }
00057 return result;
00058 }
00059
00060 template < typename FloatType, typename IntType >
00061 af::shared<scitbx::vec3<FloatType> >
00062 gradients(
00063 basic_map<FloatType,IntType> const& map,
00064 af::const_ref<scitbx::vec3<FloatType> > const& sites,
00065 FloatType delta_h=1.0,
00066 std::size_t search_iter=0)
00067 {
00068 if (search_iter == 0) {
00069 #if defined(__linux__) && defined(__GNUC__) \
00070 && __GNUC__ == 2 && __GNUC_MINOR__ == 96
00071 search_iter = 53;
00072 #else
00073 search_iter = std::numeric_limits<FloatType>::digits;
00074 #endif
00075 }
00076 af::shared<scitbx::vec3<FloatType> > grad_vals;
00077 scitbx::vec3<FloatType> grad_val;
00078 std::size_t num = sites.size();
00079
00080
00081
00082 for(std::size_t i = 0; i < num; ++i)
00083 {
00084 grad_val = gradient(map,sites[i],delta_h);
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 FloatType current_density = map.get_cart_value(sites[i]);
00098 FloatType local_delta_h = delta_h;
00099 bool zero_out = true;
00100 for ( std::size_t iter=0; iter<search_iter; ++iter )
00101 {
00102 scitbx::vec3<FloatType> pred = sites[i] + grad_val;
00103 FloatType pred_dens = map.get_cart_value(pred);
00104 if ( pred_dens < current_density )
00105 {
00106 local_delta_h *= 0.5;
00107 grad_val = gradient(map,sites[i],local_delta_h);
00108 }
00109 else
00110 {
00111 zero_out = false;
00112 break;
00113 }
00114 }
00115 if ( zero_out )
00116 {
00117 grad_val[0] = grad_val[1] = grad_val[2] = 0;
00118 }
00119 grad_vals.push_back(-grad_val);
00120 }
00121 return grad_vals;
00122 }
00123
00124 }}}
00125
00126 #endif // CCTBX_MAPTBX_REAL_SPACE_REFINEMENT_H