class_docstr: This implements GP regression with the FITC approximation.
  
  The key reference is :cite:t:`Snelson06sparsegaussian`.
  
  Implementation loosely based on code from GPML matlab library although
  obviously gradients are automatic in GPflow.
docstr: Construct a tensorflow function to compute the bound on the marginal
  likelihood.
docstr_tok: ["Construct","a","tensorflow","function","to","compute","the","bound","on","the","marginal","likelihood","."]
code: def fitc_log_marginal_likelihood(self) -> tf.Tensor:
      """
      Construct a tensorflow function to compute the bound on the marginal
      likelihood.
      """
  
      # FITC approximation to the log marginal likelihood is
      # log ( normal( y | mean, K_fitc ) )
      # where K_fitc = Qff + diag( \nu )
      # where Qff = Kfu kuu^{-1} kuf
      # with \nu_i = Kff_{i,i} - Qff_{i,i} + \sigma^2
  
      # We need to compute the Mahalanobis term -0.5* err^T K_fitc^{-1} err
      # (summed over functions).
  
      # We need to deal with the matrix inverse term.
      # K_fitc^{-1} = ( Qff + \diag( \nu ) )^{-1}
      #             = ( V^T V + \diag( \nu ) )^{-1}
      # Applying the Woodbury identity we obtain
      #             = \diag( \nu^{-1} )
      #                 - \diag( \nu^{-1} ) V^T ( I + V \diag( \nu^{-1} ) V^T )^{-1}
      #                     V \diag(\nu^{-1} )
      # Let \beta =  \diag( \nu^{-1} ) err
      # and let \alpha = V \beta
      # then Mahalanobis term = -0.5* (
      #    \beta^T err - \alpha^T Solve( I + V \diag( \nu^{-1} ) V^T, alpha )
      # )
  
      err, nu, _Luu, L, _alpha, _beta, gamma = self.common_terms()
  
      mahalanobisTerm = -0.5 * tf.reduce_sum(
          tf.square(err) / tf.expand_dims(nu, 1)
      ) + 0.5 * tf.reduce_sum(tf.square(gamma))
  
      # We need to compute the log normalizing term -N/2 \log 2 pi - 0.5 \log \det( K_fitc )
  
      # We need to deal with the log determinant term.
      # \log \det( K_fitc ) = \log \det( Qff + \diag( \nu ) )
      #                     = \log \det( V^T V + \diag( \nu ) )
      # Applying the determinant lemma we obtain
      #                     = \log [ \det \diag( \nu ) \det( I + V \diag( \nu^{-1} ) V^T ) ]
      #                     = \log [
      #                        \det \diag( \nu ) ] + \log [ \det( I + V \diag( \nu^{-1} ) V^T )
      #                     ]
  
      constantTerm = (
          -0.5
          * self.num_data
          * tf.math.log(tf.constant(2.0 * np.pi, default_float()))
      )
      logDeterminantTerm = -0.5 * tf.reduce_sum(
          tf.math.log(nu)
      ) - tf.reduce_sum(tf.math.log(tf.linalg.diag_part(L)))
      logNormalizingTerm = constantTerm + logDeterminantTerm
  
      return mahalanobisTerm + logNormalizingTerm * self.num_latent_gps
  
imports: from typing import NamedTuple, Optional, Tuple
  import numpy
  import tensorflow
  from check_shapes import check_shapes, inherit_check_shapes
  from ..None import posteriors
  from ..base import InputData, MeanAndVariance, RegressionData, TensorData
  from ..config import default_float, default_jitter
  from ..covariances.dispatch import Kuf, Kuu
  from ..inducing_variables import InducingPoints
  from ..kernels import Kernel
  from ..likelihoods import Gaussian
  from ..mean_functions import MeanFunction
  from ..utilities import add_noise_cov, assert_params_false, to_default_float
  from .model import GPModel
  from .training_mixins import InternalDataTrainingLossMixin
  from .util import InducingPointsLike, data_input_to_tensor, inducingpoint_wrapper
label_desc: Use image node_id 3 for calling the GPRFITC obj's underlying member method code with example usage: obj.fitc_log_marginal_likelihood() and returns: unknown