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)
anomalous_flag=False, d_min=0.8) structure = random_structure.xray_structure(indices.space_group_info(), elements=['C']*6 + ['O']*2 + ['N'], volume_per_atom=18.6, random_u_iso=True) f_ideal = structure.structure_factors(d_min=indices.d_min()).f_calc() f_obs = f_ideal.amplitudes() f_obs *= 2 f_obs.set_observation_type_xray_amplitude() f_obs_square = f_ideal.norm() f_obs_square *= 3 f_obs_square.set_observation_type_xray_intensity() ls_against_f = xray.unified_least_squares_residual(f_obs) ls_against_f_square = xray.unified_least_squares_residual(f_obs_square) residuals = ls_against_f(f_ideal, compute_derivatives=True) print "against F: value=%.3f, scale=%.3f" % (residuals.target(), residuals.scale_factor()) residuals = ls_against_f_square(f_ideal, compute_derivatives=True) print "against F^2: value=%.3f, scale=%.3f" % (residuals.target(), residuals.scale_factor()) perturbed_structure = structure.random_shift_sites(max_shift_cart=0.2) for s in perturbed_structure.scatterers(): s.flags.set_grad_site(True) refining_structure = perturbed_structure.deep_copy_scatterers() optimiser = xray.lbfgs(
d_min=0.8) structure = random_structure.xray_structure(indices.space_group_info(), elements=['C'] * 6 + ['O'] * 2 + ['N'], volume_per_atom=18.6, random_u_iso=True) f_ideal = structure.structure_factors(d_min=indices.d_min()).f_calc() f_obs = f_ideal.amplitudes() f_obs *= 2 f_obs.set_observation_type_xray_amplitude() f_obs_square = f_ideal.norm() f_obs_square *= 3 f_obs_square.set_observation_type_xray_intensity() ls_against_f = xray.unified_least_squares_residual(f_obs) ls_against_f_square = xray.unified_least_squares_residual(f_obs_square) residuals = ls_against_f(f_ideal, compute_derivatives=True) print("against F: value=%.3f, scale=%.3f" % (residuals.target(), residuals.scale_factor())) residuals = ls_against_f_square(f_ideal, compute_derivatives=True) print("against F^2: value=%.3f, scale=%.3f" % (residuals.target(), residuals.scale_factor())) perturbed_structure = structure.random_shift_sites(max_shift_cart=0.2) for s in perturbed_structure.scatterers(): s.flags.set_grad_site(True) refining_structure = perturbed_structure.deep_copy_scatterers() optimiser = xray.lbfgs(target_functor=ls_against_f_square,
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)