def predict_jacobian(self, Xnew, kern=None, full_cov=False):
if kern is None:<EOL><INDENT>kern = self.kern<EOL><DEDENT>mean_jac = np.empty((Xnew.shape[<NUM_LIT:0>],Xnew.shape[<NUM_LIT:1>],self.output_dim))<EOL>for i in range(self.output_dim):<EOL><INDENT>mean_jac[:,:,i] = kern.gradients_X(self.posterior.woodbury_vector[:,i:i+<NUM_LIT:1>].T, Xnew, self._predictive_variable)<EOL><DEDENT>dK_dXnew_full = np.empty((self._predictive_variable.shape[<NUM_LIT:0>], Xnew.shape[<NUM_LIT:0>], Xnew.shape[<NUM_LIT:1>]))<EOL>one = np.ones((<NUM_LIT:1>,<NUM_LIT:1>))<EOL>for i in range(self._predictive_variable.shape[<NUM_LIT:0>]):<EOL><INDENT>dK_dXnew_full[i] = kern.gradients_X(one, Xnew, self._predictive_variable[[i]])<EOL><DEDENT>if full_cov:<EOL><INDENT>dK2_dXdX = kern.gradients_XX(one, Xnew)<EOL><DEDENT>else:<EOL><INDENT>dK2_dXdX = kern.gradients_XX_diag(one, Xnew)<EOL><DEDENT>def compute_cov_inner(wi):<EOL><INDENT>if full_cov:<EOL><INDENT>var_jac = dK2_dXdX - np.einsum('<STR_LIT>', dK_dXnew_full.T.dot(wi), dK_dXnew_full) <EOL><DEDENT>else:<EOL><INDENT>var_jac = dK2_dXdX - np.einsum('<STR_LIT>', dK_dXnew_full.T.dot(wi), dK_dXnew_full)<EOL><DEDENT>return var_jac<EOL><DEDENT>if self.posterior.woodbury_inv.ndim == <NUM_LIT:3>: <EOL><INDENT>if full_cov:<EOL><INDENT>var_jac = np.empty((Xnew.shape[<NUM_LIT:0>],Xnew.shape[<NUM_LIT:0>],Xnew.shape[<NUM_LIT:1>],Xnew.shape[<NUM_LIT:1>],self.output_dim))<EOL>for d in range(self.posterior.woodbury_inv.shape[<NUM_LIT:2>]):<EOL><INDENT>var_jac[:, :, :, :, d] = compute_cov_inner(self.posterior.woodbury_inv[:, :, d])<EOL><DEDENT><DEDENT>else:<EOL><INDENT>var_jac = np.empty((Xnew.shape[<NUM_LIT:0>],Xnew.shape[<NUM_LIT:1>],Xnew.shape[<NUM_LIT:1>],self.output_dim))<EOL>for d in range(self.posterior.woodbury_inv.shape[<NUM_LIT:2>]):<EOL><INDENT>var_jac[:, :, :, d] = compute_cov_inner(self.posterior.woodbury_inv[:, :, d])<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>var_jac = compute_cov_inner(self.posterior.woodbury_inv)<EOL><DEDENT>return mean_jac, var_jac<EOL>
Compute the derivatives of the posterior of the GP.

Given a set of points at which to predict X* (size [N*,Q]), compute the
mean and variance of the derivative. Resulting arrays are sized:

 dL_dX* -- [N*, Q ,D], where D is the number of output in this GP (usually one).
  Note that this is the mean and variance of the derivative,
  not the derivative of the mean and variance! (See predictive_gradients for that)

 dv_dX*  -- [N*, Q],    (since all outputs have the same variance)
  If there is missing data, it is not implemented for now, but
  there will be one output variance per output dimension.

:param X: The points at which to get the predictive gradients.
:type X: np.ndarray (Xnew x self.input_dim)
:param kern: The kernel to compute the jacobian for.
:param boolean full_cov: whether to return the cross-covariance terms between
the N* Jacobian vectors

:returns: dmu_dX, dv_dX
:rtype: [np.ndarray (N*, Q ,D), np.ndarray (N*,Q,(D)) ]