def d_target_d_params_finite(f_obs, xray_structure, eps=1.e-8):
    result = flex.double()
    scatterers = xray_structure.scatterers()
    xray_structure_eps = xray_structure.deep_copy_scatterers()
    scatterers_eps = xray_structure_eps.scatterers()
    for i_scatterer in xrange(len(scatterers)):
        if (not scatterers[i_scatterer].flags.use_u_aniso()):
            np = 7
        else:
            np = 12
        dx = []
        for ix in xrange(np):
            ts = []
            for signed_eps in [eps, -eps]:
                si_eps = scatterer_as_list(scatterers[i_scatterer])
                si_eps[ix] += signed_eps
                scatterers_eps[i_scatterer] = scatterer_from_list(si_eps)
                sf = structure_factors(xray_structure=xray_structure_eps,
                                       miller_set=f_obs)
                sum_target_f = 0
                for obs, f in zip(f_obs.data(), sf.fs()):
                    target = least_squares(obs=obs, calc=f)
                    sum_target_f += target.f()
                ts.append(sum_target_f)
            result.append((ts[0] - ts[1]) / (2 * eps))
        scatterers_eps[i_scatterer] = scatterers[i_scatterer]
    return result
def exercise(args):
  verbose =  "--verbose" in args
  if (not verbose):
    out = StringIO()
  else:
    out = sys.stdout
  for i_trial in range(10):
    for n_sites in range(2,5+1):
      ops = []
      for i in range(3):
        ops.append(matrix.sqr(flex.random_double(size=9, factor=2)-1))
      sites = []
      for i in range(n_sites):
        sites.append(matrix.col(flex.random_double(size=3, factor=4)-2))
      hkl = matrix.row(flex.random_double(size=3, factor=4)-2)
      sf = exp_i_hx(sites=sites, ops=ops, hkl=hkl)
      for obs_factor in [1, 1.1]:
        obs = abs(sf.f()) * obs_factor
        grads_fin = d_exp_i_hx_d_sites_finite(
          sites=sites, ops=ops, obs=obs, hkl=hkl)
        print("grads_fin:", list(grads_fin), file=out)
        tf = least_squares(obs=obs, calc=sf.f())
        grads_ana = sf.d_target_d_sites(target=tf)
        print("grads_ana:", list(grads_ana), file=out)
        compare_derivatives(grads_ana, grads_fin)
        curvs_fin = d2_exp_i_hx_d_sites_finite(
          sites=sites, ops=ops, obs=obs, hkl=hkl)
        print("curvs_fin:", list(curvs_fin), file=out)
        curvs_ana = sf.d2_target_d_sites(target=tf)
        print("curvs_ana:", list(curvs_ana), file=out)
        compare_derivatives(curvs_ana, curvs_fin)
        print(file=out)
  print("OK")
def d_target_d_params_finite(f_obs, xray_structure, eps=1.e-8):
  result = flex.double()
  scatterers = xray_structure.scatterers()
  xray_structure_eps = xray_structure.deep_copy_scatterers()
  scatterers_eps = xray_structure_eps.scatterers()
  for i_scatterer in xrange(len(scatterers)):
    if (not scatterers[i_scatterer].flags.use_u_aniso()):
      np = 7
    else:
      np = 12
    dx = []
    for ix in xrange(np):
      ts = []
      for signed_eps in [eps, -eps]:
        si_eps = scatterer_as_list(scatterers[i_scatterer])
        si_eps[ix] += signed_eps
        scatterers_eps[i_scatterer] = scatterer_from_list(si_eps)
        sf = structure_factors(
          xray_structure=xray_structure_eps, miller_set=f_obs)
        sum_target_f = 0
        for obs,f in zip(f_obs.data(), sf.fs()):
          target = least_squares(obs=obs, calc=f)
          sum_target_f += target.f()
        ts.append(sum_target_f)
      result.append((ts[0]-ts[1])/(2*eps))
    scatterers_eps[i_scatterer] = scatterers[i_scatterer]
  return result
