Exemplo n.º 1
0
def l1_cross_distances(X):
    """
    Computes the nonzero componentwise L1 cross-distances between the vectors
    in X.

    Parameters
    ----------

    X: array_like
        An array with shape (n_samples, n_features)

    Returns
    -------
    D: array with shape (n_samples * (n_samples - 1) / 2, n_features)
        The array of componentwise L1 cross-distances.

    ij: arrays with shape (n_samples * (n_samples - 1) / 2, 2)
        The indices i and j of the vectors in X associated to the cross-
        distances in D: D[k] = np.abs(X[ij[k, 0]] - Y[ij[k, 1]]).
    """
    X = sk_utils.array2d(X)
    n_samples, n_features = X.shape
    n_nonzero_cross_dist = n_samples * (n_samples - 1) // 2
    ij = np.zeros((n_nonzero_cross_dist, 2), dtype=np.int)
    D = np.zeros((n_nonzero_cross_dist, n_features))
    ll_1 = 0
    for k in range(n_samples - 1):
        ll_0 = ll_1
        ll_1 = ll_0 + n_samples - k - 1
        ij[ll_0:ll_1, 0] = k
        ij[ll_0:ll_1, 1] = np.arange(k + 1, n_samples)
        D[ll_0:ll_1] = np.abs(X[k] - X[(k + 1):n_samples])

    return D, ij
