def fit_general(xy, uv):
    """ Performs a simple fit for the shift only between
        matched lists of positions 'xy' and 'uv'.

        Output: (same as for fit_arrays)
        =================================
        DEVELOPMENT NOTE:
            Checks need to be put in place to verify that
            enough objects are available for a fit.
        =================================
    """
    # Set up products used for computing the fit
    gxy = uv.astype(ndfloat128)
    guv = xy.astype(ndfloat128)
    Sx = gxy[:,0].sum()
    Sy = gxy[:,1].sum()
    Su = guv[:,0].sum()
    Sv = guv[:,1].sum()

    Sux = np.dot(guv[:,0], gxy[:,0])
    Svx = np.dot(guv[:,1], gxy[:,0])
    Suy = np.dot(guv[:,0], gxy[:,1])
    Svy = np.dot(guv[:,1], gxy[:,1])
    Sxx = np.dot(gxy[:,0], gxy[:,0])
    Syy = np.dot(gxy[:,1], gxy[:,1])
    Sxy = np.dot(gxy[:,0], gxy[:,1])

    n = len(xy[:,0])
    M = np.array([[Sx, Sy, n], [Sxx, Sxy, Sx], [Sxy, Syy, Sy]])
    U = np.array([Su, Sux, Suy])
    V = np.array([Sv, Svx, Svy])

    # The fit solutioN...
    # where
    #   u = P0 + P1*x + P2*y
    #   v = Q0 + Q1*x + Q2*y
    #
    try:
        invM = np.linalg.inv(M.astype(np.float64))
    except np.linalg.LinAlgError:
        raise SingularMatrixError(
            "Singular matrix: suspected colinear points."
        )
    P = np.dot(invM, U).astype(np.float64)
    Q = np.dot(invM, V).astype(np.float64)
    if not (np.all(np.isfinite(P)) and np.all(np.isfinite(Q))):
        raise ArithmeticError('Singular matrix.')

    # Return the shift, rotation, and scale changes
    result = build_fit(P, Q, 'general')
    resids = xy - np.dot(uv, result['fit_matrix']) - result['offset']
    result['rms'] = resids.std(axis=0)
    result['resids'] = resids
    result['rmse'] = float(np.sqrt(np.mean(2 * resids**2)))
    result['mae'] = float(np.mean(np.linalg.norm(resids, axis=1)))

    return result
Performs a simple fit for the shift only between
        matched lists of positions 'xy' and 'uv'.

        Output: (same as for fit_arrays)
        =================================
        DEVELOPMENT NOTE:
            Checks need to be put in place to verify that
            enough objects are available for a fit.
        =================================