예제 #1
0
def transport_plan_projections_transpose(im,
                                         supp,
                                         neighbors_graph,
                                         weights_neighbors,
                                         spectrum=None,
                                         indices=None):
    """ Adjoint operator to :func:`transport_plan_projections` 
    
    """
    from numpy import zeros, squeeze, sqrt, add, repeat

    shap = im.shape
    if indices is None:
        nb_proj = neighbors_graph.shape[3]
        indices = arange(0, nb_proj)
    else:
        nb_proj = size(indices)
    if spectrum is None:
        spectrum = ones((nb_proj, ))
    P_out = zeros((shap[0] * shap[1], shap[0] * shap[1], nb_proj))
    siz_supp = neighbors_graph.shape[0]
    indx = repeat(supp[:, 0], 4).reshape((siz_supp, 4))
    indy = repeat(supp[:, 1], 4).reshape((siz_supp, 4))

    for i in range(0, nb_proj):
        add.at(P_out[:,:,indices[i]],(indx,indy),spectrum[indices[i]]*weights_neighbors[:,:,indices[i]]\
                                *im[neighbors_graph[:,0,:,indices[i]],neighbors_graph[:,1,:,indices[i]]])
    return squeeze(P_out)
예제 #2
0
def transport_plan_projections(P,
                               shap,
                               supp,
                               neighbors_graph,
                               weights_neighbors,
                               spectrum=None,
                               indices=None):
    """ Computes monochromatic components (displacement interpolation steps) from transport plan.
    
    """
    from numpy import zeros, int, squeeze, add, ones

    if indices is None:
        nb_proj = neighbors_graph.shape[3]
        indices = arange(0, nb_proj)
    else:
        nb_proj = size(indices)
    if spectrum is None:
        spectrum = ones((nb_proj, ))
    im_proj = zeros((shap[0], shap[1], nb_proj))
    siz_supp = neighbors_graph.shape[0]
    for i in range(0, nb_proj):
        add.at(im_proj[:,:,indices[i]],(neighbors_graph[:,0,:,indices[i]],neighbors_graph[:,1,:,indices[i]]),\
        spectrum[indices[i]]*weights_neighbors[:,:,indices[i]]*P[supp[:,0],supp[:,1]].reshape((siz_supp,1)).dot(ones((1,4))))

    return squeeze(im_proj)
예제 #3
0
def transport_plan_projections_transpose_2(im_stack,supp,neighbors_graph,weights_neighbors,spectrum):
    """ Computes the adjoint operator of the displacement inteerpolation for a
    given transport plan."""
    from numpy import zeros,squeeze,sqrt,add,repeat
    shap = im_stack.shape
    nb_proj = neighbors_graph.shape[3]
    P_out = zeros((shap[0]*shap[1],shap[0]*shap[1],nb_proj))
    siz_supp = neighbors_graph.shape[0]
    indx = repeat(supp[:,0],4).reshape((siz_supp,4))
    indy = repeat(supp[:,1],4).reshape((siz_supp,4))

    for i in range(0,nb_proj):
        add.at(P_out[:,:,i],(indx,indy),spectrum[i]*weights_neighbors[:,:,i]*im_stack[neighbors_graph[:,0,:,i],neighbors_graph[:,1,:,i],i])
    return P_out
예제 #4
0
    def backward(self, idx: int, accum_grad: Function.T) -> Function.T:
        ''' Method which turns the column shaped input to image shape
        '''

        # Create images placeholder
        images = zeros(self.children[0].shape)

        # Separate the image sections and the batch_size (shape[0])
        separated_grad = accum_grad\
            .reshape(self._n_features, -1, images.shape[0])\
            .transpose(2, 0, 1)  # Move the batch_size at the beginning

        # Fill in the placeholder
        k, i, j = self._im2col_indices
        add.at(images, (slice(None), k, i, j), separated_grad)

        return images