Exemplo n.º 2
0
    def predict(self,
                X,
                eval_MSE=False,
                transformY=True,
                returnRV=False,
                integratedPrediction=False,
                eval_confidence_bounds=False,
                coef_bound=1.96,
                batch_size=None):
        """
		This function evaluates the Gaussian Process model at x.  

		Parameters
		----------
		`X` : array_like  
			An array with shape (n_eval, n_features) giving the point(s) at
			which the prediction(s) should be made.  

		`eval_MSE` : boolean, optional  
			A boolean specifying whether the Mean Squared Error should be
			evaluated or not.  
			Default assumes evalMSE = False and evaluates only the BLUP (mean
			prediction).  

		`transformY` : boolean, optional  
			A boolean specifying if the predicted values should correspond to
			the same space as the data given to the fit method, or to the
			warped space (in which the GP is fitted).
			Default is True. Setting to False can be useful to compute the Expected
			Improvement in an optimization process.  

		`returnRV` : boolean, optional  
			A boolean specifying if the method should return the predicted random variables
			at x instead of a float number.  
			Default is False.  

		`integratedPrediction` : boolean, optional  
			A boolean specifying if the method should return the fully Bayesian
			prediction, ie compute the expectation given the posterior in the
			original space. If False, the returned value is the inverse value
			(by the mapping function) of the GP prediction. This is much more faster
			as the integratedPrediction needs to numerically compute the integral.
			Default is False.  

		`eval_confidence_bounds` : boolean, optional  
			A boolean specifying if the method should return the confidence bounds.
			Because of the non-linearity of the mapping function, this cannot be computed
			directly with the MSE, but needs to invert the mapping function.  
			Default is False. If True, coef_bound specifies the boundary to compute.  

		`coef_bound` : float, optional  
			A float specifying the confidence bounds to compute. Upper and lower
			confidence bounds are computed as the inverse of m + coef_bound*sigma
			where m and sigma are the mean and the std of the posterior in the GP
			space.  
			Default is 1.96 which corresponds to the 95% confidence bounds.  

		`batch_size` : integer, optional  
			An integer giving the maximum number of points that can be
			evaluated simultaneously (depending on the available memory).
			Default is None so that all given points are evaluated at the same
			time.  

		Returns
		-------
		`y` : array_like, shape (n_samples,)  
			Prediction at x.

		`MSE` : array_like, optional (if eval_MSE == True)  
			Mean Squared Error at x.

		`LCB` : array_like, optional (if eval_confidence_bounds == True)  
			Lower confidence bound.

		`UCB` : array_like, optional (if eval_confidence_bounds == True)  
			Upper confidence bound.
		"""

        # Check input shapes
        X = sk_utils.array2d(X)
        n_eval, _ = X.shape
        n_samples, n_features = self.X.shape
        n_samples_y, n_targets = self.y.shape

        if (n_targets > 1):
            raise ValueError('More than one target in the Y outputs. \
							  Currently only 1D outputs are handled')

        # Run input checks
        self._check_params(n_samples)

        if X.shape[1] != n_features:
            raise ValueError(("The number of features in X (X.shape[1] = %d) "
                              "should match the number of features used "
                              "for fit() "
                              "which is %d.") % (X.shape[1], n_features))

        # Normalize input
        if self.normalize:
            X = (X - self.X_mean) / self.X_std

        # Initialize output
        y = np.zeros(n_eval)
        if eval_MSE:
            MSE = np.zeros(n_eval)

        # Get pairwise componentwise L1-distances to the input training set
        dx = manhattan_distances(X, Y=self.X, sum_over_features=False)
        # Get regression function and correlation
        f = self.regr(X)
        r = self.corr(self.theta, dx).reshape(n_eval, n_samples)

        # Scaled predictor
        y_ = np.dot(f, self.beta) + np.dot(r, self.gamma)

        # Predictor
        y = (self.y_mean + self.y_std * y_).reshape(n_eval, n_targets)

        # transform the warped y, modeled as a Gaussian, to the real y
        size = y.shape[0]
        warped_y = np.copy(y)

        if (transformY):
            if (np.sum([y[i][0] > 8.2 for i in range(size)]) > 0):
                print('Warning : mapping_inversion failed')
            real_y = [self.mapping_inv(X[i], y[i][0]) for i in range(size)]
            real_y = self.raw_y_std * np.asarray(real_y) + self.raw_y_mean
            y = real_y.reshape(n_eval, n_targets)

        if self.y_ndim_ == 1:
            y = y.ravel()
            warped_y = warped_y.ravel()

        # Mean Squared Error
        if eval_MSE:
            C = self.C
            if C is None:
                # Light storage mode (need to recompute C, F, Ft and G)
                if self.verbose:
                    print("This GaussianProcess used 'light' storage mode "
                          "at instantiation. Need to recompute "
                          "autocorrelation matrix...")
                reduced_likelihood_function_value, par = \
                 self.reduced_likelihood_function()
                self.C = par['C']
                self.Ft = par['Ft']
                self.G = par['G']

            rt = linalg.solve_triangular(self.C, r.T, lower=True)

            if self.beta0 is None:
                # Universal Kriging
                u = linalg.solve_triangular(self.G.T,
                                            np.dot(self.Ft.T, rt) - f.T)
            else:
                # Ordinary Kriging
                u = np.zeros((n_targets, n_eval))

            MSE = np.dot(self.sigma2.reshape(n_targets, 1),
                         (1. - (rt**2.).sum(axis=0) +
                          (u**2.).sum(axis=0))[np.newaxis, :])
            MSE = np.sqrt((MSE**2.).sum(axis=0) / n_targets)

            # Mean Squared Error might be slightly negative depending on
            # machine precision: force to zero!
            MSE[MSE < 0.] = 0.

            if self.y_ndim_ == 1:
                MSE = MSE.ravel()
                sigma = np.sqrt(MSE)
                if (returnRV):
                    return [
                        self.predicted_RV([warped_y[i]], sigma[i], X[i])
                        for i in range(size)
                    ]
                else:
                    if (eval_confidence_bounds):
                        if not (transformY):
                            print(
                                'Warning, transformY set to False but trying to evaluate conf bounds'
                            )
                        warped_y_with_boundL = warped_y - coef_bound * sigma
                        warped_y_with_boundU = warped_y + coef_bound * sigma
                        pred_with_boundL = self.raw_y_std * np.asarray([
                            self.mapping_inv(X[i], warped_y_with_boundL[i])[0]
                            for i in range(size)
                        ]) + self.raw_y_mean
                        pred_with_boundU = self.raw_y_std * np.asarray([
                            self.mapping_inv(X[i], warped_y_with_boundU[i])[0]
                            for i in range(size)
                        ]) + self.raw_y_mean

                        if (integratedPrediction):
                            lb = self.raw_y_min - 3. * (self.raw_y_max -
                                                        self.raw_y_min)
                            ub = self.raw_y_max + 3. * (self.raw_y_max -
                                                        self.raw_y_min)
                            print(lb, ub)
                            integrated_real_y = [
                                self.integrate_prediction([warped_y[i]],
                                                          sigma[i], X[i], lb,
                                                          ub)
                                for i in range(size)
                            ]
                            integrated_real_y = np.asarray(integrated_real_y)
                            print('Integrated prediction')
                            return integrated_real_y, MSE, pred_with_boundL, pred_with_boundU

                        else:
                            return y, MSE, pred_with_boundL, pred_with_boundU

                    else:
                        return y, MSE

            else:
                return y, MSE

        else:
            return y
