Esempio n. 1
0
    def get_Ainv(self):
        """Get the inverse of A"""

        # Already computed
        if hasattr(self, '_Ainv'):
            return self._Ainv

        # Variogram function
        vgf = self.variogram_func

        # Loop on clouds
        if not hasattr(self, '_dd'): self._dd = []
        Ainv = []
        AA = []
        next = int(not self._simple)
        for ic in xrange(self.ncloud):

            # Get distance between input points
            if len(self._dd) < ic + 1:
                dd = get_distances(self.xc[ic],
                                   self.yc[ic],
                                   self.xc[ic],
                                   self.yc[ic],
                                   mode=self.distfunc)
                self._dd.append(dd)
            else:
                dd = self._dd[ic]

            # Form A
            np = self.npc[ic]
            A = N.empty((np + next, np + next))
            A[:np, :np] = vgf(dd)
            if self.exact:
                N.fill_diagonal(A, 0)
                A[:np, :np][isclose(A[:np, :np], 0.)] = 0.
            if not self._simple:
                A[-1] = 1
                A[:, -1] = 1
                A[-1, -1] = 0

            # Invert for single cloud
            if self.nproc == 1:
                Ainv.append(syminv(A))
            else:
                AA.append(A)

        # Multiprocessing inversion
        if self.nproc > 1:
            pool = Pool(self.nproc)
            Ainv = pool.map(syminv, AA, chunksize=1)
            pool.close()

        # Fortran arrays
        Ainv = [N.asfortranarray(ainv, 'd') for ainv in Ainv]
        self.Ainv = Ainv
        return Ainv
Esempio n. 2
0
    def get_Ainv(self):
        """Get the inverse of A"""

        # Already computed
        if hasattr(self, '_Ainv'):
            return self._Ainv

        # Variogram function
        vgf = self.variogram_func

        # Loop on clouds
        if not hasattr(self, '_dd'): self._dd = []
        Ainv = []
        AA = []
        next = int(not self._simple)
        for ic in xrange(self.ncloud):

            # Get distance between input points
            if len(self._dd)<ic+1:
                dd = get_distances(self.xc[ic], self.yc[ic],
                    self.xc[ic], self.yc[ic], mode=self.distfunc)
                self._dd.append(dd)
            else:
                dd = self._dd[ic]

            # Form A
            np = self.npc[ic]
            A = N.empty((np+next, np+next))
            A[:np, :np] = vgf(dd)
            if self.exact:
                N.fill_diagonal(A, 0)
                A[:np, :np][isclose(A[:np, :np], 0.)] = 0.
            if not self._simple:
                A[-1] = 1
                A[:, -1] = 1
                A[-1, -1] = 0

            # Invert for single cloud
            if self.nproc==1:
                Ainv.append(syminv(A))
            else:
                AA.append(A)

        # Multiprocessing inversion
        if self.nproc>1:
            pool = Pool(self.nproc)
            Ainv = pool.map(syminv, AA, chunksize=1)
            pool.close()

        # Fortran arrays
        Ainv = [N.asfortranarray(ainv, 'd') for ainv in Ainv]
        self.Ainv = Ainv
        return Ainv
Esempio n. 3
0
    def get_Ainv(self):
        """Get the inverse of A"""

        # Already computed
        if hasattr(self, '_Ainv'):
            return self._Ainv

        # Variogram function
        vgf = self.variogram_func

        # Loop on clouds
        if not hasattr(self, '_dd'): self._dd = []
        Ainv = []
        AA = []
        for ic in xrange(self.ncloud):

            # Get distance between input points
            if len(self._dd)<ic+1:
                x0, x1 = N.meshgrid(self.xc[ic], self.xc[ic])
                y0, y1 = N.meshgrid(self.yc[ic], self.yc[ic])
                dd = (x1-x0)**2 ; del x0,x1
                dd += (y1-y0)**2 ; del y0,y1
                dd = N.sqrt(dd).astype('d')
                self._dd.append(dd)
            else:
                dd = self._dd[ic]

            # Form A
            A = N.empty((self.npc[ic]+1, self.npc[ic]+1))
            A[:-1, :-1] = vgf(dd)
            if self.exact:
                N.fill_diagonal(A, 0)
                A[:-1, :-1][isclose(A[:-1, :-1], 0.)] = 0.
            A[-1] = 1
            A[:, -1] = 1
            A[-1, -1] = 0

            # Invert for single cloud
            if self.nproc==1:
                Ainv.append(syminv(A))
            else:
                AA.append(A)

        # Multiprocessing inversion
        if self.nproc>1:
            Ainv = Pool(self.nproc).map(syminv, AA, chunksize=1)

        # Fortran arrays
        Ainv = [N.asfortranarray(ainv, 'd')for ainv in Ainv]
        self.Ainv = Ainv
        return Ainv
