Exemplo n.º 1
0
def algorithm_4(f_obs,
                F,
                phase_source,
                max_cycles=100,
                auto_converge_eps=1.e-7,
                use_cpp=True):
    """
  Phased simultaneous search (alg4)
  """
    fc, f_masks = F[0], F[1:]
    fc = fc.deep_copy()
    F = [fc] + F[1:]
    # C++ version
    if (use_cpp):
        return mosaic_ext.alg4([f.data() for f in F], f_obs.data(),
                               phase_source.data(), max_cycles,
                               auto_converge_eps)
    # Python version (1.2-3 times slower, but much more readable!)
    cntr = 0
    x_prev = None
    while True:
        f_obs_cmpl = f_obs.phase_transfer(phase_source=phase_source)
        A = []
        b = []
        for j, Fj in enumerate(F):
            A_rows = []
            for n, Fn in enumerate(F):
                Gjn = flex.real(Fj.data() * flex.conj(Fn.data()))
                A_rows.append(flex.sum(Gjn))
            Hj = flex.real(Fj.data() * flex.conj(f_obs_cmpl.data()))
            b.append(flex.sum(Hj))
            A.extend(A_rows)
        A = matrix.sqr(A)
        A_1 = A.inverse()
        b = matrix.col(b)
        x = A_1 * b
        #
        fc_d = flex.complex_double(phase_source.indices().size(), 0)
        for i, f in enumerate(F):
            fc_d += f.data() * x[i]
        phase_source = phase_source.customized_copy(data=fc_d)
        x_ = x[:]
        #
        cntr += 1
        if (cntr > max_cycles): break
        if (x_prev is None): x_prev = x_[:]
        else:
            max_diff = flex.max(
                flex.abs(flex.double(x_prev) - flex.double(x_)))
            if (max_diff <= auto_converge_eps): break
            x_prev = x_[:]
    return x_
Exemplo n.º 2
0
 def update_target_and_grads(self, x):
     self.x = x
     s = 1  #180/math.pi
     i_model = flex.double(self.i_obs.data().size(), 0)
     for n, kn in enumerate(self.x):
         for m, km in enumerate(self.x):
             tmp = self.F[n].data() * flex.conj(self.F[m].data())
             i_model += kn * km * flex.real(tmp)
             #pn = self.F[n].phases().data()*s
             #pm = self.F[m].phases().data()*s
             #Fn = flex.abs(self.F[n].data())
             #Fm = flex.abs(self.F[m].data())
             #i_model += kn*km*Fn*Fm*flex.cos(pn-pm)
     diff = i_model - self.i_obs.data()
     t = flex.sum(diff * diff) / 4
     #
     g = flex.double()
     for j in range(len(self.F)):
         tmp = flex.double(self.i_obs.data().size(), 0)
         for m, km in enumerate(self.x):
             tmp += km * flex.real(
                 self.F[j].data() * flex.conj(self.F[m].data()))
             #pj = self.F[j].phases().data()*s
             #pm = self.F[m].phases().data()*s
             #Fj = flex.abs(self.F[j].data())
             #Fm = flex.abs(self.F[m].data())
             #tmp += km * Fj*Fm*flex.cos(pj-pm)
         g.append(flex.sum(diff * tmp))
     self.t = t
     self.g = g
     #
     if self.use_curvatures:
         d = flex.double()
         for j in range(len(self.F)):
             tmp1 = flex.double(self.i_obs.data().size(), 0)
             tmp2 = flex.double(self.i_obs.data().size(), 0)
             for m, km in enumerate(self.x):
                 zz = flex.real(self.F[j].data() *
                                flex.conj(self.F[m].data()))
                 tmp1 += km * zz
                 tmp2 += zz
                 #pj = self.F[j].phases().data()*s
                 #pm = self.F[m].phases().data()*s
                 #Fj = flex.abs(self.F[j].data())
                 #Fm = flex.abs(self.F[m].data())
                 #tmp += km * Fj*Fm*flex.cos(pj-pm)
             d.append(flex.sum(tmp1 * tmp1 + tmp2))
         self.d = d
