Exemplo n.º 1
0
    def __call__(self, x, y=None, observed=True, regularize=True):

        if x is y:
            symm=True
        else:
            symm=False

        # Remember shape of x, and then 'regularize' it.
        orig_shape = np.shape(x)
        if len(orig_shape)>1:
            orig_shape = orig_shape[:-1]

        if regularize:
            x=regularize_array(x)

        ndimx = x.shape[-1]
        lenx = x.shape[0]

        # Safety
        if self.ndim is not None:
            if not self.ndim == ndimx:
                raise ValueError, "The number of spatial dimensions of x, "+\
                                    ndimx.__str__()+\
                                    ", does not match the number of spatial dimensions of the Covariance instance's base mesh, "+\
                                    self.ndim.__str__()+"."


        # If there are observation points, prepare self(obs_mesh, x)
        # and chol(self(obs_mesh, obs_mesh)).T.I * self(obs_mesh, x)
        if self.observed and observed:
            Cxo = cvx_covariance(self.eval_fun, x, cutoff=self.cutoff, **self.params)
            Uo_Cxo = self.Uo_backsolver(Cxo)
            # Uo_Cxo = trisolve(self.Uo, Cxo, uplo='U', transa='T')


        # ==========================================================
        # = If only one argument is provided, return the diagonal. =
        # ==========================================================
        # See documentation.
        if y is None:

            V = diag_call(x=x, cov_fun = self.diag_cov_fun)
            for i in range(lenx):

                # Update return value using observations.
                if self.observed and observed:
                    V[i] -= Uo_Cxo[:,i].T*Uo_Cxo[:,i]

            return V.reshape(orig_shape)

        else:

            # ====================================================================
            # = If x and y are same np.array, return triangular-only sparse factor. =
            # ====================================================================
            if symm:

                C = cvx_covariance(self.eval_fun, x, cutoff=self.cutoff, **self.params)

                # Update return value using observations.
                if self.observed and observed:
                    C -= Uo_Cxo.T * Uo_Cxo
                return C


            # ======================================
            # = # If x and y are different np.arrays: =
            # ======================================
            else:

                if regularize:
                    y=regularize_array(y)

                ndimy = y.shape[-1]
                leny = y.shape[0]

                if not ndimx==ndimy:
                    raise ValueError, 'The last dimension of x and y (the number of spatial dimensions) must be the same.'

                C = cvx_covariance(self.eval_fun, x, y, cutoff=self.cutoff, **self.params)

                # Update return value using observations.
                if self.observed and observed:

                    # If there are observation points, prepare self(obs_mesh, y)
                    # and chol(self(obs_mesh, obs_mesh)).T.I * self(obs_mesh, y)
                    cvx_covariance(self.eval_fun, self.obs_mesh, y, cutoff=self.cutoff, **self.params)
                    Uo_Cyo = self.Uo_backsolver(Cyo.T)
                    # Uo_Cyo = trisolve(self.Uo, Cyo,uplo='U', transa='T')
                    # C -= Uo_Cxo.T * Uo_Cyo
                    C -= Uo_Cxo.T * Uo_Cyo.T

                return C
Exemplo n.º 2
0
def cvx_covariance(cov_fun, x, y=None, cutoff=1e-5, **params):
    """
    cvx_covariance(cov_fun, x, y=None cutoff=1e-5, **params)

    Returns a sparse version of cov_fun(x,y,**params).

    If y=None, returns a sparse (cxopt) version of the upper
    triangle of cov_fun(x,x, **params) with all elements less than or
    equal to cov_fun(x,x, **params).max() * cutoff set to 0 (left out
    of the nonzero structure).
    """

    m = x.shape[0]

    r_ind = []
    c_ind = []

    if y is None:
        n=m

        # Get the diagonal, to see what the largest element is, and scale the cutoff.
        bigdiag = diag_call(x=x, cov_fun = lambda xe: cov_fun(xe,xe,**params))
        C = cvx.base.spmatrix(bigdiag, range(m), range(m))
        maxval = bigdiag.max()
        cutoff = maxval * cutoff

        # Make sure you're passing np.arrays of the right dimensions into
        # cov_fun.
        if len(x.shape)>1:
            singleton_pt = np.zeros((1,x.shape[1]),dtype=float)
        else:
            singleton_pt = np.zeros(1,dtype=float)

        # Write in rows.
        for i in xrange(m):
            singleton_pt[:] = x[i,:]
            data_now = cov_fun(singleton_pt, x[i:,:], **params).view(np.ndarray).ravel()
            indices_now = np.where(data_now > cutoff)[0]
            for j in indices_now:
                C[i,j+i] = data_now[j]
                # C[j+i,i] = data_now[j]


    else:
        n=y.shape[0]
        C = cvx.base.spmatrix(0., range(m), range(n))

        # Make sure you're passing np.arrays of the right dimensions into
        # cov_fun.
        if len(y.shape)>1:
            singleton_pt = np.zeros((1,y.shape[1]),dtype=float)
        else:
            singleton_pt = np.zeros(1,dtype=float)

        for i in xrange(n):
            singleton_pt[:] = y[i,:]
            data_now = cov_fun(singleton_pt, x, **params).view(np.ndarray).ravel()
            indices_now = np.where(data_now > cutoff)[0]
            for j in indices_now:
                C[i,j] = data_now[j]

    return C