Exemplo n.º 3
0
	def predict(self, X, eval_MSE=False, transformY=True, returnRV=False, integratedPrediction= False, eval_confidence_bounds=False,coef_bound=1.96, batch_size=None):
		"""
		This function evaluates the Gaussian Process model at x.

		Parameters
		----------
		X : array_like
			An array with shape (n_eval, n_features) giving the point(s) at
			which the prediction(s) should be made.

		eval_MSE : boolean, optional
			A boolean specifying whether the Mean Squared Error should be
			evaluated or not.
			Default assumes evalMSE = False and evaluates only the BLUP (mean
			prediction).

		transformY : boolean, optional
			A boolean specifying if the predicted values should correspond to
			the same space as the data given to the fit method, or to the
			warped space (in which the GP is fitted).
			Default is True. Setting to False can be useful to compute the Expected
			Improvement in an optimization process.

		returnRV : boolean, optional
			A boolean specifying if the method should return the predicted random variables
			at x instead of a float number.
			Default is False.

		integratedPrediction : boolean, optional
			A boolean specifying if the method should return the fully Bayesian
			prediction, ie compute the expectation given the posterior in the
			original space. If False, the returned value is the inverse value
			(by the mapping function) of the GP prediction. This is much more faster
			as the integratedPrediction needs to numerically compute the integral.
			Default is False.

		eval_confidence_bounds : boolean, optional
			A boolean specifying if the method should return the confidence bounds.
			Because of the non-linearity of the mapping function, this cannot be computed
			directly with the MSE, but needs to invert the mapping function.
			Default is False. If True, coef_bound specifies the boundary to compute.

		coef_bound : float, optional
			A float specifying the confidence bounds to compute. Upper and lower
			confidence bounds are computed as the inverse of m + coef_bound*sigma
			where m and sigma are the mean and the std of the posterior in the GP
			space.
			Default is 1.96 which corresponds to the 95% confidence bounds.

		batch_size : integer, optional
			An integer giving the maximum number of points that can be
			evaluated simultaneously (depending on the available memory).
			Default is None so that all given points are evaluated at the same
			time.

		Returns
		-------
		y : array_like, shape (n_samples,)
			Prediction at x.

		MSE : array_like, optional (if eval_MSE == True)
			Mean Squared Error at x.

		LCB : array_like, optional (if eval_confidence_bounds == True)
			Lower confidence bound.

		UCB : array_like, optional (if eval_confidence_bounds == True)
			Upper confidence bound.
		"""

		# Check input shapes
		X = sk_utils.array2d(X)
		n_eval, _ = X.shape
		n_samples, n_features = self.X.shape
		n_samples_y, n_targets = self.y.shape

		if(n_targets > 1):
			raise ValueError('More than one target in the Y outputs. \
							  Currently only 1D outputs are handled')

		# Run input checks
		self._check_params(n_samples)

		if X.shape[1] != n_features:
			raise ValueError(("The number of features in X (X.shape[1] = %d) "
							  "should match the number of features used "
							  "for fit() "
							  "which is %d.") % (X.shape[1], n_features))

		# Normalize input
		if self.normalize:
			X = (X - self.X_mean) / self.X_std
			
		# Initialize output
		y = np.zeros(n_eval)
		if eval_MSE:
			MSE = np.zeros(n_eval)

		# Get pairwise componentwise L1-distances to the input training set
		dx = manhattan_distances(X, Y=self.X, sum_over_features=False)
		# Get regression function and correlation
		f = self.regr(X)
		r = self.corr(self.theta, dx).reshape(n_eval, n_samples)

		# Scaled predictor
		y_ = np.dot(f, self.beta) + np.dot(r, self.gamma)

		# Predictor
		y = (self.y_mean + self.y_std * y_).reshape(n_eval, n_targets)

		# transform the warped y, modeled as a Gaussian, to the real y
		size = y.shape[0]
		warped_y = np.copy(y)
		
		if(transformY):
			if( np.sum([ y[i][0] > 8.2 for i in range(size)]) >0):
				print('Warning : mapping_inversion failed')
			real_y = [ self.mapping_inv(X[i],y[i][0]) for i in range(size)]
			real_y = self.raw_y_std * np.asarray(real_y) +self.raw_y_mean
			y = real_y.reshape(n_eval, n_targets)
		
		if self.y_ndim_ == 1:
			y = y.ravel()
			warped_y = warped_y.ravel()

		# Mean Squared Error
		if eval_MSE:
			C = self.C
			if C is None:
				# Light storage mode (need to recompute C, F, Ft and G)
				if self.verbose:
					print("This GaussianProcess used 'light' storage mode "
						  "at instantiation. Need to recompute "
						  "autocorrelation matrix...")
				reduced_likelihood_function_value, par = \
					self.reduced_likelihood_function()
				self.C = par['C']
				self.Ft = par['Ft']
				self.G = par['G']

			rt = linalg.solve_triangular(self.C, r.T, lower=True)

			if self.beta0 is None:
				# Universal Kriging
				u = linalg.solve_triangular(self.G.T,
											np.dot(self.Ft.T, rt) - f.T)
			else:
				# Ordinary Kriging
				u = np.zeros((n_targets, n_eval))

			MSE = np.dot(self.sigma2.reshape(n_targets, 1),
						 (1. - (rt ** 2.).sum(axis=0)
						  + (u ** 2.).sum(axis=0))[np.newaxis, :])
			MSE = np.sqrt((MSE ** 2.).sum(axis=0) / n_targets)

			# Mean Squared Error might be slightly negative depending on
			# machine precision: force to zero!
			MSE[MSE < 0.] = 0.

			if self.y_ndim_ == 1:
				MSE = MSE.ravel()
				sigma = np.sqrt(MSE)
				if(returnRV):
					return [ self.predicted_RV([warped_y[i]],sigma[i],X[i]) for i in range(size)]
				else:
					if(eval_confidence_bounds):
						if not(transformY):
							print('Warning, transformY set to False but trying to evaluate conf bounds')
						warped_y_with_boundL = warped_y - coef_bound * sigma
						warped_y_with_boundU = warped_y + coef_bound * sigma
						pred_with_boundL = self.raw_y_std * np.asarray( [ self.mapping_inv(X[i],warped_y_with_boundL[i])[0] for i in range(size) ] ) +self.raw_y_mean
						pred_with_boundU =  self.raw_y_std * np.asarray( [ self.mapping_inv(X[i],warped_y_with_boundU[i])[0] for i in range(size)] ) +self.raw_y_mean
						
						if(integratedPrediction):
							lb = self.raw_y_min - 3.*(self.raw_y_max-self.raw_y_min)
							ub = self.raw_y_max + 3.*(self.raw_y_max-self.raw_y_min)
							print(lb,ub)
							integrated_real_y = [ self.integrate_prediction([warped_y[i]],sigma[i],X[i],lb,ub) for i in range(size)]
							integrated_real_y =  np.asarray(integrated_real_y)
							print('Integrated prediction')
							return integrated_real_y,MSE,pred_with_boundL,pred_with_boundU

						else:
							return y,MSE,pred_with_boundL,pred_with_boundU

						
					else:
						return y, MSE
			
			else:
				return y, MSE

		else:
			return y
