code: def lml(self):
          
          reml = (self._logdetXX() - self._logdetH()) / 2
          if self._optimal["scale"]:
              lml = self._lml_optimal_scale()
          else:
              lml = self._lml_arbitrary_scale()
          return lml + reml
docs: Log of the marginal likelihood.
  
          Returns
          -------
          lml : float
              Log of the marginal likelihood.
  
          Notes
          -----
          The log of the marginal likelihood is given by ::
  
              2⋅log(p(𝐲)) = -n⋅log(2π) - n⋅log(s) - log|D| - (Qᵀ𝐲)ᵀs⁻¹D⁻¹(Qᵀ𝐲)
                          + (Qᵀ𝐲)ᵀs⁻¹D⁻¹(QᵀX𝜷)/2 - (QᵀX𝜷)ᵀs⁻¹D⁻¹(QᵀX𝜷).
  
          By using the optimal 𝜷, the log of the marginal likelihood can be rewritten
          as::
  
              2⋅log(p(𝐲)) = -n⋅log(2π) - n⋅log(s) - log|D| + (Qᵀ𝐲)ᵀs⁻¹D⁻¹Qᵀ(X𝜷-𝐲).
  
  
          In the extreme case where 𝜷 is such that 𝐲 = X𝜷, the maximum is attained as
          s→0.
  
          For optimals 𝜷 and s, the log of the marginal likelihood can be further
          simplified to ::
  
              2⋅log(p(𝐲; 𝜷, s)) = -n⋅log(2π) - n⋅log s - log|D| - n.