def exercise(args):
  verbose =  "--verbose" in args
  if (not verbose):
    out = StringIO()
  else:
    out = sys.stdout
  for i_trial in xrange(10):
    for n_sites in xrange(2,5+1):
      ops = []
      for i in xrange(3):
        ops.append(matrix.sqr(flex.random_double(size=9, factor=2)-1))
      sites = []
      for i in xrange(n_sites):
        sites.append(matrix.col(flex.random_double(size=3, factor=4)-2))
      hkl = matrix.row(flex.random_double(size=3, factor=4)-2)
      sf = exp_i_hx(sites=sites, ops=ops, hkl=hkl)
      for obs_factor in [1, 1.1]:
        obs = abs(sf.f()) * obs_factor
        grads_fin = d_exp_i_hx_d_sites_finite(
          sites=sites, ops=ops, obs=obs, hkl=hkl)
        print >> out, "grads_fin:", list(grads_fin)
        tf = least_squares(obs=obs, calc=sf.f())
        grads_ana = sf.d_target_d_sites(target=tf)
        print >> out, "grads_ana:", list(grads_ana)
        compare_derivatives(grads_ana, grads_fin)
        curvs_fin = d2_exp_i_hx_d_sites_finite(
          sites=sites, ops=ops, obs=obs, hkl=hkl)
        print >> out, "curvs_fin:", list(curvs_fin)
        curvs_ana = sf.d2_target_d_sites(target=tf)
        print >> out, "curvs_ana:", list(curvs_ana)
        compare_derivatives(curvs_ana, curvs_fin)
        print >> out
  print "OK"
def exercise(args):
    verbose = "--verbose" in args
    if (not verbose):
        out = StringIO()
    else:
        out = sys.stdout
    for n_alphas in xrange(2, 5):
        for i_trial in xrange(5):
            alphas = [2 * math.pi * random.random() for i in xrange(n_alphas)]
            exp_sum = exp_i_alpha_sum(alphas=alphas)
            obs = abs(exp_sum.f())
            compare_analytical_and_finite(obs=obs, alphas=alphas, out=out)
            compare_analytical_and_finite(obs=obs * (random.random() + 0.5),
                                          alphas=alphas,
                                          out=out)
    for obs in [0, 0.1]:
        for calc in [0j, 1.e-200j]:
            target = least_squares(obs=obs, calc=calc)
            assert target.f() == obs**2
            assert target.da() == 0
            assert target.db() == 0
            if (obs == 0):
                assert target.daa() == 2
                assert target.dbb() == 2
                assert target.dab() == 0
            else:
                assert target.daa() == -1.e160
                assert target.dbb() == -1.e160
                assert target.dab() == 1.e160
        calc = 1 + 1j
        while (calc != 0):
            target = least_squares(obs=obs, calc=calc)
            # exercise numerical stability without checking the results
            target.f()
            target.da()
            target.db()
            target.daa()
            target.dbb()
            target.dab()
            calc /= 2
    print "OK"
def d_target_d_alphas_finite(obs, alphas, eps=1.e-8):
    result = []
    for i_alpha in xrange(len(alphas)):
        alphas_eps = list(alphas)
        ts = []
        for signed_eps in [eps, -eps]:
            alphas_eps[i_alpha] = alphas[i_alpha] + signed_eps
            exp_sum = exp_i_alpha_sum(alphas=alphas_eps)
            target = least_squares(obs=obs, calc=exp_sum.f())
            ts.append(target.f())
        result.append((ts[0] - ts[1]) / (2 * eps))
    return result
def d_target_d_alphas_finite(obs, alphas, eps=1.0e-8):
    result = []
    for i_alpha in xrange(len(alphas)):
        alphas_eps = list(alphas)
        ts = []
        for signed_eps in [eps, -eps]:
            alphas_eps[i_alpha] = alphas[i_alpha] + signed_eps
            exp_sum = exp_i_alpha_sum(alphas=alphas_eps)
            target = least_squares(obs=obs, calc=exp_sum.f())
            ts.append(target.f())
        result.append((ts[0] - ts[1]) / (2 * eps))
    return result
