code: def gradient_dot(self, v):
          
          self._init_svd()
          V = unvec(v, (self.G.shape[0], -1) + v.shape[1:])
          r = {}
  
          C = self._C0.gradient()["Lu"]
          r["C0.Lu"] = tensordot(V.T @ self.G @ self.G.T, C, axes=([-2], [0]))
          r["C0.Lu"] = r["C0.Lu"].reshape(V.shape[2:] + (-1,) + (C.shape[-1],), order="F")
  
          C = self._C1.gradient()["Lu"]
          r["C1.Lu"] = tensordot(V.T, C, axes=([-2], [0]))
          r["C1.Lu"] = r["C1.Lu"].reshape(V.shape[2:] + (-1,) + (C.shape[-1],), order="F")
  
          return r
docs: Implements ∂K⋅v.
  
          Parameters
          ----------
          v : array_like
              Vector from ∂K⋅v.
  
          Returns
          -------
          C0.Lu : ndarray
              ∂K⋅v, where the gradient is taken over the C₀ parameters.
          C1.Lu : ndarray
              ∂K⋅v, where the gradient is taken over the C₁ parameters.