Esempio n. 4
0
    def interp(self, xo, yo, geterr=False, blockr=None):
        """Interpolate to positions xo,yo

        :Params:

            - **xo/yo**: Output positions.
            - **geterr**, optional: Also return errors.

        :Return: ``zo`` or ``zo,eo``
        """

        # Inits
        xo = N.asarray(xo, 'd')
        yo = N.asarray(yo, 'd')
        npo = xo.shape[0]
        vgf = self.variogram_func
        so = (self.nt, npo) if self.nt else npo
        zo = N.zeros(so, 'd')
        if geterr:
            eo = N.zeros(npo, 'd')
        if self.ncloud > 1 or geterr:
            wo = N.zeros(npo, 'd')

        # Loop on clouds
        Ainv = self.Ainv
        next = int(not self._simple)
        for ic in xrange(self.ncloud):  # TODO: multiproc here?

            # Distances to output points
            # dd = cdist(N.transpose([xi,yi]),N.transpose([xo,yo])) # TODO: test cdist
            dd = get_distances(xo,
                               yo,
                               self.xc[ic],
                               self.yc[ic],
                               mode=self.distfunc)

            # Form B
            np = self.npc[ic]
            B = N.empty((np + next, npo))
            B[:self.npc[ic]] = vgf(dd)
            if not self._simple:
                B[-1] = 1
            if self.exact:
                B[:np][isclose(B[:np], 0.)] = 0.
            del dd

            # Block kriging
            if blockr:
                tree = cKDTree(N.transpose([xo, yo]))
                Bb = B.copy()
                for i, iineigh in enumerate(tree.query_ball_tree(tree,
                                                                 blockr)):
                    Bb[:, i] = B[:, iineigh].mean()
                B = Bb

            # Compute weights
            W = N.ascontiguousarray(symm(Ainv[ic], N.asfortranarray(B, 'd')))

            # Simple kriging with adjusted mean for long distance values
            if self._simple and self.farvalue is not None:
                s = self.get_sill()
                Ais = self.get_sill() * Ainv[ic].sum(axis=0)
                mean = self.farvalue - (self.zc[ic] * Ais).sum()
                mean /= (1 - Ais.sum())
            else:
                mean = self.mean

            # Interpolate
            z = N.ascontiguousarray(
                dgemv(N.asfortranarray(W[:np].T, 'd'),
                      N.asfortranarray(self.zc[ic] - mean, 'd')))
            if self._simple:
                z += mean

            # Simplest case
            if not geterr and self.ncloud < 2:
                zo[:] = z.T
                continue

            # Get error


#            e = (W[:-1]*B[:-1]).sum(axis=0)
            e = (W * B).sum(axis=0)
            del W, B

            # Weigthed contribution based on errors
            w = 1 / e**2
            if self.ncloud > 1:
                z[:] *= w
            wo += w
            del w
            zo[:] += z.T
            del z

        # Error
        if geterr:
            eo = 1 / N.sqrt(wo)

        # Normalization
        if self.ncloud > 1:
            zo[:] /= wo

        gc.collect()
        if geterr: return zo, eo
        return zo
