How Does ``Fit`` Work?
======================
How does ``Fit`` get from a (named) model and some data to a fit? Consider the following example::

  from symfit.api import parameters, variables, Fit
  
  a, b = parameters('a, b')
  x, y = variables('x, y')
  model = {y: a * x + b}

  fit = Fit(model, x=x_data, y=y_data, sigma_y=sigma_data)
  fit_result = fit.execute()

The first thing ``symfit`` does is build :math:`\chi^2` for your model::

  chi_squared = sum((y - f)**2/sigmas[y]**2 for y, f in model.items())

In this line ``sigmas`` is a defaultdict which contains all vars that where given a value, but returns 1 otherwise.

This :math:`\chi^2` is then transformed into a python function which can then be used to do the numerical calculations::

  vars, params = seperate_symbols(chi_squared)
  py_chi_squared = lambdify(vars + params, chi_squared)

We are now almost there. Just two steps left. The first is to wrap all the data into the ``py_chi_squared`` function using ``partial`` into the function to be optimized::

  from functools import partial

  error = partial(py_chi_squared, **data_per_var)

where ``data_per_var`` is a dict containing variable names: value pairs.

Now all that is left is to call ``leastsqbound`` and have it find the best fit parameters::

  best_fit_parameters, covariance_matrix = leastsqbound(
      error,
      self.guesses,
      self.eval_jacobian,
      self.bounds,
  )

That's it! Finally there are some steps to generate a FitResult object, but these are not important for our current discussion.

What if the model is unnamed?
=============================
Simple. Suppose our model had been the following::

  model = a * x + b

  fit = Fit(model, x=x_data, data=y_data, sigma=sigma_data)
  fit_result = fit.execute()

``symfit`` will generate an extra variable in this case: data. Then the previous process will be applied.