def __init__(O, f_obs, i_obs, i_sig, i_calc=None, f_calc=None, wa=0.1, wb=0): assert [i_calc, f_calc].count(None) == 1 if (i_calc is None): from cctbx.array_family import flex i_calc = flex.norm(f_calc) from cctbx import xray raw = xray.targets_shelxl_wght_ls_kwt_b_dv( f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, ic=i_calc, wa=wa, wb=wb) assert len(raw) == 5 O.scale_factor, \ O.weights, \ O.target, \ O.i_gradients, \ O.i_curvatures = raw if (f_calc is None): O.f_gradients = None O.f_hessians = None else: g = O.i_gradients c = O.i_curvatures O.f_gradients = 2 * g * f_calc a = flex.real(f_calc) b = flex.imag(f_calc) aa = 2 * g + 4 * a * a * c bb = 2 * g + 4 * b * b * c ab = 4 * a * b * c O.f_hessians = flex.vec3_double(aa, bb, ab)
def exercise_py_LS(obs, f_calc, weighting, verbose): weighting.computing_derivatives_wrt_f_c = True r = xray.unified_least_squares_residual(obs, weighting=weighting) rt = r(f_calc, compute_derivatives=True) if obs.is_xray_amplitude_array(): assert(isinstance(rt, xray.targets_least_squares_residual)) elif obs.is_xray_intensity_array(): assert(isinstance(rt, xray.targets_least_squares_residual_for_intensity)) scale_factor = rt.scale_factor() gr_ana = rt.derivatives() K = scale_factor w = weighting.weights if w is not None: w = w.deep_copy() dw_dfc = weighting.derivatives_wrt_f_c if dw_dfc is not None: dw_dfc = dw_dfc.deep_copy() y_o = obs.data() if w is None: w = flex.double(obs.size(), 1) sum_w_y_o_sqr = flex.sum(w * y_o * y_o) f_c = f_calc.data().deep_copy() if obs.is_xray_amplitude_array(): y_c = flex.abs(f_c) der = f_c * (1/y_c) elif obs.is_xray_intensity_array(): y_c = flex.norm(f_c) der = 2 * f_c gr_explicit = w*2*K*(K*y_c - y_o) * der / sum_w_y_o_sqr sum_w_squares = flex.sum(w*flex.pow2(K*y_c - y_o)) assert approx_equal(gr_ana, gr_explicit) gr_fin = flex.complex_double() eps = 1.e-6 for i_refl in xrange(obs.size()): gc = [] for i_part in [0,1]: fc0 = f_calc.data()[i_refl] ts = [] for signed_eps in [eps,-eps]: if (i_part == 0): f_calc.data()[i_refl] = complex(fc0.real + signed_eps, fc0.imag) else: f_calc.data()[i_refl] = complex(fc0.real, fc0.imag + signed_eps) rt = r(f_calc, compute_derivatives=False, scale_factor=scale_factor) ts.append(rt.target()) f_calc.data()[i_refl] = fc0 gc.append((ts[0]-ts[1])/(2*eps)) gr_fin.append(complex(*gc)) if (verbose): print "ana:", list(gr_ana) print "fin:", list(gr_fin) if dw_dfc is None: assert approx_equal(gr_fin, gr_ana) else: gr_total_ana = ( gr_ana + dw_dfc*(flex.pow2(K*y_c - y_o)/sum_w_y_o_sqr - sum_w_squares*flex.pow2(y_o)/sum_w_y_o_sqr**2) ) assert approx_equal(gr_fin, gr_total_ana)
def kwt(f_obs, i_obs, i_sig, f_calc, i_calc, wa, wb): if (f_calc is not None): i_calc = flex.norm(f_calc) k = calc_k(f_obs, i_calc) weights = calc_w(wa=wa, wb=wb, i_obs=i_obs, i_sig=i_sig, i_calc=i_calc, k=k) t = calc_t(i_obs=i_obs, i_calc=i_calc, k=k, weights=weights) return k, weights, t
def kwt(f_obs, i_obs, i_sig, f_calc, i_calc, wa, wb): if (f_calc is not None): i_calc = flex.norm(f_calc) k = calc_k(f_obs, i_calc) weights = calc_w( wa=wa, wb=wb, i_obs=i_obs, i_sig=i_sig, i_calc=i_calc, k=k) t = calc_t( i_obs=i_obs, i_calc=i_calc, k=k, weights=weights) return k, weights, t
def compute(self, f_calc, scale_factor=None): self.calculated = f_calc assert (self.observed.is_xray_intensity_array()) assert (self.calculated.is_complex_array()) a, b = self._params f_c = self.calculated.data() if scale_factor is None: scale_factor = self.observed.scale_factor(self.calculated, cutoff_factor=0.99) self.scale_factor = scale_factor f_c = f_c * math.sqrt(scale_factor) # don't modify f_c in place sigmas_square = flex.pow2(self.observed.sigmas()) f_obs_square_plus = self.observed.data().deep_copy() negatives = self.observed.data() < 0 f_obs_square_plus.set_selected(negatives, 0) p = (f_obs_square_plus + 2 * flex.norm(f_c)) / 3 w = 1 / (sigmas_square + flex.pow2(a * p) + b * p) dw_dfc = -(2 * a * a * p + b) * flex.pow2(w) * (4. / 3 * f_c) self.weights, self.derivatives_wrt_f_c = w, dw_dfc
def run(): crystal_symmetry = crystal.symmetry(unit_cell=(10, 11, 12, 85, 95, 100), space_group_symbol="P 1") miller_set = miller.build_set(crystal_symmetry=crystal_symmetry, anomalous_flag=False, d_min=3) f_calc = miller_set.array(data=flex.polar( flex.random_double(miller_set.size()) * 10 - 5, flex.random_double(miller_set.size()) * 10 - 5)) scale_factor = flex.random_double() obs = miller_set.array(data=scale_factor * flex.norm(f_calc.data()) + (flex.random_double(miller_set.size()) * 2 - 1), sigmas=flex.random_double(miller_set.size())) obs.set_observation_type_xray_intensity() exercise_shelx_weighting(f_calc, obs, scale_factor) exercise_quasi_unit_weighting(obs) print('OK')
def exercise(space_group_info, n_scatterers=8, d_min=2.5, anomalous_flag=False, verbose=0): f_calc = random_f_calc( space_group_info=space_group_info, n_scatterers=n_scatterers, d_min=d_min, anomalous_flag=anomalous_flag, verbose=verbose) if (f_calc is None): return data = flex.norm(f_calc.data()) scale_factor = 9999998/flex.max(data) data = data * scale_factor + 1 f_calc = miller.array( miller_set=f_calc, data=data, sigmas=data/10).set_observation_type_xray_intensity() f_calc = f_calc.select(flex.random_permutation(size=data.size())) recycle(miller_array=f_calc) recycle(miller_array=f_calc.f_sq_as_f())
def compute(self, f_calc, scale_factor=None): self.calculated = f_calc assert(self.observed.is_xray_intensity_array()) assert(self.calculated.is_complex_array()) a,b = self._params f_c = self.calculated.data() if scale_factor is None: scale_factor = self.observed.scale_factor( self.calculated, cutoff_factor=0.99) self.scale_factor = scale_factor f_c = f_c * math.sqrt(scale_factor) # don't modify f_c in place sigmas_square = flex.pow2(self.observed.sigmas()) f_obs_square_plus = self.observed.data().deep_copy() negatives = self.observed.data() < 0 f_obs_square_plus.set_selected(negatives, 0) p = (f_obs_square_plus + 2*flex.norm(f_c))/3 w = 1/(sigmas_square + flex.pow2(a*p) + b*p) dw_dfc = -(2*a*a*p + b) * flex.pow2(w) * (4./3*f_c) self.weights, self.derivatives_wrt_f_c = w, dw_dfc
def exercise(space_group_info, n_scatterers=8, d_min=2.5, anomalous_flag=False, verbose=0): f_calc = random_f_calc(space_group_info=space_group_info, n_scatterers=n_scatterers, d_min=d_min, anomalous_flag=anomalous_flag, verbose=verbose) if (f_calc is None): return data = flex.norm(f_calc.data()) scale_factor = 9999998 / flex.max(data) data = data * scale_factor + 1 f_calc = miller.array(miller_set=f_calc, data=data, sigmas=data / 10).set_observation_type_xray_intensity() f_calc = f_calc.select(flex.random_permutation(size=data.size())) recycle(miller_array=f_calc) recycle(miller_array=f_calc.f_sq_as_f())
def run(args): assert args in [[], ["--verbose"]] verbose = "--verbose" in args exercise_least_squares_residual() exercise_core_LS(xray.targets_least_squares_residual, verbose) exercise_core_LS(xray.targets_least_squares_residual_for_intensity, verbose) crystal_symmetry = crystal.symmetry( unit_cell=(10,11,12,85,95,100), space_group_symbol="P 1") miller_set = miller.build_set( crystal_symmetry=crystal_symmetry, anomalous_flag=False, d_min=3) f_calc = miller_set.array( data=flex.polar( flex.random_double(miller_set.size())*10-5, flex.random_double(miller_set.size())*10-5)) obs = miller_set.array( data=flex.abs(f_calc.data()) + (flex.random_double(miller_set.size())*2-1), sigmas=flex.random_double(miller_set.size())) obs.set_observation_type_xray_amplitude() weighting = xray.weighting_schemes.amplitude_unit_weighting() exercise_py_LS(obs, f_calc, weighting, verbose) obs = miller_set.array( data=flex.norm(f_calc.data()) + (flex.random_double(miller_set.size())*2-1), sigmas=flex.random_double(miller_set.size())) obs.set_observation_type_xray_intensity() weighting = xray.weighting_schemes.intensity_quasi_unit_weighting() exercise_py_LS(obs, f_calc, weighting, verbose) weighting = xray.weighting_schemes.simple_shelx_weighting(a=100, b=150) exercise_py_LS(obs, f_calc, weighting, verbose) weighting = xray.weighting_schemes.shelx_weighting(a=100, b=150) exercise_py_LS(obs, f_calc, weighting, verbose) print "OK"
def calc_shelxl_wght_ls(O, f_cbs, need): assert need in ["w", "t"] i_calc = flex.norm(f_cbs) from cctbx.xray.targets.tst_shelxl_wght_ls import calc_k, calc_w, calc_t k = calc_k(f_obs=O.f_obs.data(), i_calc=i_calc) assert O.i_obs.sigmas().all_ge(0.01) w = calc_w( wa=0.1, wb=0, i_obs=O.i_obs.data(), i_sig=O.i_obs.sigmas(), i_calc=i_calc, k=k) if (need == "w"): return w class wrapper(object): def __init__(W): W.t = calc_t(O.i_obs.data(), i_calc, k, w) def target_work(W): return W.t return wrapper()
def run(): crystal_symmetry = crystal.symmetry( unit_cell=(10,11,12,85,95,100), space_group_symbol="P 1") miller_set = miller.build_set( crystal_symmetry=crystal_symmetry, anomalous_flag=False, d_min=3) f_calc = miller_set.array( data=flex.polar( flex.random_double(miller_set.size())*10-5, flex.random_double(miller_set.size())*10-5)) scale_factor = flex.random_double() obs = miller_set.array( data=scale_factor * flex.norm(f_calc.data()) + (flex.random_double(miller_set.size())*2-1), sigmas=flex.random_double(miller_set.size())) obs.set_observation_type_xray_intensity() exercise_shelx_weighting(f_calc, obs, scale_factor) exercise_quasi_unit_weighting(obs) print 'OK'
def run(args): assert args in [[], ["--verbose"]] verbose = "--verbose" in args exercise_least_squares_residual() exercise_core_LS(xray.targets_least_squares_residual, verbose) exercise_core_LS(xray.targets_least_squares_residual_for_intensity, verbose) crystal_symmetry = crystal.symmetry(unit_cell=(10, 11, 12, 85, 95, 100), space_group_symbol="P 1") miller_set = miller.build_set(crystal_symmetry=crystal_symmetry, anomalous_flag=False, d_min=3) f_calc = miller_set.array(data=flex.polar( flex.random_double(miller_set.size()) * 10 - 5, flex.random_double(miller_set.size()) * 10 - 5)) obs = miller_set.array(data=flex.abs(f_calc.data()) + (flex.random_double(miller_set.size()) * 2 - 1), sigmas=flex.random_double(miller_set.size())) obs.set_observation_type_xray_amplitude() weighting = xray.weighting_schemes.amplitude_unit_weighting() exercise_py_LS(obs, f_calc, weighting, verbose) obs = miller_set.array(data=flex.norm(f_calc.data()) + (flex.random_double(miller_set.size()) * 2 - 1), sigmas=flex.random_double(miller_set.size())) obs.set_observation_type_xray_intensity() weighting = xray.weighting_schemes.intensity_quasi_unit_weighting() exercise_py_LS(obs, f_calc, weighting, verbose) weighting = xray.weighting_schemes.simple_shelx_weighting(a=100, b=150) exercise_py_LS(obs, f_calc, weighting, verbose) weighting = xray.weighting_schemes.shelx_weighting(a=100, b=150) exercise_py_LS(obs, f_calc, weighting, verbose) print "OK"
def __init__(O, f_obs, i_obs, i_sig, i_calc=None, f_calc=None, wa=0.1, wb=0): assert [i_calc, f_calc].count(None) == 1 if (i_calc is None): from cctbx.array_family import flex i_calc = flex.norm(f_calc) from cctbx import xray raw = xray.targets_shelxl_wght_ls_kwt_b_dv(f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, ic=i_calc, wa=wa, wb=wb) assert len(raw) == 5 O.scale_factor, \ O.weights, \ O.target, \ O.i_gradients, \ O.i_curvatures = raw if (f_calc is None): O.f_gradients = None O.f_hessians = None else: g = O.i_gradients c = O.i_curvatures O.f_gradients = 2 * g * f_calc a = flex.real(f_calc) b = flex.imag(f_calc) aa = 2 * g + 4 * a * a * c bb = 2 * g + 4 * b * b * c ab = 4 * a * b * c O.f_hessians = flex.vec3_double(aa, bb, ab)
def exercise_py_LS(obs, f_calc, weighting, verbose): weighting.computing_derivatives_wrt_f_c = True r = xray.unified_least_squares_residual(obs, weighting=weighting) rt = r(f_calc, compute_derivatives=True) if obs.is_xray_amplitude_array(): assert (isinstance(rt, xray.targets_least_squares_residual)) elif obs.is_xray_intensity_array(): assert (isinstance(rt, xray.targets_least_squares_residual_for_intensity)) scale_factor = rt.scale_factor() gr_ana = rt.derivatives() K = scale_factor w = weighting.weights if w is not None: w = w.deep_copy() dw_dfc = weighting.derivatives_wrt_f_c if dw_dfc is not None: dw_dfc = dw_dfc.deep_copy() y_o = obs.data() if w is None: w = flex.double(obs.size(), 1) sum_w_y_o_sqr = flex.sum(w * y_o * y_o) f_c = f_calc.data().deep_copy() if obs.is_xray_amplitude_array(): y_c = flex.abs(f_c) der = f_c * (1 / y_c) elif obs.is_xray_intensity_array(): y_c = flex.norm(f_c) der = 2 * f_c gr_explicit = w * 2 * K * (K * y_c - y_o) * der / sum_w_y_o_sqr sum_w_squares = flex.sum(w * flex.pow2(K * y_c - y_o)) assert approx_equal(gr_ana, gr_explicit) gr_fin = flex.complex_double() eps = 1.e-6 for i_refl in xrange(obs.size()): gc = [] for i_part in [0, 1]: fc0 = f_calc.data()[i_refl] ts = [] for signed_eps in [eps, -eps]: if (i_part == 0): f_calc.data()[i_refl] = complex(fc0.real + signed_eps, fc0.imag) else: f_calc.data()[i_refl] = complex(fc0.real, fc0.imag + signed_eps) rt = r(f_calc, compute_derivatives=False, scale_factor=scale_factor) ts.append(rt.target()) f_calc.data()[i_refl] = fc0 gc.append((ts[0] - ts[1]) / (2 * eps)) gr_fin.append(complex(*gc)) if (verbose): print "ana:", list(gr_ana) print "fin:", list(gr_fin) if dw_dfc is None: assert approx_equal(gr_fin, gr_ana) else: gr_total_ana = (gr_ana + dw_dfc * (flex.pow2(K * y_c - y_o) / sum_w_y_o_sqr - sum_w_squares * flex.pow2(y_o) / sum_w_y_o_sqr**2)) assert approx_equal(gr_fin, gr_total_ana)
def exercise(mt, n_refl): f_obs = mt.random_double(size=n_refl) i_obs = flex.pow2(f_obs) i_sig = mt.random_double(size=i_obs.size()) f_calc = flex.complex_double(mt.random_double(size=f_obs.size()), mt.random_double(size=f_obs.size())) i_calc = flex.norm(f_calc) wa = 1.23 wb = 2.34 trg = kwt2(f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, f_calc=f_calc, i_calc=None, wa=wa, wb=wb) def check_i_derivs(): g_ana = trg.i_gradients c_ana = trg.i_curvatures eps = 1e-6 g_fin = flex.double() c_fin = flex.double() for ih in xrange(i_calc.size()): fs = [] gs = [] c_orig = i_calc[ih] for signed_eps in [eps, -eps]: i_calc[ih] = c_orig + signed_eps trg_eps = kwt2(f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, f_calc=None, i_calc=i_calc, wa=wa, wb=wb) fs.append(trg_eps.target) gs.append(trg_eps.i_gradients[ih]) g_fin.append((fs[0] - fs[1]) / (2 * eps)) c_fin.append((gs[0] - gs[1]) / (2 * eps)) i_calc[ih] = c_orig assert approx_equal(g_ana, g_fin) assert approx_equal(c_ana, c_fin) def check_f_derivs(): g_ana = trg.f_gradients c_ana = trg.f_hessians eps = 1e-6 g_fin = flex.complex_double() c_fin = flex.vec3_double() for ih in xrange(i_calc.size()): c_orig = f_calc[ih] g_fin_ab = [] c_fin_ab = [] for iab in [0, 1]: fs = [] gs = [] for signed_eps in [eps, -eps]: if (iab == 0): f_calc[ih] = complex(c_orig.real + signed_eps, c_orig.imag) else: f_calc[ih] = complex(c_orig.real, c_orig.imag + signed_eps) trg_eps = kwt2(f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, f_calc=f_calc, i_calc=None, wa=wa, wb=wb) fs.append(trg_eps.target) gs.append(trg_eps.f_gradients[ih]) g_fin_ab.append((fs[0] - fs[1]) / (2 * eps)) c_fin_ab.append((gs[0] - gs[1]) / (2 * eps)) g_fin.append(complex(*g_fin_ab)) assert approx_equal(c_fin_ab[0].imag, c_fin_ab[1].real) c_fin.append( (c_fin_ab[0].real, c_fin_ab[1].imag, c_fin_ab[0].imag)) f_calc[ih] = c_orig assert approx_equal(g_ana, g_fin) assert approx_equal(c_ana, c_fin) check_i_derivs() check_f_derivs()
def compute(self, f_calc, scale_factor=None): self.calculated = f_calc a,b,c,d,e,f = self._params if self._obs_part_dirty: # The part depending only on |F_o|^2 if c == 0: q = None else: exp_args = self.observed.sin_theta_over_lambda_sq().data() if e != 0: k_sqr = exp_args.deep_copy() exp_args *= c exp_vals = flex.exp(exp_args) if c > 0: q = exp_vals else: q = 1 - exp_vals self._q = q if self.observed.sigmas() is not None: self._den_obs = flex.pow2(self.observed.sigmas()) if d != 0: self._den_obs += d if e != 0: e_times_sin_theta_sq = k_sqr e_times_sin_theta_sq *= e * self._wavelength self._den_obs += e_times_sin_theta_sq else: self._den_obs = None negatives = self.observed.data() < 0 self._p_obs = self.observed.data().deep_copy() self._p_obs.set_selected(negatives, 0) self._p_obs *= f # self._obs_part_dirty = False # The part depending on |F_c|^2 as well q = self._q f_c = self.calculated.data() p = flex.norm(f_c) if scale_factor is None: scale_factor = self.observed.scale_factor( self.calculated, cutoff_factor=0.99) self.scale_factor = scale_factor p *= scale_factor p *= 1 - f p += self._p_obs den = p.deep_copy() den *= a * a der = None if self.computing_derivatives_wrt_f_c: der = 2*den den += b if self.computing_derivatives_wrt_f_c: der += b den *= p if self._den_obs is not None: den += self._den_obs if q is None: w = 1 / den else: w = q / den if self.computing_derivatives_wrt_f_c: if scale_factor is not None: # don't modify f_c in place f_c = f_c * math.sqrt(scale_factor) der *= -flex.pow2(w) der *= 4./3 der = der * f_c self.weights = w self.derivatives_wrt_f_c = der
def compute(self, f_calc, scale_factor=None): self.calculated = f_calc a, b, c, d, e, f = self._params if self._obs_part_dirty: # The part depending only on |F_o|^2 if c == 0: q = None else: exp_args = self.observed.sin_theta_over_lambda_sq().data() if e != 0: k_sqr = exp_args.deep_copy() exp_args *= c exp_vals = flex.exp(exp_args) if c > 0: q = exp_vals else: q = 1 - exp_vals self._q = q if self.observed.sigmas() is not None: self._den_obs = flex.pow2(self.observed.sigmas()) if d != 0: self._den_obs += d if e != 0: e_times_sin_theta_sq = k_sqr e_times_sin_theta_sq *= e * self._wavelength self._den_obs += e_times_sin_theta_sq else: self._den_obs = None negatives = self.observed.data() < 0 self._p_obs = self.observed.data().deep_copy() self._p_obs.set_selected(negatives, 0) self._p_obs *= f # self._obs_part_dirty = False # The part depending on |F_c|^2 as well q = self._q f_c = self.calculated.data() p = flex.norm(f_c) if scale_factor is None: scale_factor = self.observed.scale_factor(self.calculated, cutoff_factor=0.99) self.scale_factor = scale_factor p *= scale_factor p *= 1 - f p += self._p_obs den = p.deep_copy() den *= a * a der = None if self.computing_derivatives_wrt_f_c: der = 2 * den den += b if self.computing_derivatives_wrt_f_c: der += b den *= p if self._den_obs is not None: den += self._den_obs if q is None: w = 1 / den else: w = q / den if self.computing_derivatives_wrt_f_c: if scale_factor is not None: # don't modify f_c in place f_c = f_c * math.sqrt(scale_factor) der *= -flex.pow2(w) der *= 4. / 3 der = der * f_c self.weights = w self.derivatives_wrt_f_c = der
def run_fast_terms(structure_fixed, structure_p1, f_obs, f_calc_fixed, f_calc_p1, symmetry_flags, gridding, grid_tags, n_sample_grid_points=10, test_origin=False, verbose=0): if (f_calc_fixed is None): f_part = flex.complex_double() else: f_part = f_calc_fixed.data() m = flex.double() for i in xrange(f_obs.indices().size()): m.append(random.random()) assert f_obs.anomalous_flag() == f_calc_p1.anomalous_flag() fast_terms = translation_search.fast_terms( gridding=gridding, anomalous_flag=f_obs.anomalous_flag(), miller_indices_p1_f_calc=f_calc_p1.indices(), p1_f_calc=f_calc_p1.data()) for squared_flag in (False, True): map = fast_terms.summation( space_group=f_obs.space_group(), miller_indices_f_obs=f_obs.indices(), m=m, f_part=f_part, squared_flag=squared_flag).fft().accu_real_copy() assert map.all() == gridding map_stats = maptbx.statistics(map) if (0 or verbose): map_stats.show_summary() grid_tags.build(f_obs.space_group_info().type(), symmetry_flags) assert grid_tags.n_grid_misses() == 0 assert grid_tags.verify(map) for i_sample in xrange(n_sample_grid_points): run_away_counter = 0 while 1: run_away_counter += 1 assert run_away_counter < 1000 if (i_sample == 0 and test_origin): grid_point = [0,0,0] else: grid_point = [random.randrange(g) for g in gridding] grid_site = [float(x)/g for x,g in zip(grid_point,gridding)] structure_shifted = structure_fixed.deep_copy_scatterers() assert structure_shifted.special_position_indices().size() == 0 structure_shifted.add_scatterers( scatterers=structure_p1.apply_shift(grid_site).scatterers()) if (structure_shifted.special_position_indices().size() == 0): break if (test_origin): assert i_sample != 0 i_grid = flex.norm(f_obs.structure_factors_from_scatterers( xray_structure=structure_shifted, algorithm="direct").f_calc().data()) if (squared_flag): p = 4 else: p = 2 map_value = map[grid_point] * f_obs.space_group().n_ltr()**p if (not squared_flag): sum_m_i_grid = flex.sum(m * i_grid) else: sum_m_i_grid = flex.sum(m * flex.pow2(i_grid)) assert "%.6g" % sum_m_i_grid == "%.6g" % map_value, ( sum_m_i_grid, map_value)
def exercise(mt, n_refl): f_obs = mt.random_double(size=n_refl) i_obs = flex.pow2(f_obs) i_sig = mt.random_double(size=i_obs.size()) f_calc = flex.complex_double( mt.random_double(size=f_obs.size()), mt.random_double(size=f_obs.size())) i_calc = flex.norm(f_calc) wa = 1.23 wb = 2.34 trg = kwt2( f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, f_calc=f_calc, i_calc=None, wa=wa, wb=wb) def check_i_derivs(): g_ana = trg.i_gradients c_ana = trg.i_curvatures eps = 1e-6 g_fin = flex.double() c_fin = flex.double() for ih in xrange(i_calc.size()): fs = [] gs = [] c_orig = i_calc[ih] for signed_eps in [eps, -eps]: i_calc[ih] = c_orig + signed_eps trg_eps = kwt2( f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, f_calc=None, i_calc=i_calc, wa=wa, wb=wb) fs.append(trg_eps.target) gs.append(trg_eps.i_gradients[ih]) g_fin.append((fs[0]-fs[1])/(2*eps)) c_fin.append((gs[0]-gs[1])/(2*eps)) i_calc[ih] = c_orig assert approx_equal(g_ana, g_fin) assert approx_equal(c_ana, c_fin) def check_f_derivs(): g_ana = trg.f_gradients c_ana = trg.f_hessians eps = 1e-6 g_fin = flex.complex_double() c_fin = flex.vec3_double() for ih in xrange(i_calc.size()): c_orig = f_calc[ih] g_fin_ab = [] c_fin_ab = [] for iab in [0,1]: fs = [] gs = [] for signed_eps in [eps, -eps]: if (iab == 0): f_calc[ih] = complex(c_orig.real + signed_eps, c_orig.imag) else: f_calc[ih] = complex(c_orig.real, c_orig.imag + signed_eps) trg_eps = kwt2( f_obs=f_obs, i_obs=i_obs, i_sig=i_sig, f_calc=f_calc, i_calc=None, wa=wa, wb=wb) fs.append(trg_eps.target) gs.append(trg_eps.f_gradients[ih]) g_fin_ab.append((fs[0]-fs[1])/(2*eps)) c_fin_ab.append((gs[0]-gs[1])/(2*eps)) g_fin.append(complex(*g_fin_ab)) assert approx_equal(c_fin_ab[0].imag, c_fin_ab[1].real) c_fin.append((c_fin_ab[0].real, c_fin_ab[1].imag, c_fin_ab[0].imag)) f_calc[ih] = c_orig assert approx_equal(g_ana, g_fin) assert approx_equal(c_ana, c_fin) check_i_derivs() check_f_derivs()