def d2_target_d_alphas_finite(obs, alphas, eps=1.e-8):
    result = []
    for i_alpha in xrange(len(alphas)):
        alphas_eps = list(alphas)
        gs = []
        for signed_eps in [eps, -eps]:
            alphas_eps[i_alpha] = alphas[i_alpha] + signed_eps
            exp_sum = exp_i_alpha_sum(alphas=alphas_eps)
            target = least_squares(obs=obs, calc=exp_sum.f())
            dalphas = exp_sum.d_target_d_alphas(target=target)
            gs.append(dalphas)
        result.append([(gp - gm) / (2 * eps) for gp, gm in zip(gs[0], gs[1])])
    return result
def exercise(args):
    verbose = "--verbose" in args
    if not verbose:
        out = StringIO()
    else:
        out = sys.stdout
    for n_alphas in xrange(2, 5):
        for i_trial in xrange(5):
            alphas = [2 * math.pi * random.random() for i in xrange(n_alphas)]
            exp_sum = exp_i_alpha_sum(alphas=alphas)
            obs = abs(exp_sum.f())
            compare_analytical_and_finite(obs=obs, alphas=alphas, out=out)
            compare_analytical_and_finite(obs=obs * (random.random() + 0.5), alphas=alphas, out=out)
    for obs in [0, 0.1]:
        for calc in [0j, 1.0e-200j]:
            target = least_squares(obs=obs, calc=calc)
            assert target.f() == obs ** 2
            assert target.da() == 0
            assert target.db() == 0
            if obs == 0:
                assert target.daa() == 2
                assert target.dbb() == 2
                assert target.dab() == 0
            else:
                assert target.daa() == -1.0e160
                assert target.dbb() == -1.0e160
                assert target.dab() == 1.0e160
        calc = 1 + 1j
        while calc != 0:
            target = least_squares(obs=obs, calc=calc)
            # exercise numerical stability without checking the results
            target.f()
            target.da()
            target.db()
            target.daa()
            target.dbb()
            target.dab()
            calc /= 2
    print "OK"
def d2_target_d_alphas_finite(obs, alphas, eps=1.0e-8):
    result = []
    for i_alpha in xrange(len(alphas)):
        alphas_eps = list(alphas)
        gs = []
        for signed_eps in [eps, -eps]:
            alphas_eps[i_alpha] = alphas[i_alpha] + signed_eps
            exp_sum = exp_i_alpha_sum(alphas=alphas_eps)
            target = least_squares(obs=obs, calc=exp_sum.f())
            dalphas = exp_sum.d_target_d_alphas(target=target)
            gs.append(dalphas)
        result.append([(gp - gm) / (2 * eps) for gp, gm in zip(gs[0], gs[1])])
    return result
Example #11
0
def compare_analytical_and_finite(obs, params, out):
    grads_fin = d_target_d_params_finite(obs=obs, params=params)
    print("grads_fin:", pack_gradients(grads_fin), file=out)
    exp_sum = g_exp_i_alpha_sum(params=params)
    target = least_squares(obs=obs, calc=exp_sum.f())
    grads_ana = exp_sum.d_target_d_params(target=target)
    print("grads_ana:", pack_gradients(grads_ana), file=out)
    assert approx_equal(pack_gradients(grads_ana), pack_gradients(grads_fin))
    curvs_fin = d2_target_d_params_finite(obs=obs, params=params)
    print("curvs_fin:", curvs_fin, file=out)
    curvs_ana = list(exp_sum.d2_target_d_params(target=target))
    print("curvs_ana:", curvs_ana, file=out)
    assert approx_equal(curvs_ana, curvs_fin)
    print(file=out)