예제 #5
0
def transport_plan_projections_transpose_2(im_stack, supp, neighbors_graph,
                                           weights_neighbors, spectrum):
    """ Computes the adjoint operator of the displacement inteerpolation for a
    given transport plan."""
    from numpy import zeros, squeeze, sqrt, add, repeat
    shap = im_stack.shape
    nb_proj = neighbors_graph.shape[3]
    P_out = zeros((shap[0] * shap[1], shap[0] * shap[1], nb_proj))
    siz_supp = neighbors_graph.shape[0]
    indx = repeat(supp[:, 0], 4).reshape((siz_supp, 4))
    indy = repeat(supp[:, 1], 4).reshape((siz_supp, 4))

    for i in range(0, nb_proj):
        add.at(
            P_out[:, :,
                  i], (indx, indy), spectrum[i] * weights_neighbors[:, :, i] *
            im_stack[neighbors_graph[:, 0, :, i], neighbors_graph[:, 1, :, i],
                     i])
    return P_out
예제 #6
0
def transport_plan_projections(P,shap,supp,neighbors_graph,weights_neighbors,spectrum=None,indices=None):
    """ Computes monochromatic components (displacement interpolation steps) from transport plan.
    
    """
    from numpy import zeros,int,squeeze,add,ones

    if indices is None:
        nb_proj = neighbors_graph.shape[3]
        indices = arange(0,nb_proj)
    else:
        nb_proj = size(indices)
    if spectrum is None:
        spectrum = ones((nb_proj,))
    im_proj = zeros((shap[0],shap[1],nb_proj))
    siz_supp = neighbors_graph.shape[0]
    for i in range(0,nb_proj):
        add.at(im_proj[:,:,indices[i]],(neighbors_graph[:,0,:,indices[i]],neighbors_graph[:,1,:,indices[i]]),\
        spectrum[indices[i]]*weights_neighbors[:,:,indices[i]]*P[supp[:,0],supp[:,1]].reshape((siz_supp,1)).dot(ones((1,4))))

    return squeeze(im_proj)
예제 #7
0
def transport_plan_projections_transpose(im,supp,neighbors_graph,weights_neighbors,spectrum=None,indices=None):
    """ Adjoint operator to :func:`transport_plan_projections` 
    
    """
    from numpy import zeros,squeeze,sqrt,add,repeat

    shap = im.shape
    if indices is None:
        nb_proj = neighbors_graph.shape[3]
        indices = arange(0,nb_proj)
    else:
        nb_proj = size(indices)
    if spectrum is None:
        spectrum = ones((nb_proj,))
    P_out = zeros((shap[0]*shap[1],shap[0]*shap[1],nb_proj))
    siz_supp = neighbors_graph.shape[0]
    indx = repeat(supp[:,0],4).reshape((siz_supp,4))
    indy = repeat(supp[:,1],4).reshape((siz_supp,4))

    for i in range(0,nb_proj):
        add.at(P_out[:,:,indices[i]],(indx,indy),spectrum[indices[i]]*weights_neighbors[:,:,indices[i]]\
                                *im[neighbors_graph[:,0,:,indices[i]],neighbors_graph[:,1,:,indices[i]]])
    return squeeze(P_out)
예제 #8
0
def sample(bins, time, value):
    """
    Given value[i] was observed at time[i],
    group them into bins i.e.,
    *(bins[j], bins[j+1], ...)*

    Values for bin j are equal to the
    average of all value[k] and,
    bin[j] <= time[k] < bin[j+1].

    __Arguments__
    bins: _np.array_
        Endpoints of the bins.
        For n bins it shall be of length n + 1.
    t: _np.array_
        Times at which the values are observed.
    vt: _np.array_
        Values for those times.

    __Returns__
    x: _np.array_
        Endspoints of all the bins.
    y: _np.array_
        Average values in all bins.
    """
    bin_idx = np_digitize(time, bins) - 1
    value_sums = np_zeros(shape=len(bins) - 1, dtype=np_float32)
    value_cnts = np_zeros(shape=len(bins) - 1, dtype=np_float32)
    np_add.at(value_sums, bin_idx, value)
    np_add.at(value_cnts, bin_idx, 1)
    # ensure graph has no holes
    zeros = np_where(value_cnts == 0)
    assert value_cnts[0] > 0
    for z in zeros:
        value_sums[z] = value_sums[z - 1]
        value_cnts[z] = value_cnts[z - 1]
    return bins[1:], value_sums / value_cnts
