text: #!/usr/bin/env python3
  # -*- coding: utf-8 -*-
  """
  Created on Mon Jan 10 14:11:50 2022
  
  @author: apple
  
  """
  
  # smoke_test (this makes sure this example notebook gets tested)
  
  import math
  import torch
  import gpytorch
  from matplotlib import pyplot as plt
  
  from IPython.display import Markdown, display
  def printmd(string):
      display(Markdown(string))
      
      
  train_x = torch.linspace(0, 1, 100)
  train_y = torch.sin(train_x * (2 * math.pi)) + torch.randn(train_x.size()) * 0.2
  
  # We will use the simplest form of GP model, exact inference
  class ExactGPModel(gpytorch.models.ExactGP):
      def __init__(self, train_x, train_y, likelihood):
          super(ExactGPModel, self).__init__(train_x, train_y, likelihood)
          self.mean_module = gpytorch.means.ConstantMean()
          self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernel())
  
      def forward(self, x):
          mean_x = self.mean_module(x)
          covar_x = self.covar_module(x)
          return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)
  
  # initialize likelihood and model
  likelihood = gpytorch.likelihoods.GaussianLikelihood()
  model = ExactGPModel(train_x, train_y, likelihood)
  
  for param_name, param in model.named_parameters():
      print(f'Parameter name: {param_name:42} value = {param.item()}')
  
  ###########################
  raw_outputscale = model.covar_module.raw_outputscale
  print('raw_outputscale, ', raw_outputscale)
  
  # Three ways of accessing the raw outputscale constraint
  print('\nraw_outputscale_constraint1', model.covar_module.raw_outputscale_constraint)
  
  printmd('\n\n**Printing all model constraints...**\n')
  for constraint_name, constraint in model.named_constraints():
      print(f'Constraint name: {constraint_name:55} constraint = {constraint}')
  
  printmd('\n**Getting raw outputscale constraint from model...**')
  print(model.constraint_for_parameter_name("covar_module.raw_outputscale"))
  
  
  printmd('\n**Getting raw outputscale constraint from model.covar_module...**')
  print(model.covar_module.constraint_for_parameter_name("raw_outputscale"))
  #############################
  raw_outputscale = model.covar_module.raw_outputscale
  constraint = model.covar_module.raw_outputscale_constraint
  
  print('Transformed outputscale', constraint.transform(raw_outputscale))
  print(constraint.inverse_transform(constraint.transform(raw_outputscale)))
  print(torch.equal(constraint.inverse_transform(constraint.transform(raw_outputscale)), raw_outputscale))
  
  print('Transform a bunch of negative tensors: ', constraint.transform(torch.tensor([-1., -2., -3.])))
  #############################