def compare_analytical_and_finite(obs, alphas, out):
    grads_fin = d_target_d_alphas_finite(obs=obs, alphas=alphas)
    print >> out, "grads_fin:", grads_fin
    exp_sum = exp_i_alpha_sum(alphas=alphas)
    target = least_squares(obs=obs, calc=exp_sum.f())
    grads_ana = exp_sum.d_target_d_alphas(target=target)
    print >> out, "grads_ana:", grads_ana
    assert approx_equal(grads_ana, grads_fin)
    curvs_fin = d2_target_d_alphas_finite(obs=obs, alphas=alphas)
    print >> out, "curvs_fin:", curvs_fin
    curvs_ana = exp_sum.d2_target_d_alphas(target=target)
    print >> out, "curvs_ana:", curvs_ana
    assert approx_equal(curvs_ana, curvs_fin)
    print >> out
def compare_analytical_and_finite(obs, params, out):
  grads_fin = d_target_d_params_finite(obs=obs, params=params)
  print >> out, "grads_fin:", pack_gradients(grads_fin)
  exp_sum = g_exp_i_alpha_sum(params=params)
  target = least_squares(obs=obs, calc=exp_sum.f())
  grads_ana = exp_sum.d_target_d_params(target=target)
  print >> out, "grads_ana:", pack_gradients(grads_ana)
  assert approx_equal(pack_gradients(grads_ana), pack_gradients(grads_fin))
  curvs_fin = d2_target_d_params_finite(obs=obs, params=params)
  print >> out, "curvs_fin:", curvs_fin
  curvs_ana = list(exp_sum.d2_target_d_params(target=target))
  print >> out, "curvs_ana:", curvs_ana
  assert approx_equal(curvs_ana, curvs_fin)
  print >> out
def compare_analytical_and_finite(obs, alphas, out):
    grads_fin = d_target_d_alphas_finite(obs=obs, alphas=alphas)
    print >> out, "grads_fin:", grads_fin
    exp_sum = exp_i_alpha_sum(alphas=alphas)
    target = least_squares(obs=obs, calc=exp_sum.f())
    grads_ana = exp_sum.d_target_d_alphas(target=target)
    print >> out, "grads_ana:", grads_ana
    assert approx_equal(grads_ana, grads_fin)
    curvs_fin = d2_target_d_alphas_finite(obs=obs, alphas=alphas)
    print >> out, "curvs_fin:", curvs_fin
    curvs_ana = exp_sum.d2_target_d_alphas(target=target)
    print >> out, "curvs_ana:", curvs_ana
    assert approx_equal(curvs_ana, curvs_fin)
    print >> out
def compare_analytical_and_finite(obs, hkl, d_star_sq, params, out):
  grads_fin = d_target_d_params_finite(
    obs=obs, hkl=hkl, d_star_sq=d_star_sq, params=params)
  print >> out, "grads_fin:", pack_gradients(grads_fin)
  sf = structure_factor(hkl=hkl, d_star_sq=d_star_sq, params=params)
  target = least_squares(obs=obs, calc=sf.f())
  grads_ana = sf.d_target_d_params(target=target)
  print >> out, "grads_ana:", pack_gradients(grads_ana)
  assert approx_equal(pack_gradients(grads_ana), pack_gradients(grads_fin))
  curvs_fin = d2_target_d_params_finite(
    obs=obs, hkl=hkl, d_star_sq=d_star_sq, params=params)
  print >> out, "curvs_fin:", curvs_fin
  curvs_ana = sf.d2_target_d_params(target=target)
  print >> out, "curvs_ana:", curvs_ana
  assert approx_equal(curvs_ana, curvs_fin, 1.e-5)
  print >> out
