Design of C++ Mathematical Libraries

LCG Project | LCG Applications Area

SEAL Project | Project Portal

 

$Date: 2004/11/09 10:46:36 $

Introduction

These library written in C++ provide the mathematical functionality required by the LHC experiments. Background information is the inventory of mathematical functions

Requirements

Main user of this software will be :

General requirements

MathLib Components

We have identified the following components according to the functionality. A component a priori is not a priori relflects in a unique library. See packaging for library organization and distribution

Mathematical Functions

This library contains free functions in the namespace mathlib. At the beginning will consist of only one library containing the most used functions. If the size of this library will become too large, functions which will be used less will be demoted to an additional library.

Library content

These functions are special functions and statistical functions. The functions we propose for the first version of the library are the following

Special functions

Statistical functions

This functions include probability density functions and corresponding cumulative distributions (integrals of the pdf)

Others

  • Polynomial (evaluation)
  • Detailed Design

    Following the C++ proposal, the library consists of free functions in a namespace. We will have one (or more) header files defining the functions with no reference to the implementation.

    As first choice we prefer to hide the implementation, therefore the functions will not be inlined. This will cause a small performance penalty, which is negligible for computational expensive functions.

    Here is the effect on performances on a function evaluating a polynomial as function of order.

    Here is example for Bessel function :

    SpecFunc.h
    namespace mathlib { 
    	double cyl_bessel_j(double nu, double x);
    	double cyl_bessel_i(double nu, double x);
        ....
    	double erfc (double x);
    }
    
    Implementation based on GSL
    SpecFunc.cpp
    #include "MathFunc/SpecFunc.h"
    #include "gsl/gsl_sf.h"
    
    mathlib::cyl_bessel_j( double nu, double x) { 
    	return gsl_sf_bessel_Jnu (nu, x); 
    }
    

    Error Handling

    In the shown example no error handling is provided. In reality we want to handle them and the proposed approach is to use the Exception classes from the standard library. Errors that can occur in functions are:

    C++ Function Classes

    This library contains the interface and classes to describe generic functions. These are needed to have a uniform way of using the numerical algorithms. Therefore with same function object, the user can evaluate its integral numerically, can used to fit his data or can compose it with other function objects. In addition, either using the same interfaces of through simple adapters the function objects can be passed to tools like ROOT to be displayed. The ideas here are inspired by the Generic functions of CLHEP and it is adapted to our needs.

    We provide the following classes and interfaces:

    Interfaces:

    Base Classes:

    Concrete Classes

    Here are classes representing the various type of functions (especially statistical one), such as Gaussian, Exponential, etc...., inheriting either from ParamFunction or from PdfFunction. A typical use-case for this functions is in fitting, the user, compose in a trivial way it's own model functions using the provided functions from the library.

    Numerical Algorithms

    This library will contain the various algorithms. We describe here their design and how the make use of the C++ Function library. The basic idea here is to separate as much as possible the interface of the numerical algorithm to the underlying implementation of the algorithm. We plan to have a core numerical algorithms library which we'll have the algorithm interfaces and concrete classes with default implementations, which in the majority of the cases will be based for the moment on GSL. Addition implementation of the algorithms which can be present in a different library will be able to be added and used with a plug-in manager. The plugin-manager will reside in a separate library.

    Numerical Integration

    We will have an interface Integrator. This interface will define a method to set and retrieve control parameters, like tolerance, number of points, etc.., then the following method to perform the integration will be present:
    double eval(const IGenFunction & f, double a, double b);
    
    The concrete class implementing the Integrator interfaces, would have in addition the following method based on a generic (templated) function class :
    template <class UserFunc>
    double eval(const UserFunc & f, double a, double b);
    
    Having a templated method taking a function, which needs just to implement the operator(), gives the advantage of avoid virtual calls, when evaluating the function values inside the algorithm. Since templated member function cannot be virtual, this method can be present only in the concrete class and not in the interface.

    We plan to have the first integrator implementations based on GSL. In this case, in addition to the template method, the class will have also the following method based on function pointers, for users which do not want to use our function interfaces and want to call the integrator class directly using a free C function, avoiding the use of adapters. We use the same signature for the function pointer as GSL.

    typedef double ( * FuncPointer ) ( double, void * ); 
    double eval( FuncPointer f, double a, double b);
    
    In GSL, there are various numerical integration algorithms. We plan to include these algorithms: We have two possibility for implementing these algorithms. One is having a common class and choosing the type of algorithms using a string (or an enumeration parameters) in the constructor. The second possibility is having a different class for each type of algorithm. In this case would be convenient to present to the user a common base class inheriting from the Integrator interface which creates the different class representing each algorithm behind.

    Numerical Differentiation

    This algorithm provides differentiation by finite difference. It will consists of a set of functions in a Differentiator class. Required methods for the interface, would be:
    double eval( const IGenFunction & f, double x);
    
    // in case of singularity or if f is defined only for values greater than x 
    double evalForward( const IGenFunction & f, double x);
    // in case of singularity or if f is defined only for values smaller than x 
    double evalBackward( const IGenFunction & f, double x);
    
    In addition, we will have like in the Integrator class, the template methods and those based on the free function pointer, double ( * ) (double, void *)
    template <class UserFunc>
    double eval(const UserFunc & f, double x);
    typedef double ( * FuncPointer ) ( double, void * ); 
    double eval( FuncPointer f, double x);
    

    Root Finders

    We'll have here algorithms to find the root of a function in one or multi-dimensions. Interfaces will exist in both case, using function classes of type IGenFunction or IMDGenFunction. In addition exist algorithms which needs the function gradient. A Root Finder base class is created taking as argument the algorithm type. The proposed methods for the are:
    double  
    

    Interpolation

    Random numbers

    The random number library will be implemented according to the design proposed for the C++ Standard library (see proposal document). This library will provide a palette of random number generators and possibility of generating random numbers according to pre-defined distributions.

    The development of this library has a lower priority, since very good solution exist, like CLHEP, which is widely used by our community.

    Linear Algebra

    Also for the linear algebra, various library already exist, and before developing any new one, we evaluate the exist ones.

    Library packaging

    We expect to have this libraries:
    Contact: Lorenzo Moneta
    last update: 30 August 2004