예제 #9
0
    def train_document_dm_concat(model, doc_words, doctag_indexes, alpha, work=None, neu1=None,
                                 learn_doctags=True, learn_words=True, learn_hidden=True,
                                 word_vectors=None, word_locks=None, doctag_vectors=None, doctag_locks=None):
        """
        Update distributed memory model ("PV-DM") by training on a single document, using a
        concatenation of the context window word vectors (rather than a sum or average).

        Called internally from `Doc2Vec.train()` and `Doc2Vec.infer_vector()`.

        The document is provided as `doc_words`, a list of word tokens which are looked up
        in the model's vocab dictionary, and `doctag_indexes`, which provide indexes
        into the doctag_vectors array.

        Any of `learn_doctags', `learn_words`, and `learn_hidden` may be set False to
        prevent learning-updates to those respective model weights, as if using the
        (partially-)frozen model to infer other compatible vectors.

        This is the non-optimized, Python version. If you have a C compiler, gensim
        will use the optimized version from doc2vec_inner instead.

        """
        if word_vectors is None:
            word_vectors = model.syn0
        if word_locks is None:
            word_locks = model.syn0_lockf
        if doctag_vectors is None:
            doctag_vectors = model.docvecs.doctag_syn0
        if doctag_locks is None:
            doctag_locks = model.docvecs.doctag_syn0_lockf

        word_vocabs = [model.vocab[w] for w in doc_words if w in model.vocab and
                       model.vocab[w].sample_int > model.random.rand() * 2**32]
        doctag_len = len(doctag_indexes)
        if doctag_len != model.dm_tag_count:
            return 0  # skip doc without expected number of doctag(s) (TODO: warn/pad?)

        null_word = model.vocab['\0']
        pre_pad_count = model.window
        post_pad_count = model.window
        padded_document_indexes = (
            (pre_pad_count * [null_word.index])  # pre-padding
            + [word.index for word in word_vocabs if word is not None]  # elide out-of-Vocabulary words
            + (post_pad_count * [null_word.index])  # post-padding
        )

        for pos in range(pre_pad_count, len(padded_document_indexes) - post_pad_count):
            word_context_indexes = (
                padded_document_indexes[(pos - pre_pad_count): pos]  # preceding words
                + padded_document_indexes[(pos + 1):(pos + 1 + post_pad_count)]  # following words
            )
            word_context_len = len(word_context_indexes)
            predict_word = model.vocab[model.index2word[padded_document_indexes[pos]]]
            # numpy advanced-indexing copies; concatenate, flatten to 1d
            l1 = concatenate((doctag_vectors[doctag_indexes], word_vectors[word_context_indexes])).ravel()
            neu1e = train_cbow_pair(model, predict_word, None, l1, alpha,
                                    learn_hidden=learn_hidden, learn_vectors=False)

            # filter by locks and shape for addition to source vectors
            e_locks = concatenate((doctag_locks[doctag_indexes], word_locks[word_context_indexes]))
            neu1e_r = (neu1e.reshape(-1, model.vector_size)
                       * np_repeat(e_locks, model.vector_size).reshape(-1, model.vector_size))

            if learn_doctags:
                np_add.at(doctag_vectors, doctag_indexes, neu1e_r[:doctag_len])
            if learn_words:
                np_add.at(word_vectors, word_context_indexes, neu1e_r[doctag_len:])

        return len(padded_document_indexes) - pre_pad_count - post_pad_count