def d2_exp_i_hx_d_sites_finite(sites, ops, hkl, obs, eps=1.e-8):
  result = flex.double()
  sites_eps = list(sites)
  for js,site in enumerate(sites):
    site_eps = list(site)
    for jp in range(3):
      vs = []
      for signed_eps in [eps, -eps]:
        site_eps[jp] = site[jp] + signed_eps
        sites_eps[js] = matrix.col(site_eps)
        sf = exp_i_hx(sites=sites_eps, ops=ops, hkl=hkl)
        tf = least_squares(obs=obs, calc=sf.f())
        vs.append(sf.d_target_d_sites(target=tf))
      result.extend(((vs[0]-vs[1])/(2*eps)).as_1d())
    sites_eps[js] = sites[js]
  return result
def d2_exp_i_hx_d_sites_finite(sites, ops, hkl, obs, eps=1.e-8):
  result = flex.double()
  sites_eps = list(sites)
  for js,site in enumerate(sites):
    site_eps = list(site)
    for jp in xrange(3):
      vs = []
      for signed_eps in [eps, -eps]:
        site_eps[jp] = site[jp] + signed_eps
        sites_eps[js] = matrix.col(site_eps)
        sf = exp_i_hx(sites=sites_eps, ops=ops, hkl=hkl)
        tf = least_squares(obs=obs, calc=sf.f())
        vs.append(sf.d_target_d_sites(target=tf))
      result.extend(((vs[0]-vs[1])/(2*eps)).as_1d())
    sites_eps[js] = sites[js]
  return result
def d2_target_d_params_finite(obs, hkl, d_star_sq, params, eps=1.e-8):
  result = []
  params_eps = copy.deepcopy(params)
  for i_param in xrange(len(params)):
    for ix in xrange(7):
      gs = []
      for signed_eps in [eps, -eps]:
        pi_eps = params[i_param].as_list()
        pi_eps[ix] += signed_eps
        params_eps[i_param] = parameters(pi_eps[:3], *pi_eps[3:])
        sf = structure_factor(hkl=hkl, d_star_sq=d_star_sq, params=params_eps)
        target = least_squares(obs=obs, calc=sf.f())
        dp = sf.d_target_d_params(target=target)
        gs.append(pack_gradients(dp))
      result.append([(gp-gm)/(2*eps) for gp,gm in zip(gs[0],gs[1])])
    params_eps[i_param] = params[i_param]
  return result
def d2_target_d_params_finite(obs, params, eps=1.e-8):
  result = []
  params_eps = copy.deepcopy(params)
  for i_param in xrange(len(params)):
    for ix in xrange(4):
      gs = []
      for signed_eps in [eps, -eps]:
        pi_eps = params[i_param].as_list()
        pi_eps[ix] += signed_eps
        params_eps[i_param] = parameters(*pi_eps)
        exp_sum = g_exp_i_alpha_sum(params=params_eps)
        target = least_squares(obs=obs, calc=exp_sum.f())
        dp = exp_sum.d_target_d_params(target=target)
        gs.append(pack_gradients(dp))
      result.append([(gp-gm)/(2*eps) for gp,gm in zip(gs[0],gs[1])])
    params_eps[i_param] = params[i_param]
  return result
def d_target_d_params_finite(obs, params, eps=1.e-8):
  result = []
  params_eps = copy.deepcopy(params)
  for i_param in xrange(len(params)):
    dx = []
    for ix in xrange(4):
      ts = []
      for signed_eps in [eps, -eps]:
        pi_eps = params[i_param].as_list()
        pi_eps[ix] += signed_eps
        params_eps[i_param] = parameters(*pi_eps)
        exp_sum = g_exp_i_alpha_sum(params=params_eps)
        target = least_squares(obs=obs, calc=exp_sum.f())
        ts.append(target.f())
      dx.append((ts[0]-ts[1])/(2*eps))
    result.append(gradients(*dx))
    params_eps[i_param] = params[i_param]
  return result