Esempio n. 5
0
    def interp(self, xo, yo, geterr=False, blockr=None):
        """Interpolate to positions xo,yo

        :Params:

            - **xo/yo**: Output positions.
            - **geterr**, optional: Also return errors.

        :Return: ``zo`` or ``zo,eo``
        """

        # Inits
        xo = N.asarray(xo, 'd')
        yo = N.asarray(yo, 'd')
        npo = xo.shape[0]
        vgf = self.variogram_func
        so = (self.nt, npo) if self.nt else npo
        zo = N.zeros(so, 'd')
        if geterr:
            eo = N.zeros(npo, 'd')
        if self.ncloud>1 or geterr:
            wo = N.zeros(npo, 'd')

        # Loop on clouds
        Ainv = self.Ainv
        next = int(not self._simple)
        for ic in xrange(self.ncloud): # TODO: multiproc here?

            # Distances to output points
            # dd = cdist(N.transpose([xi,yi]),N.transpose([xo,yo])) # TODO: test cdist
            dd = get_distances(xo, yo, self.xc[ic], self.yc[ic], mode=self.distfunc)

            # Form B
            np = self.npc[ic]
            B = N.empty((np+next, npo))
            B[:self.npc[ic]] = vgf(dd)
            if not self._simple:
                B[-1] = 1
            if self.exact:
                B[:np][isclose(B[:np], 0.)] = 0.
            del dd

            # Block kriging
            if blockr:
                tree = cKDTree(N.transpose([xo, yo]))
                Bb = B.copy()
                for i, iineigh in enumerate(tree.query_ball_tree(tree, blockr)):
                    Bb[:, i] = B[:, iineigh].mean()
                B = Bb

            # Compute weights
            W = N.ascontiguousarray(symm(Ainv[ic], N.asfortranarray(B, 'd')))

            # Simple kriging with adjusted mean for long distance values
            if self._simple and self.farvalue is not None:
                s = self.get_sill()
                Ais = self.get_sill() * Ainv[ic].sum(axis=0)
                mean = self.farvalue - (self.zc[ic] * Ais).sum()
                mean /= (1 - Ais.sum())
            else:
                mean = self.mean

            # Interpolate
            z = N.ascontiguousarray(dgemv(N.asfortranarray(W[:np].T, 'd'),
                N.asfortranarray(self.zc[ic]-mean, 'd')))
            if self._simple:
                z += mean

            # Simplest case
            if not geterr and self.ncloud<2:
                zo[:] = z.T
                continue

            # Get error
#            e = (W[:-1]*B[:-1]).sum(axis=0)
            e = (W*B).sum(axis=0)
            del W, B

            # Weigthed contribution based on errors
            w = 1/e**2
            if self.ncloud>1:
                z[:] *= w
            wo += w
            del w
            zo[:] += z.T ; del z

        # Error
        if geterr:
            eo = 1/N.sqrt(wo)

        # Normalization
        if self.ncloud>1:
            zo[:] /= wo

        gc.collect()
        if geterr: return zo, eo
        return zo
Esempio n. 6
0
    def interp(self, xo, yo, geterr=False, blockr=None):
        """Interpolate to positions xo,yo

        :Params:

            - **xo/yo**: Output positions.
            - **geterr**, optional: Also return errors.

        :Return: ``zo`` or ``zo,eo``
        """

        # Inits
        xo = N.asarray(xo, 'd')
        yo = N.asarray(yo, 'd')
        npo = xo.shape[0]
        vgf = self.variogram_func
        so = (self.nt, npo) if self.nt else npo
        zo = N.zeros(so, 'd')
        if geterr:
            eo = N.zeros(npo, 'd')
        if self.ncloud>1 or geterr:
            wo = N.zeros(npo, 'd')

        # Loop on clouds
        Ainv = self.Ainv
        for ic in xrange(self.ncloud): # TODO: multiproc here?

            # Distances to output points
            # dd = cdist(N.transpose([xi,yi]),N.transpose([xo,yo])) # TODO: test cdist
            xxo, xxi = N.meshgrid(xo, self.xc[ic])
            dd = (xxo-xxi)**2 ; del xxi, xxo
            yyo, yyi = N.meshgrid(yo, self.yc[ic])
            dd += (yyo-yyi)**2 ; del yyi, yyo
            dd = N.sqrt(dd)

            # Form B
            B = N.empty((self.npc[ic]+1, npo))
            B[-1] = 1
            B[:-1] = vgf(dd)
            if self.exact:
                B[:-1][isclose(B[:-1], 0.)] = 0.
            del dd

            # Block kriging
            if blockr:
                tree = cKDTree(N.transpose([xo, yo]))
                Bb = B.copy()
                for i, iineigh in enumerate(tree.query_ball_tree(tree, blockr)):
                    Bb[:, i] = B[:, iineigh].mean()
                B = Bb

            # Compute weights
            W = N.ascontiguousarray(symm(Ainv[ic], N.asfortranarray(B, 'd')))

            # Interpolate
            z = N.ascontiguousarray(dgemv(N.asfortranarray(W[:-1].T, 'd'),
                N.asfortranarray(self.zc[ic], 'd')))

            # Simplest case
            if not geterr and self.ncloud<2:
                zo[:] = z.T
                continue

            # Get error
#            e = (W[:-1]*B[:-1]).sum(axis=0)
            e = (W*B).sum(axis=0)
            del W, B

            # Weigthed contribution based on errors
            w = 1/e**2
            if self.ncloud>1:
                z[:] *= w
            wo += w
            del w
            zo[:] += z.T ; del z

        # Error
        if geterr:
            eo = 1/N.sqrt(wo)

        # Normalization
        if self.ncloud>1:
            zo[:] /= wo

        gc.collect()
        if geterr: return zo, eo
        return zo