# Path: glimix_core/_util/format.py
# def format_function(func, params, attrs=None):
#     if attrs is None:
#         attrs = []
#     tname = type(func).__name__
#     name = func.name
#     kwargs_input = [f"{arg}={val}" for arg, val in params.items()]
#     input = ", ".join(kwargs_input)
#     msg = f"{tname}({input})"
#     if name is not None:
#         msg += f": {name}"
# 
#     msg += "\n"
#     for a in attrs:
#         msg += _format_named_arr(a[0], a[1])
#     return msg


from numpy import asarray, dot, ones, zeros
from optimix import Function, Vector
from .._util import format_function
        """
        return dot(self.L, self.L.T)

    def gradient(self):
        """
        Derivative of the covariance matrix over the lower triangular, flat part of L.

        It is equal to

            ∂K/∂Lᵢⱼ = ALᵀ + LAᵀ,

        where Aᵢⱼ is an n×m matrix of zeros except at [Aᵢⱼ]ᵢⱼ=1.

        Returns
        -------
        Lu : ndarray
            Derivative of K over the lower-triangular, flat part of L.
        """
        L = self.L
        n = self.L.shape[0]
        grad = {"Lu": zeros((n, n, n * self._L.shape[1]))}
        for ii in range(self._L.shape[0] * self._L.shape[1]):
            row = ii // self._L.shape[1]
            col = ii % self._L.shape[1]
            grad["Lu"][row, :, ii] = L[:, col]
            grad["Lu"][:, row, ii] += L[:, col]

        return grad

    def __str__(self):

# Path: glimix_core/_util/format.py
# def format_function(func, params, attrs=None):
#     if attrs is None:
#         attrs = []
#     tname = type(func).__name__
#     name = func.name
#     kwargs_input = [f"{arg}={val}" for arg, val in params.items()]
#     input = ", ".join(kwargs_input)
#     msg = f"{tname}({input})"
#     if name is not None:
#         msg += f": {name}"
# 
#     msg += "\n"
#     for a in attrs:
#         msg += _format_named_arr(a[0], a[1])
#     return msg


# Path: glimix_core/cov/_lrfree.py
from numpy import asarray, dot, ones, zeros
from optimix import Function, Vector
from .._util import format_function

        """
        return dot(self.L, self.L.T)

    def gradient(self):
        """
        Derivative of the covariance matrix over the lower triangular, flat part of L.

        It is equal to

            ∂K/∂Lᵢⱼ = ALᵀ + LAᵀ,

        where Aᵢⱼ is an n×m matrix of zeros except at [Aᵢⱼ]ᵢⱼ=1.

        Returns
        -------
        Lu : ndarray
            Derivative of K over the lower-triangular, flat part of L.
        """
        L = self.L
        n = self.L.shape[0]
        grad = {"Lu": zeros((n, n, n * self._L.shape[1]))}
        for ii in range(self._L.shape[0] * self._L.shape[1]):
            row = ii // self._L.shape[1]
            col = ii % self._L.shape[1]
            grad["Lu"][row, :, ii] = L[:, col]
            grad["Lu"][:, row, ii] += L[:, col]

        return grad

    def __str__(self):

        return format_function(