Skip to content

Fitting

William Wood edited this page Dec 28, 2019 · 7 revisions

Mathematical Functions and Fittings

Fitting data in JISA is handled by the Fitting class. This contains many static methods for performing different types of fits. Each of these can be done using separate x-value and y-value Matrix objects or by using a list of Data objects representing each point.

Contents

  1. Function Objects
  2. Fit Objects
  3. Linear Fit
  4. Polynomial Fit
  5. Gaussian Fit
  6. Harmonic Fit (Cosine)
  7. General Fitting

Function Objects

Top ↑

Mathematical (univariate) functions in JISA are represented as Function objects. You can create one yourself using a lambda like so:

Function function = x -> 5*x + 12;

which is the equivalent of writing

You can evaluate a Function for any value of x by using value(...) like so:

// Value of f(x=1.23)
double value = function.value(1.23);

If the function is differentiable, you can get a new Function object that represents its derivative like so:

Function derivative = function.derivative();

Fit Objects

Top ↑

When performing a fit of any kind, you will have returned to you a Fit object. These represent the results of the fit, containing all fitting The most basic fitting is that of the polynomial fit. This parameters. In general these can always be accessed, either individually or all together, by using:

// Get one parameter
double singleParam = fit.getParameter(index);

// Get all parameters in an array
double[] allParams = fit.getParameters();

The convention of what index corresponds to which parameter will depend on the type of fit. For instance, in a polynomial fit it corresponds to the order of the term (ie 0 is the y-intercept, 1 is the linear term, 2 is the quadratic etc).

However, each type of fit will return its own type of Fit. For instance, a gaussian fit will return a GaussianFit object which has its own methods for retrieving fitted parameters more logically. For example:

double amp = fit.getAmplitude();
double std = fit.getDeviation();

You can extract a Function object represented the fitted function by use of:

Function fitted = fit.getFunction();

Linear Fit

Top ↑

Fitting a straight line to data is easily done by use of the Fitting.linearFit(...) method:

LinearFit fit = Fitting.linearFit(Matrix x, Matrix y);
LinearFit fit = Fitting.linearFit(List<Data> data);

This will return a LinearFit object from which you can get the gradient and intercept of your fit like so:

// y = mx + c
double m = fit.getGradient();
double c = fit.getIntercept();

Polynomial Fit

Top ↑

Polynomial fits of arbitrary order are done by use of the Fitting.polyFit(...) method:

PolyFit fit = Fitting.polyFit(Matrix x, Matrix y, int order);
PolyFit fit = Fitting.polyFit(List<Data> data, int order);

For example if we have the following:

RMatrix x = new RMatrix(5, 1);
x.setValues(0, 1, 2, 3, 4);

// Create y = 3*x^2 + 2
RMatrix y = x.map(a -> 3*a*a + 2);

then we could call:

PolyFit fit = Fitting.polyFit(x, y, 2);

The PolyFit object we get back will contain the polynomial co-efficients which we can extract by use of getParameter(...):

// y = ax^2 + bx + c
double a = fit.getParameter(2); // = 3
double b = fit.getParameter(1); // = 0
double c = fit.getParameter(0); // = 2

The index for each co-efficient is equal to its order. In our case that means the quadratic term is 2, the linear term is 1 and the y-intercept (zeroth-order) is 0.

Gaussian Fit

Top ↑

Fitting a single Gaussian peak can be done through use of:

GaussianFit fit = Fitting.gaussianFit(Matrix x, Matrix y);
GaussianFit fit = Fitting.gaussianFit(List<Data> data);

The form used for fitting a Gaussian is the following:

Therefore, a GuassianFit object lets you get the value of by use of the following:

double a = fit.getOffset();
double b = fit.getAmplitude();
double c = fit.getPosition();
double d = fit.getDeviation();

Harmonic Fit (Cosine)

Top ↑

You can fit a harmonic function by use of:

CosFit fit = Fitting.cosFit(Matrix x, Matrix y);
CosFit fit = Fitting.cosFit(List<Data> data);

This fits the function

You can then extract the parameters from the fit like so:

double a   = fit.getAmplitude();
double w   = fit.getAngFrequency();
double phi = fit.getPhase();

General Fitting

Top ↑

You can fit any general expression using Fitting.fit(...).

Fit fit = Fitting.fit(Matrix x, Matrix y, PFunction toFit, double[] guess);
Fit fit = Fitting.fit(List<Data> data, PFunction toFit, double[] guess);

To define the function to fit, you need to create a PFunction expression. These take an x-value and array of fitting parameters. For instance, if we wanted to fit the function

then we would write:

PFunction toFit = (x, p) -> (p[0]*x / (x*x + p[1])) + p[2];

Where p = {a, b, c}.

We also need to provide the fitting method with an initial guess of the parameters.

PFunction toFit   = (x, p) -> (p[0]*x / (x*x + p[1])) + p[2];
double[]  initial = {1, 1, 1};
Fit       fit     = Fitting.fit(x, y, toFit, initial);

You can then extract the fitted values of the parameters by use of:

double a = fit.getParameter(0);
double b = fit.getParameter(1);
double c = fit.getParameter(2);

For instance, if in-fact

then running the above on 11 points from 0 to 100 results in:

a = 3.0
b = 5.999999999999929
c = 2.0
Before Fit After Fit
Clone this wiki locally