def d_target_d_params_finite(obs, hkl, d_star_sq, params, eps=1.e-8):
  result = []
  params_eps = copy.deepcopy(params)
  for i_param in xrange(len(params)):
    dx = []
    for ix in xrange(7):
      ts = []
      for signed_eps in [eps, -eps]:
        pi_eps = params[i_param].as_list()
        pi_eps[ix] += signed_eps
        params_eps[i_param] = parameters(pi_eps[:3], *pi_eps[3:])
        sf = structure_factor(hkl=hkl, d_star_sq=d_star_sq, params=params_eps)
        target = least_squares(obs=obs, calc=sf.f())
        ts.append(target.f())
      dx.append((ts[0]-ts[1])/(2*eps))
    result.append(gradients(dx[:3], *dx[3:]))
    params_eps[i_param] = params[i_param]
  return result
Example #22
0
def d2_target_d_params_finite(obs, params, eps=1.e-8):
    result = []
    params_eps = copy.deepcopy(params)
    for i_param in range(len(params)):
        for ix in range(4):
            gs = []
            for signed_eps in [eps, -eps]:
                pi_eps = params[i_param].as_list()
                pi_eps[ix] += signed_eps
                params_eps[i_param] = parameters(*pi_eps)
                exp_sum = g_exp_i_alpha_sum(params=params_eps)
                target = least_squares(obs=obs, calc=exp_sum.f())
                dp = exp_sum.d_target_d_params(target=target)
                gs.append(pack_gradients(dp))
            result.append([(gp - gm) / (2 * eps)
                           for gp, gm in zip(gs[0], gs[1])])
        params_eps[i_param] = params[i_param]
    return result
Example #23
0
def d_target_d_params_finite(obs, params, eps=1.e-8):
    result = []
    params_eps = copy.deepcopy(params)
    for i_param in range(len(params)):
        dx = []
        for ix in range(4):
            ts = []
            for signed_eps in [eps, -eps]:
                pi_eps = params[i_param].as_list()
                pi_eps[ix] += signed_eps
                params_eps[i_param] = parameters(*pi_eps)
                exp_sum = g_exp_i_alpha_sum(params=params_eps)
                target = least_squares(obs=obs, calc=exp_sum.f())
                ts.append(target.f())
            dx.append((ts[0] - ts[1]) / (2 * eps))
        result.append(gradients(*dx))
        params_eps[i_param] = params[i_param]
    return result
def compare_analytical_and_finite(obs, hkl, d_star_sq, params, out):
    grads_fin = d_target_d_params_finite(obs=obs,
                                         hkl=hkl,
                                         d_star_sq=d_star_sq,
                                         params=params)
    print >> out, "grads_fin:", pack_gradients(grads_fin)
    sf = structure_factor(hkl=hkl, d_star_sq=d_star_sq, params=params)
    target = least_squares(obs=obs, calc=sf.f())
    grads_ana = sf.d_target_d_params(target=target)
    print >> out, "grads_ana:", pack_gradients(grads_ana)
    assert approx_equal(pack_gradients(grads_ana), pack_gradients(grads_fin))
    curvs_fin = d2_target_d_params_finite(obs=obs,
                                          hkl=hkl,
                                          d_star_sq=d_star_sq,
                                          params=params)
    print >> out, "curvs_fin:", curvs_fin
    curvs_ana = sf.d2_target_d_params(target=target)
    print >> out, "curvs_ana:", curvs_ana
    assert approx_equal(curvs_ana, curvs_fin, 1.e-5)
    print >> out
def d2_target_d_params_finite(obs, hkl, d_star_sq, params, eps=1.e-8):
    result = []
    params_eps = copy.deepcopy(params)
    for i_param in xrange(len(params)):
        for ix in xrange(7):
            gs = []
            for signed_eps in [eps, -eps]:
                pi_eps = params[i_param].as_list()
                pi_eps[ix] += signed_eps
                params_eps[i_param] = parameters(pi_eps[:3], *pi_eps[3:])
                sf = structure_factor(hkl=hkl,
                                      d_star_sq=d_star_sq,
                                      params=params_eps)
                target = least_squares(obs=obs, calc=sf.f())
                dp = sf.d_target_d_params(target=target)
                gs.append(pack_gradients(dp))
            result.append([(gp - gm) / (2 * eps)
                           for gp, gm in zip(gs[0], gs[1])])
        params_eps[i_param] = params[i_param]
    return result