예제 #10
0
    def orbital_momentum(self, projection='orbital', method='onsite'):
        r""" Calculate orbital angular momentum on either atoms or orbitals

        Currently this implementation equals the Siesta implementation in that
        the on-site approximation is enforced thus limiting the calculated quantities
        to obey the following conditions:

        1. Same atom
        2. :math:`l>0`
        3. :math:`l_\nu \equiv l_\mu`
        4. :math:`m_\nu \neq m_\mu`
        5. :math:`\zeta_\nu \equiv \zeta_\mu`

        This allows one to sum the orbital angular moments on a per atom site.

        Parameters
        ----------
        projection : {'orbital', 'atom'}
            whether the angular momentum is resolved per atom, or per orbital
        method : {'onsite'}
            method used to calculate the angular momentum

        Returns
        -------
        numpy.ndarray
            orbital angular momentum with the last dimension equalling the :math:`L_x`, :math:`L_y` and :math:`L_z` components
        """
        # Check that the spin configuration is correct
        if not self.spin.is_spinorbit:
            raise ValueError(
                f"{self.__class__.__name__}.orbital_momentum requires a spin-orbit matrix"
            )

        # First we calculate
        orb_lmZ = _a.emptyi([self.no, 3])
        for atom, idx in self.geometry.atoms.iter(True):
            # convert to FIRST orbital index per atom
            oidx = self.geometry.a2o(idx)
            # loop orbitals
            for io, orb in enumerate(atom):
                orb_lmZ[oidx + io, :] = orb.l, orb.m, orb.Z

        # Now we need to calculate the stuff
        DM = self.copy()
        # The Siesta convention *only* calculates contributions
        # in the primary unit-cell.
        DM.set_nsc([1] * 3)
        geom = DM.geometry
        csr = DM._csr

        # The siesta moments are only *on-site* per atom.
        # 1. create a logical index for the matrix elements
        #    that is true for ia-ia interaction and false
        #    otherwise
        idx = repeat(_a.arangei(geom.no), csr.ncol)
        aidx = geom.o2a(idx)

        # Sparse matrix indices for data
        sidx = array_arange(csr.ptr[:-1], n=csr.ncol, dtype=np.int32)
        jdx = csr.col[sidx]
        ajdx = geom.o2a(jdx)

        # Now only take the elements that are *on-site* and which are *not*
        # having the same m quantum numbers (if the orbital index is the same
        # it means they have the same m quantum number)
        #
        # 1. on the same atom
        # 2. l > 0
        # 3. same quantum number l
        # 4. different quantum number m
        # 5. same zeta
        onsite_idx = ((aidx == ajdx) & \
                      (orb_lmZ[idx, 0] > 0) & \
                      (orb_lmZ[idx, 0] == orb_lmZ[jdx, 0]) & \
                      (orb_lmZ[idx, 1] != orb_lmZ[jdx, 1]) & \
                      (orb_lmZ[idx, 2] == orb_lmZ[jdx, 2])).nonzero()[0]
        # clean variables we don't need
        del aidx, ajdx

        # Now reduce arrays to the orbital connections that obey the
        # above criteria
        idx = idx[onsite_idx]
        idx_l = orb_lmZ[idx, 0]
        idx_m = orb_lmZ[idx, 1]
        jdx = jdx[onsite_idx]
        jdx_m = orb_lmZ[jdx, 1]
        sidx = sidx[onsite_idx]

        # Sum the spin-box diagonal imaginary parts
        DM = csr._D[sidx][:, [4, 5]].sum(1)

        # Define functions to calculate L projections
        def La(idx_l, DM, sub):
            if len(sub) == 0:
                return []
            return (idx_l[sub] * (idx_l[sub] + 1) * 0.5)**0.5 * DM[sub]

        def Lb(idx_l, DM, sub):
            if len(sub) == 0:
                return
            return (idx_l[sub] * (idx_l[sub] + 1) - 2)**0.5 * 0.5 * DM[sub]

        def Lc(idx, idx_l, DM, sub):
            if len(sub) == 0:
                return [], []
            sub = sub[idx_l[sub] >= 3]
            if len(sub) == 0:
                return [], []
            return idx[sub], (idx_l[sub] *
                              (idx_l[sub] + 1) - 6)**0.5 * 0.5 * DM[sub]

        # construct for different m
        # in Siesta the spin orbital angular momentum
        # is calculated by swapping i and j indices.
        # This is somewhat confusing to me, so I reversed everything.
        # This will probably add to the confusion when comparing the two
        # Additionally Siesta calculates L for <i|L|j> and then does:
        #    L(:) = [L(3), -L(2), -L(1)]
        # Here we *directly* store the quantities used.
        # Pre-allocate the L_xyz quantity per orbital.
        L = np.zeros([geom.no, 3])
        L0 = L[:, 0]
        L1 = L[:, 1]
        L2 = L[:, 2]

        # Pre-calculate all those which have m_i + m_j == 0
        b = (idx_m + jdx_m == 0).nonzero()[0]
        subtract.at(L2, idx[b], idx_m[b] * DM[b])
        del b

        #   mi == 0
        i_m = idx_m == 0
        #     mj == -1
        sub = logical_and(i_m, jdx_m == -1).nonzero()[0]
        subtract.at(L0, idx[sub], La(idx_l, DM, sub))
        #     mj == 1
        sub = logical_and(i_m, jdx_m == 1).nonzero()[0]
        add.at(L1, idx[sub], La(idx_l, DM, sub))

        #   mi == 1
        i_m = idx_m == 1
        #     mj == -2
        sub = logical_and(i_m, jdx_m == -2).nonzero()[0]
        subtract.at(L0, idx[sub], Lb(idx_l, DM, sub))
        #     mj == 0
        sub = logical_and(i_m, jdx_m == 0).nonzero()[0]
        subtract.at(L1, idx[sub], La(idx_l, DM, sub))
        #     mj == 2
        sub = logical_and(i_m, jdx_m == 2).nonzero()[0]
        add.at(L1, idx[sub], Lb(idx_l, DM, sub))

        #   mi == -1
        i_m = idx_m == -1
        #     mj == -2
        sub = logical_and(i_m, jdx_m == -2).nonzero()[0]
        add.at(L1, idx[sub], Lb(idx_l, DM, sub))
        #     mj == 0
        sub = logical_and(i_m, jdx_m == 0).nonzero()[0]
        add.at(L0, idx[sub], La(idx_l, DM, sub))
        #     mj == 2
        sub = logical_and(i_m, jdx_m == 2).nonzero()[0]
        add.at(L0, idx[sub], Lb(idx_l, DM, sub))

        #   mi == 2
        i_m = idx_m == 2
        #     mj == -3
        sub = logical_and(i_m, jdx_m == -3).nonzero()[0]
        subtract.at(L0, *Lc(idx, idx_l, DM, sub))
        #     mj == -1
        sub = logical_and(i_m, jdx_m == -1).nonzero()[0]
        subtract.at(L0, idx[sub], Lb(idx_l, DM, sub))
        #     mj == 1
        sub = logical_and(i_m, jdx_m == 1).nonzero()[0]
        subtract.at(L1, idx[sub], Lb(idx_l, DM, sub))
        #     mj == 3
        sub = logical_and(i_m, jdx_m == 3).nonzero()[0]
        add.at(L1, *Lc(idx, idx_l, DM, sub))

        #   mi == -2
        i_m = idx_m == -2
        #     mj == -3
        sub = logical_and(i_m, jdx_m == -3).nonzero()[0]
        add.at(L1, *Lc(idx, idx_l, DM, sub))
        #     mj == -1
        sub = logical_and(i_m, jdx_m == -1).nonzero()[0]
        subtract.at(L1, idx[sub], Lb(idx_l, DM, sub))
        #     mj == 1
        sub = logical_and(i_m, jdx_m == 1).nonzero()[0]
        add.at(L0, idx[sub], Lb(idx_l, DM, sub))
        #     mj == 3
        sub = logical_and(i_m, jdx_m == 3).nonzero()[0]
        add.at(L0, *Lc(idx, idx_l, DM, sub))

        #   mi == -3
        i_m = idx_m == -3
        #     mj == -2
        sub = logical_and(i_m, jdx_m == -2).nonzero()[0]
        subtract.at(L1, *Lc(idx, idx_l, DM, sub))
        #     mj == 2
        sub = logical_and(i_m, jdx_m == 2).nonzero()[0]
        add.at(L0, *Lc(idx, idx_l, DM, sub))

        #   mi == 3
        i_m = idx_m == 3
        #     mj == -2
        sub = logical_and(i_m, jdx_m == -2).nonzero()[0]
        subtract.at(L0, *Lc(idx, idx_l, DM, sub))
        #     mj == 2
        sub = logical_and(i_m, jdx_m == 2).nonzero()[0]
        subtract.at(L1, *Lc(idx, idx_l, DM, sub))

        if "orbital" == projection:
            return L
        elif "atom" == projection:
            # Now perform summation per atom
            l = np.zeros([geom.na, 3], dtype=L.dtype)
            add.at(l, geom.o2a(np.arange(geom.no)), L)
            return l
        raise ValueError(
            f"{self.__class__.__name__}.orbital_momentum must define projection to be 'orbital' or 'atom'."
        )