def inference(self, kern, X, likelihood, Y, mean_function=None, Y_metadata=None, K=None, variance=None, Z_tilde=None):
if mean_function is None:<EOL><INDENT>m = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>m = mean_function.f(X)<EOL><DEDENT>if variance is None:<EOL><INDENT>variance = likelihood.gaussian_variance(Y_metadata)<EOL><DEDENT>YYT_factor = Y-m<EOL>if K is None:<EOL><INDENT>K = kern.K(X)<EOL><DEDENT>Ky = K.copy()<EOL>diag.add(Ky, variance+<NUM_LIT>)<EOL>Wi, LW, LWi, W_logdet = pdinv(Ky)<EOL>alpha, _ = dpotrs(LW, YYT_factor, lower=<NUM_LIT:1>)<EOL>log_marginal =  <NUM_LIT:0.5>*(-Y.size * log_2_pi - Y.shape[<NUM_LIT:1>] * W_logdet - np.sum(alpha * YYT_factor))<EOL>if Z_tilde is not None:<EOL><INDENT>log_marginal += Z_tilde<EOL><DEDENT>dL_dK = <NUM_LIT:0.5> * (tdot(alpha) - Y.shape[<NUM_LIT:1>] * Wi)<EOL>dL_dthetaL = likelihood.exact_inference_gradients(np.diag(dL_dK), Y_metadata)<EOL>return Posterior(woodbury_chol=LW, woodbury_vector=alpha, K=K), log_marginal, {'<STR_LIT>':dL_dK, '<STR_LIT>':dL_dthetaL, '<STR_LIT>':alpha}<EOL>
Returns a Posterior class containing essential quantities of the posterior