def d_target_d_params_finite(obs, hkl, d_star_sq, params, eps=1.e-8):
    result = []
    params_eps = copy.deepcopy(params)
    for i_param in xrange(len(params)):
        dx = []
        for ix in xrange(7):
            ts = []
            for signed_eps in [eps, -eps]:
                pi_eps = params[i_param].as_list()
                pi_eps[ix] += signed_eps
                params_eps[i_param] = parameters(pi_eps[:3], *pi_eps[3:])
                sf = structure_factor(hkl=hkl,
                                      d_star_sq=d_star_sq,
                                      params=params_eps)
                target = least_squares(obs=obs, calc=sf.f())
                ts.append(target.f())
            dx.append((ts[0] - ts[1]) / (2 * eps))
        result.append(gradients(dx[:3], *dx[3:]))
        params_eps[i_param] = params[i_param]
    return result
def d_target_d_params_finite(d_order, f_obs, xray_structure, eps=1.e-8):
  assert d_order in [1,2]
  result = flex.double()
  scatterers = xray_structure.scatterers()
  site_symmetry_table = xray_structure.site_symmetry_table()
  xray_structure_eps = xray_structure.deep_copy_scatterers()
  scatterers_eps = xray_structure_eps.scatterers()
  for i_scatterer,scatterer in enumerate(scatterers):
    if (not site_symmetry_table.is_special_position(i_scatterer)):
      site_symmetry_ops = None
      if (not scatterer.flags.use_u_aniso()):
        ips = range(7)
      else:
        ips = range(12)
    else:
      site_symmetry_ops = site_symmetry_table.get(i_scatterer)
      site_constraints = site_symmetry_ops.site_constraints()
      ips = list(site_constraints.independent_indices)
      if (not scatterer.flags.use_u_aniso()):
        ips.extend(range(3,7))
      else:
        adp_constraints = site_symmetry_ops.adp_constraints()
        ips.extend([i+3 for i in adp_constraints.independent_indices])
        ips.extend(range(9,12))
    dx = []
    for ip in ips:
      vs = []
      for signed_eps in [eps, -eps]:
        si_eps = scatterer_as_list(scatterer)
        si_eps[ip] += signed_eps
        if (site_symmetry_ops is not None):
          if (ip < 3):
            all_params = site_constraints.all_params(
              independent_params=site_constraints.independent_params(
              all_params=si_eps[:3]))
            si_eps = list(all_params) + si_eps[3:]
          elif (scatterer.flags.use_u_aniso() and ip < 9):
            all_params = adp_constraints.all_params(
              independent_params=adp_constraints.independent_params(
                all_params=si_eps[3:9]))
            si_eps = si_eps[:3] + list(all_params) + si_eps[9:]
        scatterers_eps[i_scatterer] = scatterer_from_list(si_eps)
        scatterers_eps[i_scatterer].scattering_type = scatterer.scattering_type
        xray_structure_eps.re_apply_symmetry(i_scatterer)
        sf = structure_factors(
          xray_structure=xray_structure_eps, miller_set=f_obs)
        if (d_order == 1):
          sum_target_f = 0
          for obs,f in zip(f_obs.data(), sf.fs()):
            target = least_squares(obs=obs, calc=f)
            sum_target_f += target.f()
          vs.append(sum_target_f)
        else:
          dp = sf.d_target_d_params(f_obs=f_obs, target_type=least_squares)
          vs.append(dp)
      diff = (vs[0]-vs[1])/(2*eps)
      if (d_order == 1):
        result.append(diff)
      else:
        result.extend(diff)
    scatterers_eps[i_scatterer] = scatterer
  return result