class_docstr: Posterior predictive in a conjugate Multi-task GP regression model.
docstr: Returns a MTGaussianProcessRegressionModel with precomputed quantities.
  
  This differs from the constructor by precomputing quantities associated with
  observations in a non-tape safe way. `index_points` is the only parameter
  that is allowed to vary (i.e. is a `Variable` / changes after
  initialization).
  
  Specifically:
  
  * We make `observation_index_points` and `observations` mandatory
    parameters.
  * We precompute `kernel(observation_index_points, observation_index_points)`
    along with any other associated quantities relating to the `kernel`,
    `observations` and `observation_index_points`.
  
  A typical usecase would be optimizing kernel hyperparameters for a
  `MultiTaskGaussianProcess`, and computing the posterior predictive with
  respect to those optimized hyperparameters and observation / index-points
  pairs.
  
  WARNING: This method assumes `index_points` is the only varying parameter
  (i.e. is a `Variable` / changes after initialization) and hence is not
  tape-safe.
  
  Args:
    kernel: `PositiveSemidefiniteKernel`-like instance representing the
      GP's covariance function.
    observation_index_points: (Nested) `float` `Tensor` representing finite
      collection, or batch of collections, of points in the index set for
      which some data has been observed. Shape (or shape of each nested
      component) has the form `[b1, ..., bB, e, f1, ..., fF]` where `F` is
      the number of feature dimensions and must equal
      `kernel.feature_ndims` (or its corresponding nested component), and
      `e` is the number (size) of index points in each batch. `[b1, ...,
      bB, e]` must be broadcastable with the shape of `observations`, and
      `[b1, ..., bB]` must be broadcastable with the shapes of all other
      batched parameters (`kernel.batch_shape`, `index_points`, etc). The
      default value is `None`, which corresponds to the empty set of
      observations, and simply results in the prior predictive model (a GP
      with noise of variance `predictive_noise_variance`).
    observations: `float` `Tensor` representing collection, or batch of
      collections, of observations corresponding to
      `observation_index_points`. Shape has the form `[b1, ..., bB, e, t]`
      The batch shape `[b1, ..., bB]` must be
      broadcastable with the shapes of all other batched parameters
      (`kernel.batch_shape`, `index_points`, etc.). The default value is
      `None`, which corresponds to the empty set of observations, and simply
      results in the prior predictive model (a GP with noise of variance
      `predictive_noise_variance`).
    observations_is_missing:  `bool` `Tensor` of shape `[..., e]`,
      representing a batch of boolean masks.  When `observations_is_missing`
      is not `None`, the returned distribution is conditioned only on the
      observations for which the corresponding elements of
      `observations_is_missing` are `True`.
    index_points: (Nested) `float` `Tensor` representing finite collection, or
      batch of collections, of points in the index set over which the GP is
      defined.  Shape (or shape of each nested component) has the form
      `[b1, ..., bB, e, f1, ..., fF]` where `F` is the number of feature
      dimensions and must equal `kernel.feature_ndims` (or its corresponding
      nested component) and `e` is the number (size) of index points in each
      batch. Ultimately this distribution corresponds to an `e`-dimensional
      multivariate normal. The batch shape must be broadcastable with
      `kernel.batch_shape` and any batch dims yielded by `mean_fn`.
    observation_noise_variance: `float` `Tensor` representing the variance
      of the noise in the Normal likelihood distribution of the model. May be
      batched, in which case the batch shape must be broadcastable with the
      shapes of all other batched parameters (`kernel.batch_shape`,
      `index_points`, etc.).
      Default value: `None`
    predictive_noise_variance: `float` `Tensor` representing the variance in
      the posterior predictive model. If `None`, we simply re-use
      `observation_noise_variance` for the posterior predictive noise. If set
      explicitly, however, we use this value. This allows us, for example, to
      omit predictive noise variance (by setting this to zero) to obtain
      noiseless posterior predictions of function values, conditioned on noisy
      observations.
    mean_fn: Python `callable` that acts on `index_points` to produce a
      collection, or batch of collections, of mean values at `index_points`.
      Takes a (nested) `Tensor` of shape `[b1, ..., bB, e, f1, ..., fF]` and
      returns a `Tensor` whose shape is broadcastable with
      `[b1, ..., bB, e, t]`.
      Default value: `None` implies the constant zero function.
    cholesky_fn: Callable which takes a single (batch) matrix argument and
      returns a Cholesky-like lower triangular factor.  Default value: `None`,
      in which case `make_cholesky_with_jitter_fn` is used with the `jitter`
      parameter.
    validate_args: Python `bool`, default `False`. When `True` distribution
      parameters are checked for validity despite possibly degrading runtime
      performance. When `False` invalid inputs may silently render incorrect
      outputs.
      Default value: `False`.
    allow_nan_stats: Python `bool`, default `True`. When `True`,
      statistics (e.g., mean, mode, variance) use the value `NaN` to
      indicate the result is undefined. When `False`, an exception is raised
      if one or more of the statistic's batch members are undefined.
      Default value: `False`.
    name: Python `str` name prefixed to Ops created by this class.
      Default value: 'PrecomputedGaussianProcessRegressionModel'.
    _precomputed_divisor_matrix_cholesky: Internal parameter -- do not use.
    _precomputed_solve_on_observation: Internal parameter -- do not use.
  Returns
    An instance of `MultiTaskGaussianProcessRegressionModel` with precomputed
    quantities associated with observations.
