human
Complete this python program:
def funm(A, func, disp=True):
assistant
#Here is the Python code you requested.

    """Evaluate a matrix function specified by a callable.
    Returns the value of matrix-valued function ``f`` at `A`. The
    function ``f`` is an extension of the scalar-valued function `func`
    to matrices.
    Parameters
    A : (N, N) array_like
    Matrix at which to evaluate the function
    func : callable
    Callable object that evaluates a scalar function f.
    Must be vectorized (eg. using vectorize).
    disp : bool, optional
    Print warning if error in the result is estimated large
    instead of returning estimated error. (Default: True)
    Returns
    funm : (N, N) ndarray
    Value of the matrix function specified by func evaluated at `A`
    errest : float
    (if disp == False)
    1-norm of the estimated error, ||err||_1 / ||A||_1
    Examples
    >>> from scipy.linalg import funm
    >>> a = np.array([[1.0, 3.0], [1.0, 4.0]])
    >>> funm(a, lambda x: x*x)
    array([[  4.,  15.],
    [  5.,  19.]])
    >>> a.dot(a)
    array([[  4.,  15.],
    [  5.,  19.]])
    Notes
    This function implements the general algorithm based on Schur decomposition
    (Algorithm 9.1.1. in [1]_).
    If the input matrix is known to be diagonalizable, then relying on the
    eigendecomposition is likely to be faster. For example, if your matrix is
    Hermitian, you can do
    >>> from scipy.linalg import eigh
    >>> def funm_herm(a, func, check_finite=False):
    ...     w, v = eigh(a, check_finite=check_finite)
    ...     ## if you further know that your matrix is positive semidefinite,
    ...     ## you can optionally guard against precision errors by doing
    ...     # w = np.maximum(w, 0)
    ...     w = func(w)
    ...     return (v * w).dot(v.conj().T)
    References
    .. [1] Gene H. Golub, Charles F. van Loan, Matrix Computations 4th ed.
    """
    A = _asarray_square(A)
    (T, Z) = schur(A)
    (T, Z) = rsf2csf(T, Z)
    (n, n) = T.shape
    F = diag(func(diag(T)))
    F = F.astype(T.dtype.char)
    minden = abs(T[(0, 0)])
    for p in range(1, n):
        for i in range(1, ((n - p) + 1)):
            j = (i + p)
            s = (T[((i - 1), (j - 1))] * (F[((j - 1), (j - 1))] - F[((i - 1), (i - 1))]))
            ksl = slice(i, (j - 1))
            val = (dot(T[((i - 1), ksl)], F[(ksl, (j - 1))]) - dot(F[((i - 1), ksl)], T[(ksl, (j - 1))]))
            s = (s + val)
            den = (T[((j - 1), (j - 1))] - T[((i - 1), (i - 1))])
            if (den != 0.0):
                s = (s / den)
            F[((i - 1), (j - 1))] = s
            minden = min(minden, abs(den))
    F = dot(dot(Z, F), transpose(conjugate(Z)))
    F = _maybe_real(A, F)
    tol = {0: feps, 1: eps}[_array_precision[F.dtype.char]]
    if (minden == 0.0):
        minden = tol
    err = min(1, max(tol, ((tol / minden) * norm(triu(T, 1), 1))))
    if product(ravel(logical_not(isfinite(F))), axis=0):
        err = Inf
    if disp:
        if (err > (1000 * tol)):
            print('funm    result    may    be    inaccurate,    approximate    err    =', err)
        return F
    else:
        return (F, err)