-
Notifications
You must be signed in to change notification settings - Fork 9
Fitting
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.
- Function Objects
- Fit Objects
- Linear Fit
- Polynomial Fit
- Gaussian Fit
- Harmonic Fit (Cosine)
- General Fitting
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();
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();
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 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
.
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();
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();
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 |
---|---|
- Getting Started
- Object Orientation
- Choosing a Language
- Using JISA in Java
- Using JISA in Python
- Using JISA in Kotlin
- Exceptions
- Functions as Objects
- Instrument Basics
- SMUs
- Thermometers (and old TCs)
- PID and Temperature Controllers
- Lock-Ins
- Power Supplies
- Pre-Amplifiers
- Writing New Drivers