docstr_tok: ["Returns","a","MTGaussianProcessRegressionModel","with","precomputed","quantities",".","This","differs","from","the","constructor","by","precomputing","quantities","associated","with","observations","in","a","non-tape","safe","way",".","`","index_points","`","is","the","only","parameter","that","is","allowed","to","vary","(","i.e",".","is","a","`","Variable","`","\/","changes","after","initialization",")",".","Specifically",":","*","We","make","`","observation_index_points","`","and","`","observations","`","mandatory","parameters",".","*","We","precompute","`","kernel","(","observation_index_points",",","observation_index_points",")","`","along","with","any","other","associated","quantities","relating","to","the","`","kernel","`",",","`","observations","`","and","`","observation_index_points","`",".","A","typical","usecase","would","be","optimizing","kernel","hyperparameters","for","a","`","MultiTaskGaussianProcess","`",",","and","computing","the","posterior","predictive","with","respect","to","those","optimized","hyperparameters","and","observation","\/","index-points","pairs",".","WARNING",":","This","method","assumes","`","index_points","`","is","the","only","varying","parameter","(","i.e",".","is","a","`","Variable","`","\/","changes","after","initialization",")","and","hence","is","not","tape-safe",".","Args",":","kernel",":","`","PositiveSemidefiniteKernel","`","-like","instance","representing","the","GP","'s","covariance","function",".","observation_index_points",":","(","Nested",")","`","float","`","`","Tensor","`","representing","finite","collection",",","or","batch","of","collections",",","of","points","in","the","index","set","for","which","some","data","has","been","observed",".","Shape","(","or","shape","of","each","nested","component",")","has","the","form","`","[","b1",",","...",",","bB",",","e",",","f1",",","...",",","fF","]","`","where","`","F","`","is","the","number","of","feature","dimensions","and","must","equal","`","kernel.feature_ndims","`","(","or","its","corresponding","nested","component",")",",","and","`","e","`","is","the","number","(","size",")","of","index","points","in","each","batch",".","`","[","b1",",","...",",","bB",",","e","]","`","must","be","broadcastable","with","the","shape","of","`","observations","`",",","and","`","[","b1",",","...",",","bB","]","`","must","be","broadcastable","with","the","shapes","of","all","other","batched","parameters","(","`","kernel.batch_shape","`",",","`","index_points","`",",","etc",")",".","The","default","value","is","`","None","`",",","which","corresponds","to","the","empty","set","of","observations",",","and","simply","results","in","the","prior","predictive","model","(","a","GP","with","noise","of","variance","`","predictive_noise_variance","`",")",".","observations",":","`","float","`","`","Tensor","`","representing","collection",",","or","batch","of","collections",",","of","observations","corresponding","to","`","observation_index_points","`",".","Shape","has","the","form","`","[","b1",",","...",",","bB",",","e",",","t","]","`","The","batch","shape","`","[","b1",",","...",",","bB","]","`","must","be","broadcastable","with","the","shapes","of","all","other","batched","parameters","(","`","kernel.batch_shape","`",",","`","index_points","`",",","etc.",")",".","The","default","value","is","`","None","`",",","which","corresponds","to","the","empty","set","of","observations",",","and","simply","results","in","the","prior","predictive","model","(","a","GP","with","noise","of","variance","`","predictive_noise_variance","`",")",".","observations_is_missing",":","`","bool","`","`","Tensor","`","of","shape","`","[","...",",","e","]","`",",","representing","a","batch","of","boolean","masks",".","When","`","observations_is_missing","`","is","not","`","None","`",",","the","returned","distribution","is","conditioned","only","on","the","observations","for","which","the","corresponding","elements","of","`","observations_is_missing","`","are","`","True","`",".","index_points",":","(","Nested",")","`","float","`","`","Tensor","`","representing","finite","collection",",","or","batch","of","collections",",","of","points","in","the","index","set","over","which","the","GP","is","defined",".","Shape","(","or","shape","of","each","nested","component",")","has","the","form","`","[","b1",",","...",",","bB",",","e",",","f1",",","...",",","fF","]","`","where","`","F","`","is","the","number","of","feature","dimensions","and","must","equal","`","kernel.feature_ndims","`","(","or","its","corresponding","nested","component",")","and","`","e","`","is","the","number","(","size",")","of","index","points","in","each","batch",".","Ultimately","this","distribution","corresponds","to","an","`","e","`","-dimensional","multivariate","normal",".","The","batch","shape","must","be","broadcastable","with","`","kernel.batch_shape","`","and","any","batch","dims","yielded","by","`","mean_fn","`",".","observation_noise_variance",":","`","float","`","`","Tensor","`","representing","the","variance","of","the","noise","in","the","Normal","likelihood","distribution","of","the","model",".","May","be","batched",",","in","which","case","the","batch","shape","must","be","broadcastable","with","the","shapes","of","all","other","batched","parameters","(","`","kernel.batch_shape","`",",","`","index_points","`",",","etc.",")",".","Default","value",":","`","None","`","predictive_noise_variance",":","`","float","`","`","Tensor","`","representing","the","variance","in","the","posterior","predictive","model",".","If","`","None","`",",","we","simply","re-use","`","observation_noise_variance","`","for","the","posterior","predictive","noise",".","If","set","explicitly",",","however",",","we","use","this","value",".","This","allows","us",",","for","example",",","to","omit","predictive","noise","variance","(","by","setting","this","to","zero",")","to","obtain","noiseless","posterior","predictions","of","function","values",",","conditioned","on","noisy","observations",".","mean_fn",":","Python","`","callable","`","that","acts","on","`","index_points","`","to","produce","a","collection",",","or","batch","of","collections",",","of","mean","values","at","`","index_points","`",".","Takes","a","(","nested",")","`","Tensor","`","of","shape","`","[","b1",",","...",",","bB",",","e",",","f1",",","...",",","fF","]","`","and","returns","a","`","Tensor","`","whose","shape","is","broadcastable","with","`","[","b1",",","...",",","bB",",","e",",","t","]","`",".","Default","value",":","`","None","`","implies","the","constant","zero","function",".","cholesky_fn",":","Callable","which","takes","a","single","(","batch",")","matrix","argument","and","returns","a","Cholesky-like","lower","triangular","factor",".","Default","value",":","`","None","`",",","in","which","case","`","make_cholesky_with_jitter_fn","`","is","used","with","the","`","jitter","`","parameter",".","validate_args",":","Python","`","bool","`",",","default","`","False","`",".","When","`","True","`","distribution","parameters","are","checked","for","validity","despite","possibly","degrading","runtime","performance",".","When","`","False","`","invalid","inputs","may","silently","render","incorrect","outputs",".","Default","value",":","`","False","`",".","allow_nan_stats",":","Python","`","bool","`",",","default","`","True","`",".","When","`","True","`",",","statistics","(","e.g.",",","mean",",","mode",",","variance",")","use","the","value","`","NaN","`","to","indicate","the","result","is","undefined",".","When","`","False","`",",","an","exception","is","raised","if","one","or","more","of","the","statistic","'s","batch","members","are","undefined",".","Default","value",":","`","False","`",".","name",":","Python","`","str","`","name","prefixed","to","Ops","created","by","this","class",".","Default","value",":","'PrecomputedGaussianProcessRegressionModel","'",".","_precomputed_divisor_matrix_cholesky",":","Internal","parameter","--","do","not","use",".","_precomputed_solve_on_observation",":","Internal","parameter","--","do","not","use",".","Returns","An","instance","of","`","MultiTaskGaussianProcessRegressionModel","`","with","precomputed","quantities","associated","with","observations","."]
code: def precompute_regression_model(
      kernel,
      observation_index_points,
      observations,
      observations_is_missing=None,
      index_points=None,
      observation_noise_variance=None,
      predictive_noise_variance=None,
      mean_fn=None,
      cholesky_fn=None,
      validate_args=False,
      allow_nan_stats=False,
      name="PrecomputedMultiTaskGaussianProcessRegressionModel",
      _precomputed_divisor_matrix_cholesky=None,
      _precomputed_solve_on_observation=None,
  ):
      """Returns a MTGaussianProcessRegressionModel with precomputed quantities.
  
      This differs from the constructor by precomputing quantities associated with
      observations in a non-tape safe way. `index_points` is the only parameter
      that is allowed to vary (i.e. is a `Variable` / changes after
      initialization).
  
      Specifically:
  
      * We make `observation_index_points` and `observations` mandatory
        parameters.
      * We precompute `kernel(observation_index_points, observation_index_points)`
        along with any other associated quantities relating to the `kernel`,
        `observations` and `observation_index_points`.
  
      A typical usecase would be optimizing kernel hyperparameters for a
      `MultiTaskGaussianProcess`, and computing the posterior predictive with
      respect to those optimized hyperparameters and observation / index-points
      pairs.
  
      WARNING: This method assumes `index_points` is the only varying parameter
      (i.e. is a `Variable` / changes after initialization) and hence is not
      tape-safe.
  
      Args:
        kernel: `PositiveSemidefiniteKernel`-like instance representing the
          GP's covariance function.
        observation_index_points: (Nested) `float` `Tensor` representing finite
          collection, or batch of collections, of points in the index set for
          which some data has been observed. Shape (or shape of each nested
          component) has the form `[b1, ..., bB, e, f1, ..., fF]` where `F` is
          the number of feature dimensions and must equal
          `kernel.feature_ndims` (or its corresponding nested component), and
          `e` is the number (size) of index points in each batch. `[b1, ...,
          bB, e]` must be broadcastable with the shape of `observations`, and
          `[b1, ..., bB]` must be broadcastable with the shapes of all other
          batched parameters (`kernel.batch_shape`, `index_points`, etc). The
          default value is `None`, which corresponds to the empty set of
          observations, and simply results in the prior predictive model (a GP
          with noise of variance `predictive_noise_variance`).
        observations: `float` `Tensor` representing collection, or batch of
          collections, of observations corresponding to
          `observation_index_points`. Shape has the form `[b1, ..., bB, e, t]`
          The batch shape `[b1, ..., bB]` must be
          broadcastable with the shapes of all other batched parameters
          (`kernel.batch_shape`, `index_points`, etc.). The default value is
          `None`, which corresponds to the empty set of observations, and simply
          results in the prior predictive model (a GP with noise of variance
          `predictive_noise_variance`).
        observations_is_missing:  `bool` `Tensor` of shape `[..., e]`,
          representing a batch of boolean masks.  When `observations_is_missing`
          is not `None`, the returned distribution is conditioned only on the
          observations for which the corresponding elements of
          `observations_is_missing` are `True`.
        index_points: (Nested) `float` `Tensor` representing finite collection, or
          batch of collections, of points in the index set over which the GP is
          defined.  Shape (or shape of each nested component) has the form
          `[b1, ..., bB, e, f1, ..., fF]` where `F` is the number of feature
          dimensions and must equal `kernel.feature_ndims` (or its corresponding
          nested component) and `e` is the number (size) of index points in each
          batch. Ultimately this distribution corresponds to an `e`-dimensional
          multivariate normal. The batch shape must be broadcastable with
          `kernel.batch_shape` and any batch dims yielded by `mean_fn`.
        observation_noise_variance: `float` `Tensor` representing the variance
          of the noise in the Normal likelihood distribution of the model. May be
          batched, in which case the batch shape must be broadcastable with the
          shapes of all other batched parameters (`kernel.batch_shape`,
          `index_points`, etc.).
          Default value: `None`
        predictive_noise_variance: `float` `Tensor` representing the variance in
          the posterior predictive model. If `None`, we simply re-use
          `observation_noise_variance` for the posterior predictive noise. If set
          explicitly, however, we use this value. This allows us, for example, to
          omit predictive noise variance (by setting this to zero) to obtain
          noiseless posterior predictions of function values, conditioned on noisy
          observations.
        mean_fn: Python `callable` that acts on `index_points` to produce a
          collection, or batch of collections, of mean values at `index_points`.
          Takes a (nested) `Tensor` of shape `[b1, ..., bB, e, f1, ..., fF]` and
          returns a `Tensor` whose shape is broadcastable with
          `[b1, ..., bB, e, t]`.
          Default value: `None` implies the constant zero function.
        cholesky_fn: Callable which takes a single (batch) matrix argument and
          returns a Cholesky-like lower triangular factor.  Default value: `None`,
          in which case `make_cholesky_with_jitter_fn` is used with the `jitter`
          parameter.
        validate_args: Python `bool`, default `False`. When `True` distribution
          parameters are checked for validity despite possibly degrading runtime
          performance. When `False` invalid inputs may silently render incorrect
          outputs.
          Default value: `False`.
        allow_nan_stats: Python `bool`, default `True`. When `True`,
          statistics (e.g., mean, mode, variance) use the value `NaN` to
          indicate the result is undefined. When `False`, an exception is raised
          if one or more of the statistic's batch members are undefined.
          Default value: `False`.
        name: Python `str` name prefixed to Ops created by this class.
          Default value: 'PrecomputedGaussianProcessRegressionModel'.
        _precomputed_divisor_matrix_cholesky: Internal parameter -- do not use.
        _precomputed_solve_on_observation: Internal parameter -- do not use.
      Returns
        An instance of `MultiTaskGaussianProcessRegressionModel` with precomputed
        quantities associated with observations.
      """
  
      with tf.name_scope(name) as name:
          if tf.nest.is_nested(kernel.feature_ndims):
              input_dtype = dtype_util.common_dtype(
                  [kernel, index_points, observation_index_points],
                  dtype_hint=nest_util.broadcast_structure(
                      kernel.feature_ndims, tf.float32
                  ),
              )
              dtype = dtype_util.common_dtype(
                  [
                      observations,
                      observation_noise_variance,
                      predictive_noise_variance,
                  ],
                  tf.float32,
              )
          else:
              # If the index points are not nested, we assume they are of the same
              # dtype as the kernel.
              dtype = dtype_util.common_dtype(
                  [
                      kernel,
                      index_points,
                      observation_index_points,
                      observations,
                      observation_noise_variance,
                      predictive_noise_variance,
                  ],
                  tf.float32,
              )
              input_dtype = dtype
  
          # Convert-to-tensor arguments that are expected to not be Variables / not
          # going to change.
          observation_index_points = nest_util.convert_to_nested_tensor(
              observation_index_points,
              dtype=input_dtype,
              allow_packing=True,
          )
          if observation_noise_variance is not None:
              observation_noise_variance = tf.convert_to_tensor(
                  observation_noise_variance, dtype=dtype
              )
          observations = tf.convert_to_tensor(observations, dtype=dtype)
  
          if observations_is_missing is not None:
              observations_is_missing = tf.convert_to_tensor(
                  observations_is_missing
              )
  
          if cholesky_fn is None:
              cholesky_fn = cholesky_util.make_cholesky_with_jitter_fn()
          else:
              if not callable(cholesky_fn):
                  raise ValueError(
                      "`cholesky_fn` must be a Python callable"
                  )
  
          if mean_fn is None:
              mean_fn = lambda x: tf.zeros([1], dtype=dtype)
          else:
              if not callable(mean_fn):
                  raise ValueError(
                      "`mean_fn` must be a Python callable"
                  )
  
          if _precomputed_divisor_matrix_cholesky is not None:
              observation_scale = _scale_from_precomputed(
                  _precomputed_divisor_matrix_cholesky, kernel
              )
              solve_on_observations = _precomputed_solve_on_observation
          else:
              # Note that the conditional mean is
              # k(x, o) @ (k(o, o) + sigma**2)^-1 obs. We can precompute the latter
              # term since it won't change per iteration.
              vec_diff = _vec(
                  observations - mean_fn(observation_index_points)
              )
  
              if observations_is_missing is not None:
                  # If observations are missing, there's nothing we can do to preserve
                  # the operator structure, so densify.
                  vec_observations_is_missing = _vec(
                      observations_is_missing
                  )
                  vec_diff = tf.where(
                      vec_observations_is_missing,
                      tf.zeros([], dtype=vec_diff.dtype),
                      vec_diff,
                  )
  
                  observation_covariance = kernel.matrix_over_all_tasks(
                      observation_index_points, observation_index_points
                  ).to_dense()
  
                  if observation_noise_variance is not None:
                      broadcast_shape = (
                          distribution_util.get_broadcast_shape(
                              observation_covariance,
                              observation_noise_variance[
                                  ..., tf.newaxis, tf.newaxis
                              ],
                          )
                      )
                      observation_covariance = tf.broadcast_to(
                          observation_covariance, broadcast_shape
                      )
                      observation_covariance = _add_diagonal_shift(
                          observation_covariance,
                          observation_noise_variance,
                      )
                  observation_covariance = (
                      tf.linalg.LinearOperatorFullMatrix(
                          psd_kernels_util.mask_matrix(
                              observation_covariance,
                              is_missing=vec_observations_is_missing,
                          ),
                          is_non_singular=True,
                          is_positive_definite=True,
                      )
                  )
                  observation_scale = cholesky_util.cholesky_from_fn(
                      observation_covariance, cholesky_fn
                  )
              else:
                  observation_scale = mtgp._compute_flattened_scale(  # pylint:disable=protected-access
                      kernel=kernel,
                      index_points=observation_index_points,
                      cholesky_fn=cholesky_fn,
                      observation_noise_variance=observation_noise_variance,
                  )
              solve_on_observations = observation_scale.solvevec(
                  observation_scale.solvevec(vec_diff), adjoint=True
              )
  
          def flattened_conditional_mean_fn(x):
              return _flattened_conditional_mean_fn_helper(
                  x,
                  kernel,
                  observations,
                  observation_index_points,
                  observations_is_missing,
                  observation_scale,
                  mean_fn,
                  solve_on_observations=solve_on_observations,
              )
  
          mtgprm = MultiTaskGaussianProcessRegressionModel(
              kernel=kernel,
              observation_index_points=observation_index_points,
              observations=observations,
              index_points=index_points,
              observation_noise_variance=observation_noise_variance,
              predictive_noise_variance=predictive_noise_variance,
              cholesky_fn=cholesky_fn,
              observations_is_missing=observations_is_missing,
              _flattened_conditional_mean_fn=flattened_conditional_mean_fn,
              _observation_scale=observation_scale,
              validate_args=validate_args,
              allow_nan_stats=allow_nan_stats,
              name=name,
          )
  
          # pylint: disable=protected-access
          mtgprm._precomputed_divisor_matrix_cholesky = (
              _precomputed_from_scale(observation_scale, kernel)
          )
          mtgprm._precomputed_solve_on_observation = (
              solve_on_observations
          )
          # pylint: enable=protected-access
  
      return mtgprm
  
imports: import functools
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import softplus
  from tensorflow_probability.python.distributions import cholesky_util
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.distributions import mvn_linear_operator
  from tensorflow_probability.python.distributions.internal import stochastic_process_util
  from tensorflow_probability.python.experimental.distributions import multitask_gaussian_process
  from tensorflow_probability.python.experimental.linalg import linear_operator_unitary
  from tensorflow_probability.python.experimental.psd_kernels import multitask_kernel
  from tensorflow_probability.python.internal import batch_shape_lib
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import nest_util
  from tensorflow_probability.python.internal import parameter_properties
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import reparameterization
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.math.psd_kernels.internal import util
label_desc: Use image node_id 3 for calling the MultiTaskGaussianProcessRegressionModel obj's underlying member method code with example usage: obj.precompute_regression_model(kernel, observation_index_points, observations, observations_is_missing, index_points, observation_noise_variance, predictive_noise_variance, mean_fn, cholesky_fn, validate_args, allow_nan_stats, name, _precomputed_divisor_matrix_cholesky, _precomputed_solve_on_observation) and returns: mtgprm, _flattened_conditional_mean_fn_helper