예제 #1
0
    def scales_and_derivatives(self, phi):
        """Calculate the overall scale factor at each position in 'phi' and the
    derivatives of that scale factor wrt all parameters of the model"""

        # obtain data from all scale factor components
        data = [f.get_factors_and_derivatives(phi) for f in self._factors]

        # FIXME only using phi at the moment. In future will need other information
        # such as s1 directions or central impacts, and will have to pass the right
        # bits of information to the right ScaleFactor components contained here
        scale_components, grad_components = zip(*data)

        # the overall scale is the product of the separate scale components
        overall_scale = reduce(lambda fac1, fac2: fac1 * fac2,
                               scale_components)

        # to convert derivatives of each scale component to derivatives of the
        # overall scale we multiply by the product of the other scale components,
        # omitting the factor that has been differentiated
        if len(scale_components) > 1:
            omit_one_prods = products_omitting_one_item(scale_components)

            grad_components = [row_multiply(g, coeff) for g, coeff in \
                               zip(grad_components, omit_one_prods)]

        # Now combine the gradient components by columns to produce a single
        # gradient matrix for the overall scale
        each_ncol = [g.n_cols for g in grad_components]
        tot_ncol = sum(each_ncol)
        grad = sparse.matrix(len(overall_scale), tot_ncol)
        col_start = [0] + each_ncol[:-1]
        for icol, g in zip(col_start, grad_components):
            grad.assign_block(g, 0, icol)

        return overall_scale, grad
예제 #2
0
  def scales_and_derivatives(self, phi):
    """Calculate the overall scale factor at each position in 'phi' and the
    derivatives of that scale factor wrt all parameters of the model"""

    # obtain data from all scale factor components
    data = [f.get_factors_and_derivatives(phi) for f in self._factors]

    # FIXME only using phi at the moment. In future will need other information
    # such as s1 directions or central impacts, and will have to pass the right
    # bits of information to the right ScaleFactor components contained here
    scale_components, grad_components = zip(*data)

    # the overall scale is the product of the separate scale components
    overall_scale = reduce(lambda fac1, fac2: fac1 * fac2, scale_components)

    # to convert derivatives of each scale component to derivatives of the
    # overall scale we multiply by the product of the other scale components,
    # omitting the factor that has been differentiated
    if len(scale_components) > 1:
      omit_one_prods = products_omitting_one_item(scale_components)

      grad_components = [row_multiply(g, coeff) for g, coeff in \
                         zip(grad_components, omit_one_prods)]

    # Now combine the gradient components by columns to produce a single
    # gradient matrix for the overall scale
    each_ncol = [g.n_cols for g in grad_components]
    tot_ncol = sum(each_ncol)
    grad = sparse.matrix(len(overall_scale), tot_ncol)
    col_start = [0] + each_ncol[:-1]
    for icol, g in zip(col_start, grad_components):
      grad.assign_block(g, 0, icol)

    return overall_scale, grad
예제 #3
0
def test_row_multiply():

    m = sparse.matrix(3, 2)
    m[0, 0] = 1.0
    m[0, 1] = 2.0
    m[1, 1] = 3.0
    m[2, 0] = 4.0

    fac = flex.double((3, 2, 1))

    m2 = row_multiply(m, fac)

    assert m2.as_dense_matrix().as_1d() == flex.double(
        [3.0, 6.0, 0.0, 6.0, 4.0, 0.0]).all_eq(True)
예제 #4
0
def test_row_multiply():

  m = sparse.matrix(3, 2)
  m[0,0] = 1.
  m[0,1] = 2.
  m[1,1] = 3.
  m[2,0] = 4.

  fac = flex.double((3, 2, 1))

  m2 = row_multiply(m, fac)

  assert m2.as_dense_matrix().as_1d() == flex.double(
    [3.0, 6.0, 0.0, 6.0, 4.0, 0.0]).all_eq(True)
  print "OK"
예제 #5
0
    def get_factors_and_derivatives(self, seq):
        """Calculate and return the smoothed values and their derivatives with
    respect to the underlying parameters for this scale factor component,
    for the reflections described by the values in seq. For example, these
    may be the phi rotation angle values for a scale factor component that is
    a function of phi."""

        # Obtain data from the smoother, where value and sumweight are arrays with
        # the same length as seq. Weight is a sparse matrix with one row per
        # element of seq. Each row has some (typically 3) non-zero values
        # corresponding to the positions nearest the element of seq.
        value, weight, sumweight = self._smoother.multi_value_weight(
            seq, self._param)

        # The gradient of a single smoothed value with respect to the parameters,
        # d[v]/d[p] = w_i * (1. / sum(w_i)), where the sum is over the parameters.
        # Calculate this for all values v.
        inv_sw = 1. / sumweight
        dv_dp = row_multiply(weight, inv_sw)

        return value, dv_dp
예제 #6
0
  def get_factors_and_derivatives(self, seq):
    """Calculate and return the smoothed values and their derivatives with
    respect to the underlying parameters for this scale factor component,
    for the reflections described by the values in seq. For example, these
    may be the phi rotation angle values for a scale factor component that is
    a function of phi."""

    # Obtain data from the smoother, where value and sumweight are arrays with
    # the same length as seq. Weight is a sparse matrix with one row per
    # element of seq. Each row has some (typically 3) non-zero values
    # corresponding to the positions nearest the element of seq.
    value, weight, sumweight = self._smoother.multi_value_weight(seq,
      self._param)

    # The gradient of a single smoothed value with respect to the parameters,
    # d[v]/d[p] = w_i * (1. / sum(w_i)), where the sum is over the parameters.
    # Calculate this for all values v.
    inv_sw = 1. / sumweight
    dv_dp = row_multiply(weight, inv_sw)

    return value, dv_dp