Exemplo n.º 3
0
 def update_target_and_grads(self, x):
     self.x = x
     self.tgo.update(self.x)
     self.t = self.tgo.target()
     self.g = self.tgo.gradient()
     #
     # Reference implementation in Python
     #    s = 1 #180/math.pi
     #    i_model = flex.double(self.i_obs.data().size(),0)
     #    for n, kn in enumerate(self.x):
     #      for m, km in enumerate(self.x):
     #        tmp = self.F[n].data()*flex.conj(self.F[m].data())
     #        i_model += kn*km*flex.real(tmp)
     #        #pn = self.F[n].phases().data()*s
     #        #pm = self.F[m].phases().data()*s
     #        #Fn = flex.abs(self.F[n].data())
     #        #Fm = flex.abs(self.F[m].data())
     #        #i_model += kn*km*Fn*Fm*flex.cos(pn-pm)
     #    diff = i_model - self.i_obs.data()
     #    #print (flex.min(diff), flex.max(diff))
     #    t = flex.sum(diff*diff)/4
     #    #
     #    g = flex.double()
     #    for j in range(len(self.F)):
     #      tmp = flex.double(self.i_obs.data().size(),0)
     #      for m, km in enumerate(self.x):
     #        tmp += km * flex.real( self.F[j].data()*flex.conj(self.F[m].data()) )
     #        #pj = self.F[j].phases().data()*s
     #        #pm = self.F[m].phases().data()*s
     #        #Fj = flex.abs(self.F[j].data())
     #        #Fm = flex.abs(self.F[m].data())
     #        #tmp += km * Fj*Fm*flex.cos(pj-pm)
     #      g.append(flex.sum(diff*tmp))
     #    self.t = t/self.sum_i_obs
     #    self.g = g/self.sum_i_obs
     #    #print (self.t,t1)
     #    #print (list(self.g))
     #    #print (list(g1))
     #    #print ()
     #    #assert approx_equal(self.t, t1, 5)
     #    #assert approx_equal(self.g, g1, 1.e-6)
     #
     if self.use_curvatures:
         d = flex.double()
         for j in range(len(self.F)):
             tmp1 = flex.double(self.i_obs.data().size(), 0)
             tmp2 = flex.double(self.i_obs.data().size(), 0)
             for m, km in enumerate(self.x):
                 zz = flex.real(self.F[j].data() *
                                flex.conj(self.F[m].data()))
                 tmp1 += km * zz
                 tmp2 += zz
                 #pj = self.F[j].phases().data()*s
                 #pm = self.F[m].phases().data()*s
                 #Fj = flex.abs(self.F[j].data())
                 #Fm = flex.abs(self.F[m].data())
                 #tmp += km * Fj*Fm*flex.cos(pj-pm)
             d.append(flex.sum(tmp1 * tmp1 + tmp2))
         self.d = d
Exemplo n.º 4
0
def algorithm_4(f_obs, F, max_cycles=100, auto_converge_eps=1.e-7):
    """
  Phased simultaneous search
  """
    fc, f_masks = F[0], F[1:]
    fc = fc.deep_copy()
    F = [fc] + F[1:]
    x_res = None
    cntr = 0
    x_prev = None
    while True:
        f_obs_cmpl = f_obs.phase_transfer(phase_source=fc)
        A = []
        b = []
        for j, Fj in enumerate(F):
            A_rows = []
            for n, Fn in enumerate(F):
                Gjn = flex.real(Fj.data() * flex.conj(Fn.data()))
                A_rows.append(flex.sum(Gjn))
            Hj = flex.real(Fj.data() * flex.conj(f_obs_cmpl.data()))
            b.append(flex.sum(Hj))
            A.extend(A_rows)
        A = matrix.sqr(A)
        A_1 = A.inverse()
        b = matrix.col(b)
        x = A_1 * b
        if x_res is None: x_res = flex.double(x)
        else: x_res += flex.double(x)
        x_ = [x[0]] + list(x_res[1:])
        #print "iteration:", cntr, " ".join(["%10.6f"%i for i in x_])
        #
        fc_d = fc.data()
        for i, f in enumerate(F):
            if i == 0: continue
            fc_d += x[i] * f.data()
        fc = fc.customized_copy(data=fc_d)
        cntr += 1
        if (cntr > max_cycles): break
        if (x_prev is None): x_prev = x_[:]
        else:
            max_diff = flex.max(
                flex.abs(flex.double(x_prev) - flex.double(x_)))
            if (max_diff <= auto_converge_eps): break
            x_prev = x_[:]
    return x_
Exemplo n.º 5
0
def algorithm_3(i_obs, fc, f_masks):
    """
  Unphased two-step search
  """
    F = [fc] + f_masks
    Gnm = []
    cs = {}
    cntr = 0
    nm = []
    # Compute and store Gnm
    for n, Fn in enumerate(F):
        for m, Fm in enumerate(F):
            if m < n:
                continue
            Gnm.append(flex.real(Fn.data() * flex.conj(Fm.data())))
            cs[(n, m)] = cntr
            cntr += 1
            nm.append((n, m))
    # Keep track of indices for "upper triangular matrix vs full"
    for k, v in zip(list(cs.keys()), list(cs.values())):
        i, j = k
        if i == j: continue
        else: cs[(j, i)] = v
    # Generate and solve system Ax=b, x = A_1*b
    A = []
    b = []
    for u, Gnm_u in enumerate(Gnm):
        for v, Gnm_v in enumerate(Gnm):
            scale = 2
            n, m = nm[v]
            if n == m: scale = 1
            A.append(flex.sum(Gnm_u * Gnm_v) * scale)
        b.append(flex.sum(Gnm_u * i_obs.data()))
    A = matrix.sqr(A)
    A_1 = A.inverse()
    b = matrix.col(b)
    x = A_1 * b
    # Expand Xmn from solution x
    Xmn = []
    for n, Fn in enumerate(F):
        rows = []
        for m, Fm in enumerate(F):
            x_ = x[cs[(n, m)]]
            rows.append(x_)
        Xmn.append(rows)
    # Do formula (19)
    lnK = []
    for j, Fj in enumerate(F):
        t1 = flex.sum(flex.log(flex.double(Xmn[j])))
        t2 = 0
        for n, Fn in enumerate(F):
            for m, Fm in enumerate(F):
                t2 += math.log(Xmn[n][m])
        t2 = t2 / (2 * len(F))
        lnK.append(1 / len(F) * (t1 - t2))
    return [math.exp(x) for x in lnK]