'Fit data to this model.
Parameters
model : `~astropy.modeling.FittableModel`
model to fit to x, y, z
x : array
input coordinates
y : array
input coordinates
z : array (optional)
input coordinates
weights : array (optional)
weights
rcond :  float, optional
Cut-off ratio for small singular values of ``a``.
Singular values are set to zero if they are smaller than ``rcond``
times the largest singular value of ``a``.
Returns
model_copy : `~astropy.modeling.FittableModel`
a copy of the input model with parameters set by the fitter'

@fitter_unit_support
def __call__(self, model, x, y, z=None, weights=None, rcond=None):

    if (not model.fittable):
        raise ValueError(u'Model    must    be    a    subclass    of    FittableModel')
    if (not model.linear):
        raise ModelLinearityError(u'Model    is    not    linear    in    parameters,    linear    fit    methods    should    not    be    used.')
    _validate_constraints(self.supported_constraints, model)
    model_copy = model.copy()
    (_, fitparam_indices) = _model_to_fit_params(model_copy)
    if ((model_copy.n_inputs == 2) and (z is None)):
        raise ValueError(u'Expected    x,    y    and    z    for    a    2    dimensional    model.')
    farg = _convert_input(x, y, z, n_models=len(model_copy), model_set_axis=model_copy.model_set_axis)
    has_fixed = any(model_copy.fixed.values())
    if has_fixed:
        fixparam_indices = [idx for idx in range(len(model_copy.param_names)) if (idx not in fitparam_indices)]
        fixparams = np.asarray([getattr(model_copy, model_copy.param_names[idx]).value for idx in fixparam_indices])
    if (len(farg) == 2):
        (x, y) = farg
        if hasattr(model_copy, u'domain'):
            x = self._map_domain_window(model_copy, x)
        if has_fixed:
            lhs = self._deriv_with_constraints(model_copy, fitparam_indices, x=x)
            fixderivs = self._deriv_with_constraints(model_copy, fixparam_indices, x=x)
        else:
            lhs = model_copy.fit_deriv(x, *model_copy.parameters)
        sum_of_implicit_terms = model_copy.sum_of_implicit_terms(x)
        rhs = y
    else:
        (x, y, z) = farg
        if hasattr(model_copy, u'x_domain'):
            (x, y) = self._map_domain_window(model_copy, x, y)
        if has_fixed:
            lhs = self._deriv_with_constraints(model_copy, fitparam_indices, x=x, y=y)
            fixderivs = self._deriv_with_constraints(model_copy, fixparam_indices, x=x, y=y)
        else:
            lhs = model_copy.fit_deriv(x, y, *model_copy.parameters)
        sum_of_implicit_terms = model_copy.sum_of_implicit_terms(x, y)
        if (len(model_copy) > 1):
            if (z.ndim > 2):
                rhs = np.array([i.flatten() for i in z]).T
            else:
                rhs = z.T
        else:
            rhs = z.flatten()
    if model_copy.col_fit_deriv:
        lhs = np.asarray(lhs).T
    if has_fixed:
        if model_copy.col_fit_deriv:
            fixderivs = np.asarray(fixderivs).T
        rhs = (rhs - fixderivs.dot(fixparams))
    if (sum_of_implicit_terms is not None):
        if (len(model_copy) > 1):
            sum_of_implicit_terms = sum_of_implicit_terms[..., np.newaxis]
        rhs = (rhs - sum_of_implicit_terms)
    if (weights is not None):
        weights = np.asarray(weights, dtype=np.float)
        if (len(x) != len(weights)):
            raise ValueError(u'x    and    weights    should    have    the    same    length')
        if (rhs.ndim == 2):
            lhs *= weights[:, np.newaxis]
            rhs = (rhs * weights[:, np.newaxis])
        else:
            lhs *= weights[:, np.newaxis]
            rhs = (rhs * weights)
    if (rcond is None):
        rcond = (len(x) * np.finfo(x.dtype).eps)
    scl = (lhs * lhs).sum(0)
    (lacoef, resids, rank, sval) = np.linalg.lstsq((lhs / scl), rhs, rcond)
    self.fit_info[u'residuals'] = resids
    self.fit_info[u'rank'] = rank
    self.fit_info[u'singular_values'] = sval
    lacoef = (lacoef.T / scl).T
    self.fit_info[u'params'] = lacoef
    if (hasattr(model_copy, u'_order') and (rank != model_copy._order)):
        warnings.warn(u'The    fit    may    be    poorly    conditioned\n', AstropyUserWarning)
    _fitter_to_model_params(model_copy, lacoef.flatten())
    return model_copy
