def predict_y(self, xq, sigma=None, k=None):
        """Provide a prediction of xq in the output space

        @param xq  an array of float of length dim_x
        @param estimated_sigma  if False (default), sigma_sq=self.sigma_sq, else it is estimated from the neighbor distances in self._weights(.)
        """
        assert len(xq) == self.dataset.dim_x
        sigma_sq = self.sigma_sq if sigma is None else sigma*sigma
        k = k or self.k

        dists, index = self.dataset.nn_x(xq, k=k)

        w = self._weights(dists, index, sigma_sq)
        Xq  = np.array(np.append([1.0], xq), ndmin = 2)
        X   = np.array([self.dataset.get_x_padded(i) for i in index])
        Y = np.array([self.dataset.get_y(i) for i in index])
        
        W   = np.diag(w)
        WX  = np.dot(W, X)
        WXT = WX.T

        B   = np.dot(np.linalg.pinv(np.dot(WXT, WX)),WXT)

        self.mat = np.dot(B, np.dot(W, Y))
        Yq  = np.dot(Xq, self.mat)

        return Yq.ravel()
Provide a prediction of xq in the output space

        @param xq  an array of float of length dim_x
        @param estimated_sigma  if False (default), sigma_sq=self.sigma_sq, else it is estimated from the neighbor distances in self._weights(.)