7 Function bases and regression

7.1 Overview

To use these functionalities, you should include pnl/pnl_basis.h.

struct _PnlBasis 
{ 
  /** 
    * Must be the first element in order for the object mechanism to work 
    * properly. This allows any PnlBasis pointer to be cast to a PnlObject 
    */ 
  PnlObject     object; 
  /** The basis type */ 
  int           id; 
  /** The string to label the basis */ 
  const char   *label; 
  /** The number of variates */ 
  int           nb_variates; 
  /** The total number of elements in the basis */ 
  int           nb_func; 
  /** The sparse Tensor matrix */ 
  PnlSpMatInt  *SpT; 
  /** The number of functions in the tensor @p SpT */ 
  int           len_T; 
  /** Compute the i-th element of the one dimensional basis.  As a convention, (*f)(x, 0) MUST be equal to 1 */ 
  double      (*f)(double x, int i, int dim, void *params); 
  /** Compute the first derivative of i-th element of the one dimensional basis */ 
  double      (*Df)(double x, int i, int dim, void *params); 
  /** Compute the second derivative of the i-th element of the one dimensional basis */ 
  double      (*D2f)(double x, int i, int dim, void *params); 
  /** PNL_TRUE if the basis is reduced */ 
  int           isreduced; 
  /** The center of the domain */ 
  double       *center; 
  /** The inverse of the scaling factor to map the domain to [-1, 1]^nb_variates */ 
  double       *scale; 
  /** An array of additional functions */ 
  PnlRnFuncR   *func_list; 
  /** The number of functions in @p func_list */ 
  int           len_func_list; 
  /** Extra parameters to pass to basis functions */ 
  void         *f_params; 
  /** Size of params in bytes to be passed to malloc */ 
  size_t        f_params_size; 
  /** Non linear mapping of the data */ 
  double       (*map)(double x, int dim, void *params); 
  /** First derivative of the non linear mapping  */ 
  double       (*Dmap)(double x, int dim, void *params); 
  /** Second derivate of the linear mapping */ 
  double       (*D2map)(double x, int dim, void *params); 
  /** Extra parameters for map, Dmap and D2map */ 
  void          *map_params; 
  /** Size of @p map_params in bytes to be passed to malloc */ 
  size_t         map_params_size; 
};

A PnlBasis is a family of multivariate functions with real values. Two different kinds of functions can be stored in these families: tensor functions — originally, this was the only possibility — and standard multivariate function typed as PnlRnFuncR.

7.1.1 Tensor functions

Tensor functions are built as a tensor product of one dimensional elements. Hence, we only need a tensor matrix T to describe a multi-dimensional basis in terms of the one dimensional one. These tensors functions can be easily evaluated and differentiated twice, see pnl_basis_eval, pnl_basis_eval_vect, pnl_basis_eval_D, pnl_basis_eval_D_vect, pnl_basis_eval_D2, pnl_basis_eval_D2_vect, pnl_basis_eval_derivs, pnl_basis_eval_derivs_vect.

Three bases are already registered as listed in Table 3. A new tensor basis can be registered using the function pnl_basis_type_register.


PNL_BASIS_CANONICAL

for the Canonical polynomials
PNL_BASIS_HERMITE

for the Hermite polynomials
PNL_BASIS_TCHEBYCHEV

for the Tchebychev polynomials
Table 3: Names of the bases.

The Hermite polynomials are defined by

H (x) = (- 1)n ex22-dn-e- x22-.
 n               dxn

If G is a real valued standard normal random variable, E[Hn(G)Hm(G)] = n!1{n=m }.

The two tensors T and SpT do actually store the same information — T(i,j) is the degree w.r.t the j-th variable in the i-th function. Originally, we were only using the dense representation T, which is far more convenient to use when building the basis but it slows down the evaluation of the basis by a great deal. To overcome this lack of efficiency, a sparse storage was added. Such a basis can be created using one of the following functions.

7.1.2 Local basis functions

A local basis is a family of indicator functions of a Cartesian partition of [-1,1]d. Let (ni)i∈{1,,d} be the number of interval along each direction. An element of the partition write

      d∏ [                    ]
Ak =     - 1 + ki,- 1+ ki-+-1
     i=1       ni        ni

where k is the multi-index defined by ki ∈{0,,ni - 1} for all i ∈{1,,d}. These functions are orthogonal for the standard L2 scalar product; this property is used by pnl_basis_fit_ls. Note that they are not differentiable.

We provide the helper function pnl_basis_local_get_index to compute the linear representation of the multi-index k.

If the domain you want to consider is not [-1,1]d, use the functions pnl_basis_set_domain, pnl_basis_set_reduced and pnl_basis_set_map to map your product space into [-1,1]d.

7.1.3 Standard multivariate functions

These functions are supposed to be PnlRnFuncR.

To make this toolbox more complete, it is now possible to add some extra functions, which are not tensor product. They are stored using an independent mechanism in func_list. These additional functions are only taken into account by the methods pnl_basis_i, pnl_basis_i_vect, pnl_basis_eval and pnl_basis_eval_vect. Note in particular that it is not possible to differentiate these functions and that they are not sensitive to the isreduced attribute. To add an extra function to an existing PnlBasis, call the function

7.2 Functions

Functional regression based on a least square approach often leads to ill conditioned linear systems. One way of improving the stability of the system is to use centered and renormalized polynomials so that the original domain of interest D (a subset of d) is mapped to [-1,1]d. If the domain D is rectangular and writes [a,b] where a,b d, the reduction mapping is done by

          ( xi --(bi +-ai)∕2)
x ∈ D ↦- →     (bi - ai)∕2
                            i=1,⋅⋅⋅,d
(1)

Note that this renormalization does not apply to the extra functions by pnl_basis_add_function but only to the functions defined by the tensor T.

It is also possible to apply a non linear map φi : to the i-th coordinate of the input variable before the reduction operation if any. Then, the input variables are transformed according to

          (                  )
x ∈ D ↦-→   φi(xi)--(bi +-ai)∕2
               (bi - ai)∕2    i=1,...,d
(2)

The following functions are provided for compatibility purposes but are marked as deprecated. Use the functions with the _vect extension.