If full_values has indices in values_indices, we might want to initialize
        the full_values differently, so that subsetting is possible.

        Here you can initialize the full_values for the values needed.

        Keep in mind, that if a key does not exist in full_values when updating
        values, it will be set (so e.g. for Z there is no need to initialize Zgrad,
        as there is no subsetting needed. For X in BGPLVM on the other hand we probably need
        to initialize the gradients for the mean and the variance in order to
        have the full gradient for indexing)

def _outer_init_full_values(self):
        """
        If full_values has indices in values_indices, we might want to initialize
        the full_values differently, so that subsetting is possible.

        Here you can initialize the full_values for the values needed.

        Keep in mind, that if a key does not exist in full_values when updating
        values, it will be set (so e.g. for Z there is no need to initialize Zgrad,
        as there is no subsetting needed. For X in BGPLVM on the other hand we probably need
        to initialize the gradients for the mean and the variance in order to
        have the full gradient for indexing)
        """
        retd = dict(dL_dKmm=np.zeros((self.Z.shape[0], self.Z.shape[0])))
        if self.has_uncertain_inputs():
            retd.update(dict(dL_dpsi0=np.zeros(self.X.shape[0]),
                             dL_dpsi1=np.zeros((self.X.shape[0], self.Z.shape[0])),
                             dL_dpsi2=np.zeros((self.X.shape[0], self.Z.shape[0], self.Z.shape[0]))))
        else:
            retd.update({'dL_dKdiag': np.zeros(self.X.shape[0]),
                         'dL_dKnm': np.zeros((self.X.shape[0], self.Z.shape[0]))})
        return retd