Basis Functions
The topic Overview of the CLsqFit Class describes how the linear least squares method separates the "rubber function" being fit into the dot product of two vectors: a coefficient vector and a basis vector. The rubber function being fit must evaluate each data point to create a basis vector from its independent variables. These basis vectors are then used to compute the coefficient vector. Mira provides built-in basis functions for fitting an n-dimensional polynomial of up to 10 variables and 100 coefficients and a hyperplane of up to 10 variables. For any other function form, you must write a basis function in your script, then register it with the CLsqFit object. This topic describes how to write your own basis functions.
A basis function declared in the script has a standard interface: it receives 2 or 3 arguments and returns 1 argument. The input arguments describe the number of coefficients being fit, the value(s) of the independent variable(s) being fit and, optionally, the mean coordinates for each independent variable. The basis function uses these arguments to create a basis vector in a lua table and then returns that table. For example, if b is the basis vector assembled by the basis function, then the function must return b.
The basis function is declared using either of the following 2 forms: function(n,x) or function(n,x,m), where the arguments are defined as follows:
n |
The number of coefficients being fit, including forced coefficients. |
c |
A table containing the values of the independent variable(s), or coordinates, at the sample point. The number of table elements equals the number of basis dimensions. |
m |
A table containing the mean coordinate for the independent variable(s). This parameter is optional. The number of table elements equals the number of basis dimensions. |
The optional argument m is used if you want to estimate the fit about the mean coordinate(s) rather than about the origin. Fitting about the mean minimizes the statistical uncertainties of the coefficients. If you don't care to fit about the mean, your basis function can declare only the first 2 arguments. Remember that the coordinate vector c is always passed as a lua table, even if the fit is made to only 1 variable, such as the x coordinate. Therefore, when fitting a single variable, the basis function must use the subscript [1] to access variable dimension 1 of the table it receives. In this class, the term "dimension" is often used in place of "independent variable" or "coordinate". Thus fitting up to 10 independent variables corresponds to fitting up to 10 basis dimensions. After declaring your basis function, you must specify the number of coefficients and dimensions it uses; these are the number of independent variables used by the data points andthe number of coefficients involved in the fit.
The following methods are used along with your basis function:
This method registers your basis function with the CLsqFit object. If you do not call this method, the basis function defaults to the built-in n-dimensional polynomial. |
|
Declares the number of coefficients to be fit, which equals the numbers used by your basis function, as well as the number of basis dimensions. Note: forced coefficients are included in the coefficient count since they are represented in the basis function. |
|
Returns the number of basis dimensions declared by the SetNumCoefs method. |
A basis function defined in your script takes the following form:
Template of a Basis Function
|
declare the function |
|
create a table for the basis vector |
|
code that fills the basis vector |
|
return the status and the basis vector |
|
end of the basis function |
Several examples of a script basis function are given below.
To fit a line, the basis function would look like this:
|
n is the number of coefs; c is the independent variable |
|
declare a lua table for the basis vector |
|
basis vector element [1] is 1 |
|
basis vector element [2] is c[1], or the x coordinate |
|
return the basis vector |
|
end of the basis function |
To fit the line about the mean x coordinate, the basis function would look like this:
|
n is the number of coefs; c is the independent variable; m is the mean |
|
declare a lua table for the basis vector |
|
basis vector element [1] is 1 |
|
basis vector element [2] is c[1] |
|
return the basis vector |
|
end of the basis function |
Note that fitting the line about the origin and about the mean coordinates give different coefficients and errors for the same data.
To fit a quadratic about the origin, the basis function would look like this:
|
n is the number of coefs; c is the independent variable |
|
declare a lua table for the basis vector |
|
basis vector element [1] is 1 |
|
basis vector element [2] is c (the x coordinate) |
|
basis vector element [3] is c^2 |
|
return the basis vector |
|
end of the basis function |
To see how the parameter n might be used, consider fitting a polynomial of order n-1 (the order of a polynomial is the highest power in the polynomial). Including the "constant" term, the polynomial of order n-1 has n coefficients. Here is the basis function:
|
n is the number of coefs; c is the independent variable |
|
declare a lua table for the basis vector |
|
basis vector element [1] is 1 |
|
compute each power of the polynomial recursively |
|
basis vector element [n] is c^(n-1) |
|
end of loop |
|
return the basis vector |
|
end of the basis function |
Note that the tables c and m can contain up to 10 elements for fitting as many as 10 independent variables, or "basis dimensions". For example, if fitting to x,y coordinates, the table c has 2 elements, c[1] for the x coordinate and c[2] for the y coordinate. The following basis function fits a warped plan to an (x,y) surface using using coordinates about the mean:
|
n is the number of coefs; c is the independent variable |
|
declare a lua table for the basis vector |
|
basis vector element b[1] is 1 (the constant term) |
|
b[2] = x |
|
b[3] = y |
|
b[4] = x * y |
|
return the basis vector |
|
end of the basis function |
This case is handled by the built-in, n-dimensional polynomial basis function selected using SetBasisFunc( 1 ). Mira defaults to this basis function if you do not explicitly select a basis function in the script. In this example, you would then specify a 2x2 coefficient fit using SetNumCoefs( {2,2} ). Notice that the multiple coefficient numbers are combined into a table using {}.
As a final example, consider a "hyperplane" of the form f = a[1] + a[2] x + a[3] y + a[4] z + ... The hyperplane fits n+1 coefficients because of the constant term a[1]. This is the same as the built-in basis function selected using SetBasisFunc( 2 ).
|
n is the number of coefs; c is the independent variable |
|
declare a lua table for the basis vector |
|
basis vector element [1] is 1 (the constant term) |
|
|
|
|
|
|
|
return the basis vector |
|
end of the basis function |