Apply a performance function to a confusion matrix
    
    :param mat: confusion matrix
    :type mat: square matrix
    :param function fn: performance function

def confusion_performance(mat, fn):
    """Apply a performance function to a confusion matrix
    
    :param mat: confusion matrix
    :type mat: square matrix
    :param function fn: performance function
    """
    if mat.shape[0] != mat.shape[1] or mat.shape < (2, 2):
        raise TypeError('{} is not a confusion matrix'.format(mat))
    elif mat.shape == (2, 2):
        return fn(mat[TP], mat[TN], mat[FP], mat[FN])
    res = numpy.empty(mat.shape[0])
    for i in range(len(res)):
        res[i] = fn(mat[i, i],                                   # TP
                    sum(mat) - sum(mat[:, i]) - sum(mat[i, :]),  # TN
                    sum(mat[:, i]) - mat[i, i],                  # FP
                    sum(mat[i, :]) - mat[i, i])                  # FN
    return res