Exemplo n.º 4
0
    def fit(self, X, y, detailed_y_obs=None, obs_noise=None):
        """
		The Gaussian Copula Process model fitting method.

		Parameters
		----------
		`X` : double array_like  
			An array with shape (n_samples, n_features) with the input at which
			observations were made.  

		`y` : double array_like  
			An array with shape (n_samples, ) or shape (n_samples, n_targets)
			with the observations of the output to be predicted.
			Currently only 1D targets are supported.  

		`detailed_y_obs` : double list of list  
			A list of length n_samples where entry at position i corresponds to 
			the mutiple noisy observations (given as a list) of the input value X[i,:], 
			and whose mean is y[i].  
			If not None, it can be used to learn the mapping function or fit the GP,
			see parameters mapWithNoise and useAllNoisyY of the GaussianCopulaProcess class.  

		`obs_noise` : double array  
			An array of shape (n_samples,) corresponding to the estimated noise
			in the observed y outputs.  
			If not None, it can be used to model the noise with the Estimated
			Gaussian Noise method, see the model_noise parameter of the 
			GaussianCopulaProcess class.  

		Returns
		-------
		`gcp` : self  
			A fitted Gaussian Copula Process model object awaiting data to perform
			predictions.  
		"""
        # Run input checks
        self._check_params()
        X = sk_utils.array2d(X)
        # Check if all CV obs are given
        # and if so, convert this list of list to array
        if (detailed_y_obs is not None):
            detailed_X, detailed_raw_y = listOfList_toArray(X, detailed_y_obs)

        y = np.asarray(y)
        self.y_ndim_ = y.ndim
        if y.ndim == 1:
            y = y[:, np.newaxis]
            if (detailed_y_obs is not None):
                detailed_raw_y = detailed_raw_y[:, np.newaxis]
        else:
            print(
                'Warning: code is not ready for y outputs with dimension > 1')

        # Reshape theta if it is one dimensional and X is not
        x_dim = X.shape[1]
        #if not(self.theta.ndim == 1):
        #	print('Warning : theta has not the right shape')
        self.theta = (np.ones((x_dim, self.theta.shape[0])) * self.theta).T
        self.thetaL = (np.ones((x_dim, self.thetaL.shape[0])) * self.thetaL).T
        self.thetaU = (np.ones((x_dim, self.thetaU.shape[0])) * self.thetaU).T
        #print('theta has new shape '+str(self.theta.shape))

        self.random_state = sk_utils.check_random_state(self.random_state)
        X, y = sk_utils.check_arrays(X, y)

        # Check shapes of DOE & observations
        n_samples, n_features = X.shape
        _, n_targets = y.shape

        # Run input checks
        self._check_params(n_samples)

        # Normalize data or don't
        if self.normalize:
            X_mean = np.mean(X, axis=0)
            X_std = np.std(X, axis=0)
            X_std[X_std == 0.] = 1.
            X = (X - X_mean) / X_std

            raw_y_mean = np.mean(y, axis=0)
            raw_y_std = np.std(y, axis=0)
            raw_y_std[raw_y_std == 0.] = 1.
            y = (y - raw_y_mean) / raw_y_std

            if (obs_noise is not None):
                obs_noise = obs_noise / raw_y_std

            if (detailed_y_obs is not None):
                detailed_raw_y = (detailed_raw_y - raw_y_mean) / raw_y_std
                detailed_X = (detailed_X - X_mean) / X_std
        else:
            X_mean = np.zeros(1)
            X_std = np.ones(1)

        self.raw_y_min = np.min(y)
        self.raw_y_max = np.max(y)

        # Set attributes

        if (detailed_y_obs is not None):
            self.detailed_raw_y = detailed_raw_y
            self.detailed_X = detailed_X
        else:
            self.detailed_raw_y = None
            self.detailed_X = None

        if (self.detailed_raw_y is not None and self.mapWithNoise
                and self.useAllNoisyY):
            self.X = self.detailed_X
            self.raw_y = self.detailed_raw_y

            self.raw_y_mean = raw_y_mean
            self.raw_y_std = raw_y_std
            self.low_bound = np.min([-500., 5. * np.min(y)])
            self.X_mean, self.X_std = X_mean, X_std

            # initialize mapping only if needed, i.e. it hasn't be done
            # yet of if we want to optimize the GCP hyperparameters
            if (self.try_optimize or (self.density_functions is None)):
                self.init_mappings()

        elif (self.detailed_raw_y is not None and self.useAllNoisyY):
            self.X = X
            self.raw_y = y

            self.raw_y_mean = raw_y_mean
            self.raw_y_std = raw_y_std
            self.low_bound = np.min([-500., 5. * np.min(y)])
            self.X_mean, self.X_std = X_mean, X_std

            # initialize mapping only if needed, i.e. it hasn't be done
            # yet of if we want to optimize the GCP hyperparameters
            if (self.try_optimize or (self.density_functions is None)):
                self.init_mappings()

            self.X = self.detailed_X
            self.raw_y = self.detailed_raw_y

        else:
            self.X = X
            self.raw_y = y

            self.raw_y_mean = raw_y_mean
            self.raw_y_std = raw_y_std
            self.low_bound = np.min([-500., 5. * np.min(y)])
            self.X_mean, self.X_std = X_mean, X_std

            # initialize mapping only if needed, i.e. it hasn't be done
            # yet of if we want to optimize the GCP hyperparameters
            if (self.try_optimize or (self.density_functions is None)):
                self.init_mappings()

        self.obs_noise = obs_noise
        self.update_copula_params()

        if self.try_optimize:
            # Maximum Likelihood Estimation of the parameters
            if self.verbose:
                print("Performing Maximum Likelihood Estimation of the "
                      "autocorrelation parameters...")
            self.theta, self.reduced_likelihood_function_value_, par = \
             self._arg_max_reduced_likelihood_function()
            if np.isinf(self.reduced_likelihood_function_value_):
                raise Exception("Bad parameter region. "
                                "Try increasing upper bound")
        else:
            # Given parameters
            if self.verbose:
                print("Given autocorrelation parameters. "
                      "Computing Gaussian Process model parameters...")
            self.reduced_likelihood_function_value_, par = \
             self.reduced_likelihood_function()
            if np.isinf(self.reduced_likelihood_function_value_):
                raise Exception("Bad point. Try increasing theta0.")

        self.beta = par['beta']
        self.gamma = par['gamma']
        self.sigma2 = par['sigma2']
        self.C = par['C']
        self.Ft = par['Ft']
        self.G = par['G']

        return self
