Chapter 3: Interpolation and Approximation

.p>.CMCH3.DOC!USER_FCN_LEAST_SQUARES;user_fcn_least_squares

Computes a least-squares fit using user-supplied functions.

Synopsis

#include <imsl.h>

float *imsl_f_user_fcn_least_squares (float fcn (int k, float x), int nbasis, int ndata, float xdata[], float ydata[], ¼, 0)

The type double function is imsl_d_user_fcn_least_squares.

Required Arguments

float fcn (int k, float x)   (Input)
User-supplied function that defines the subspace from which the least-squares fit is to be performed. The k-th basis function evaluated at x is f(k, x) where k = 1, 2, ¼, nbasis.

int nbasis   (Input)
Number of basis functions.

int ndata   (Input)
Number of data points.

float xdata[]   (Input)
Array with ndata components containing the abscissas of the least-squares problem.

float ydata[]   (Input)
Array with ndata components containing the ordinates of the least-squares problem.

Return Value

A pointer to the vector containing the coefficients of the basis functions. If a fit cannot be computed, then NULL is returned. To release this space, use free.

Synopsis with Optional Arguments

#include <imsl.h>

float *imsl_f_user_fcn_least_squares (), int nbasis, int ndata,
float xdata[], float ydata[],
IMSL_RETURN_USER, float coef[],
IMSL_INTERCEPT, float *intercept,
IMSL_SSE, float *ssq_err,
IMSL_WEIGHTS, float weights[],
IMSL_FCN_W_DATA, float fcn ( ), void *data,
0)

Optional Arguments

IMSL_RETURN_USER, float coef[]   (Output)
The coefficients are stored in the user-supplied array.

IMSL_INTERCEPT, float *intercept   (Output)
This option adds an intercept to the model. Thus, the least-squares fit is computed using the user-supplied basis functions augmented by the constant function. The coefficient of the constant function is stored in intercept.

IMSL_SSE, float *ssq_err   (Output)
This option returns the error sum of squares.

IMSL_WEIGHTS, float weights[]   (Input)
This option requires the user to provide the weights.
Default: all weights equal one

IMSL_FCN_W_DATA, float fcn (int k, float x, float *data), void *data,   (Input)
User supplied function that defines the subspace from which the least-squares fit is to be performed, which also accepts a pointer to data that is supplied by the user. data is a pointer to the data to be passed to the user-supplied function.  See the Introduction, Passing Data to User-Supplied Functions at the beginning of this manual for more details.

Description

The function imsl_f_user_fcn_least_squares computes a best least-squares approximation to given univariate data of the form

by M basis functions

(where M = nbasis). In particular, the default for this function returns the coefficients a which minimize

where w = weights, n = ndata, x = xdata, and f = ydata.

If the optional argument IMSL_INTCERCEPT is chosen, then an intercept is placed in the model, and the coefficients a, returned by imsl_f_user_fcn_least_squares, minimize the error sum of squares as indicated below.

Examples

Example 1

This example fits the following two functions (indexed by δ):

1 + sinx + 7 sin3x + δe

where ɛ is a random uniform deviate over the range [1, 1] and δ is 0 for the first function and 1 for the second. These functions are evaluated at 90 equally spaced points on the interval [0, 6]. Four basis functions are used: 1, sinx, sin2x, sin3x.

#include <imsl.h>
#include <stdio.h>
#include <math.h>

#define NDATA   90
                                /* Define function */
#define F(x)    (float)(1.+ sin(x)+7.*sin(3.0*x))

float            fcn(int n, float x);

main()
{
    int         nbasis = 4, i, delta;
    float       ydata[NDATA], xdata[NDATA], *random, *coef;
                                /* Generate random numbers */
    imsl_random_seed_set(1234567);
    random = imsl_f_random_uniform(NDATA, 0);
                                /* Set up data */
    for(delta = 0;  delta < 2;  delta++) {
        for (i = 0; i < NDATA; i++) {
            xdata[i] = 6.*(float)i /((float)(NDATA-1));
            ydata[i] = F(xdata[i]) + (delta)*2.*(random[i]-.5);
        }
        coef = imsl_f_user_fcn_least_squares(fcn, nbasis, NDATA, xdata,
                                                             ydata, 0);
        printf("\nFor delta = %1d", delta);
        imsl_f_write_matrix("the computed coefficients are\n",
                            1, nbasis,  coef, 0);
    }
}


float fcn(int n, float x)
{
    return  (n == 1) ? 1.0 : sin((n-1)*x);
}

Output

For delta = 0
        the computed coefficients are

         1           2           3           4
         1           1          -0           7

For delta = 1
        the computed coefficients are

         1           2           3           4
     0.979       0.998       0.096       6.839

Example 2

Recall that the first example fitted the following two functions (indexed by δ):

1 + sinx + 7 sin3x + δe

where ɛ is a random uniform deviate over the range[1, 1] , and δ is 0 for the first function and 1 for the second. These functions are evaluated at 90 equally spaced points on the interval [0, 6]. Previously, the four basis functions were used: 1, sinx, sin2x, sin3x. This example uses the four basis functions: sinx, sin2x, sin3x, sin4x, combined with the intercept option.

#include <imsl.h>
#include <stdio.h>
#include <math.h>

#define NDATA   90
                                /* Define function */
#define F(x)     (float)(1.+ sin(x)+7.*sin(3.0*x))

float            fcn(int n, float x);

main()
{
    int         nbasis = 4, i, delta;
    float       ydata[NDATA], xdata[NDATA], *random, *coef, intercept;
                                /* Generate random numbers */
    imsl_random_seed_set(1234567);
    random = imsl_f_random_uniform(NDATA, 0);
                               /* Set up data */
    for(delta = 0;  delta < 2;  delta++){
        for (i = 0;  i < NDATA;  i++) {
            xdata[i] = 6.*(float)i /((float)(NDATA-1));
            ydata[i] = F(xdata[i]) + (delta)*2.*(random[i]-.5);
        }
        coef = imsl_f_user_fcn_least_squares(fcn, nbasis, NDATA, xdata,
                                                                 ydata,
                                             IMSL_INTERCEPT, &intercept,
                                             0);
        printf("\nFor delta = %1d\n", delta);
        printf("The predicted intercept value is  %10.3f\n" ,
                intercept);
        imsl_f_write_matrix("the computed coefficients are\n",
                            1, nbasis,  coef, 0);
    }
}


float fcn(int n, float x)
{
    return sin(n*x);
}

Output

For delta = 0
The predicted intercept value is       1.000
 
        the computed coefficients are

         1           2           3           4
         1           0           7          -0

For delta = 1
The predicted intercept value is       0.978
 
        the computed coefficients are

         1           2           3           4
     0.998       0.097       6.841       0.075

Warning Errors

IMSL_LINEAR_DEPENDENCE                     Linear dependence of the basis functions exists. One or more components of coef are set to zero.

IMSL_LINEAR_DEPENDENCE_CONST       Linear dependence of the constant function and basis functions exists. One or more components of coef are set to zero.

Fatal Errors

IMSL_NEGATIVE_WEIGHTS_2                  All weights must be greater than or equal to zero.


Visual Numerics, Inc.
Visual Numerics - Developers of IMSL and PV-WAVE
http://www.vni.com/
PHONE: 713.784.3131
FAX:713.781.9260