def gradient_dot(self, v):
        """
        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.
        """
        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
def gradient_dot(self, v):
        """
        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.
        """
        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
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
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.
Implements ∂K⋅v .