Exemplo n.º 5
0
	def fit(self, X, y,detailed_y_obs=None,obs_noise=None):
		"""
		The Gaussian Copula Process model fitting method.

		Parameters
		----------
		X : double array_like
			An array with shape (n_samples, n_features) with the input at which
			observations were made.

		y : double array_like
			An array with shape (n_samples, ) or shape (n_samples, n_targets)
			with the observations of the output to be predicted.
			Currently only 1D targets are supported.

		detailed_y_obs : double list of list
			A list of length n_samples where entry at position i corresponds to 
			the mutiple noisy observations (given as a list) of the input value X[i,:], 
			and whose mean is y[i].
			If not None, it can be used to learn the mapping function or fit the GP,
			see parameters mapWithNoise and useAllNoisyY of the GaussianCopulaProcess class.

		obs_noise : double array
			An array of shape (n_samples,) corresponding to the estimated noise
			in the observed y outputs.
			If not None, it can be used to model the noise with the Estimated
			Gaussian Noise method, see the model_noise parameter of the 
			GaussianCopulaProcess class.

		Returns
		-------
		gcp : self
			A fitted Gaussian Copula Process model object awaiting data to perform
			predictions.
		"""
		# Run input checks
		self._check_params()
		X = sk_utils.array2d(X)
		# Check if all CV obs are given
		# and if so, convert this list of list to array
		if(detailed_y_obs is not None):
			detailed_X,detailed_raw_y = listOfList_toArray(X,detailed_y_obs)	

		y = np.asarray(y)
		self.y_ndim_ = y.ndim
		if y.ndim == 1:
			y = y[:, np.newaxis]
			if(detailed_y_obs is not None):
				detailed_raw_y = detailed_raw_y[:, np.newaxis]
		else:
			print('Warning: code is not ready for y outputs with dimension > 1')
		
		# Reshape theta if it is one dimensional and X is not
		x_dim = X.shape[1]
		#if not(self.theta.ndim == 1):
		#	print('Warning : theta has not the right shape')
		self.theta = (np.ones((x_dim,self.theta.shape[0])) * self.theta ).T
		self.thetaL = (np.ones((x_dim,self.thetaL.shape[0])) * self.thetaL ).T
		self.thetaU = (np.ones((x_dim,self.thetaU.shape[0])) * self.thetaU ).T
		#print('theta has new shape '+str(self.theta.shape))
			
		self.random_state = check_random_state(self.random_state)		
		X, y = sk_utils.check_arrays(X, y)

		# Check shapes of DOE & observations
		n_samples, n_features = X.shape
		_, n_targets = y.shape

		# Run input checks
		self._check_params(n_samples)

		# Normalize data or don't
		if self.normalize:
			X_mean = np.mean(X, axis=0)
			X_std = np.std(X, axis=0)
			X_std[X_std == 0.] = 1.
			X = (X - X_mean) / X_std

			raw_y_mean = np.mean(y, axis=0)
			raw_y_std = np.std(y, axis=0)
			raw_y_std[raw_y_std == 0.] = 1.
			y = (y - raw_y_mean) / raw_y_std
			
			if(obs_noise is not None):
				obs_noise = obs_noise / raw_y_std

			if(detailed_y_obs is not None):
				detailed_raw_y = (detailed_raw_y - raw_y_mean) / raw_y_std
				detailed_X = (detailed_X - X_mean) / X_std
		else:
			X_mean = np.zeros(1)
			X_std = np.ones(1)
		
		self.raw_y_min = np.min(y)		
		self.raw_y_max = np.max(y)

		# Set attributes

		if(detailed_y_obs is not None):
			self.detailed_raw_y = detailed_raw_y
			self.detailed_X = detailed_X
		else:
			self.detailed_raw_y = None			
			self.detailed_X = None			
		
		if(self.detailed_raw_y is not None and self.mapWithNoise and self.useAllNoisyY ):
			self.X = self.detailed_X
			self.raw_y = self.detailed_raw_y
			
			self.raw_y_mean = raw_y_mean
			self.raw_y_std = raw_y_std
			self.low_bound = np.min([-500., 5. * np.min(y)])
			self.X_mean, self.X_std = X_mean, X_std

			# initialize mapping only if needed, i.e. it hasn't be done 
			# yet of if we want to optimize the GCP hyperparameters
			if (self.try_optimize or (self.density_functions is None)):
				self.init_mappings()
		
		elif(self.detailed_raw_y is not None and self.useAllNoisyY ):
			self.X = X
			self.raw_y = y

			self.raw_y_mean = raw_y_mean
			self.raw_y_std = raw_y_std
			self.low_bound = np.min([-500., 5. * np.min(y)])
			self.X_mean, self.X_std = X_mean, X_std

			# initialize mapping only if needed, i.e. it hasn't be done 
			# yet of if we want to optimize the GCP hyperparameters
			if (self.try_optimize or (self.density_functions is None)):
				self.init_mappings()

			self.X = self.detailed_X
			self.raw_y = self.detailed_raw_y

		else:
			self.X = X
			self.raw_y = y

			self.raw_y_mean = raw_y_mean
			self.raw_y_std = raw_y_std
			self.low_bound = np.min([-500., 5. * np.min(y)])
			self.X_mean, self.X_std = X_mean, X_std

			# initialize mapping only if needed, i.e. it hasn't be done 
			# yet of if we want to optimize the GCP hyperparameters
			if (self.try_optimize or (self.density_functions is None)):
				self.init_mappings()

		self.obs_noise = obs_noise
		self.update_copula_params()
		
		if self.try_optimize:
		    # Maximum Likelihood Estimation of the parameters
			if self.verbose:
				print("Performing Maximum Likelihood Estimation of the "
					  "autocorrelation parameters...")
			self.theta, self.reduced_likelihood_function_value_, par = \
				self._arg_max_reduced_likelihood_function()
			if np.isinf(self.reduced_likelihood_function_value_):
				raise Exception("Bad parameter region. "
								"Try increasing upper bound")
		else:
			# Given parameters
			if self.verbose:
				print("Given autocorrelation parameters. "
					  "Computing Gaussian Process model parameters...")
			self.reduced_likelihood_function_value_, par = \
				self.reduced_likelihood_function()
			if np.isinf(self.reduced_likelihood_function_value_):
				raise Exception("Bad point. Try increasing theta0.")

		self.beta = par['beta']
		self.gamma = par['gamma']
		self.sigma2 = par['sigma2']
		self.C = par['C']
		self.Ft = par['Ft']
		self.G = par['G']

		return self