old_contents: # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  # SPDX-License-Identifier: Apache-2.0
  
  
  import numpy as np
  from typing import Tuple
  
  
  class IModel:
      def predict(self, X: np.ndarray) -> np.ndarray:
          """
          Predict values for given points
  
          :param X: points to run prediction for
          """
          raise NotImplementedError
  
      def update_data(self, X: np.ndarray, Y: np.ndarray) -> None:
          """
          Updates model with new data points.
  
          :param X: new points
          :param Y: function values at new points X
          """
          raise NotImplementedError
  
      def optimize(self) -> None:
          """
          Optimize hyper-parameters of model
          """
          raise NotImplementedError
  
      @property
      def X(self):
          raise NotImplementedError
  
      @property
      def Y(self):
          raise NotImplementedError
  
  
  class IDifferentiable:
      def get_prediction_gradients(self, X: np.ndarray) -> Tuple:
          """
          Computes and returns model gradients of mean and variance at given points
  
          :param X: points to compute gradients at
          """
          raise NotImplementedError
  
new_contents: # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  # SPDX-License-Identifier: Apache-2.0
  
  
  import numpy as np
  from typing import Tuple
  
  
  class IModel:
      def predict(self, X: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
          """
          Predict mean and variance values for given points
  
          :param X: array of shape (n_points x n_inputs) of points to run prediction for
          :return: Tuple of mean and variance which are 2d arrays of shape (n_points x n_outputs)
          """
          raise NotImplementedError
  
      def update_data(self, X: np.ndarray, Y: np.ndarray) -> None:
          """
          Updates model with new data points.
  
          :param X: new points
          :param Y: function values at new points X
          """
          raise NotImplementedError
  
      def optimize(self) -> None:
          """
          Optimize hyper-parameters of model
          """
          raise NotImplementedError
  
      @property
      def X(self):
          raise NotImplementedError
  
      @property
      def Y(self):
          raise NotImplementedError
  
  
  class IDifferentiable:
      def get_prediction_gradients(self, X: np.ndarray) -> Tuple:
          """
          Computes and returns model gradients of mean and variance at given points
  
          :param X: points to compute gradients at
          """
          raise NotImplementedError
  
subject: Fix return type of predict in IModel interface (#41)