Design Considerations

The design goal is to create an object-oriented computing library with classes that perform common numerical tasks. The most important principle is that the library should add functionality to the user while at the same time retaining as much freedom for the user as possible and allowing for ease of use and extensibility. To that end,

Header file dependencies

For reference, it is useful to know how the top-level header files depend on each other, since it can be difficult to trace everything down. The following are the most "top-level" header files and their associated dependencies within O2scl (there are other dependencies on GSL and the C standard library not listed here).

err_hnd.h : (none)
lib_settings.h : (none)
fparser.h : (none)
array.h: err_hnd.h
exception.h: err_hnd.h
uniform_grid.h: err_hnd.h
vector.h: err_hnd.h uniform_grid.h
sring_conv.h : lib_settings.h
misc.h : err_hnd.h lib_settings.h
test_mgr.h : string_conv.h
uvector_tlate.h: err_hnd.h string_conv.h array.h vector.h
umatrix_tlate.h: err_hnd.h uvector_tlate.h
ovector_tlate.h: err_hnd.h string_conv.h uvector_tlate.h array.h vector.h
omatrix_tlate.h: err_hnd.h ovector_tlate.h omatrix_tlate.h array.h
search_vec.h: err_hnd.h ovector_tlate.h vector.h
funct.h : fparser.h ovector_tlate.h

The use of templates

Templates are used extensively, and this makes for longer compilation times so any code that can be removed conveniently from the header files should be put into source code files instead.

Error handling

Thread safety

Two approaches to thread-safe error handling which are worth comparing: the first is GSL which uses return codes and global function for an error handler, and the second is the Math/Special Functions section of Boost, which uses a separate policy type for each function. One issue is thread safety: the GSL approach is thread safe only in the sense that one can in principle use the return codes in different threads to track errors. What one cannot do in GSL is use different user-defined error handlers for different threads. The Special Functions library allows one to choose a different Policy for every special function call, and thus allows quite a bit more flexibility in designing multi-threaded error handling.

Memory allocation functions

Several classes have allocate() and free() functions to allocate and deallocate memory. If an error occurs in an allocate() function, the function should free() the partial memory that was allocated and then call the error handler. Functions which deallocate memory should never fail and should never be required to call the error handler. Similarly, class destructors should never be required to call the error handler.

Vector design

O2scl vector and matrix types are a hybrid approach: creating objects compatibile with GSL, while providing syntactic simplicity and object-oriented features common to C++ vector classes. In terms of their object-oriented nature, they are not as elegant as the ublas vector types from ublas, but for many applications they are also faster (and they are always at least as fast).

Define constants and macros

There are a couple define constants and macros that O2scl understands, they are all in upper case and begin with the prefix O2SCL_.

Range-checking for arrays and matrices is turned on by default, but can be turned off by defining O2SCL_NO_RANGE_CHECK during the initial configuration of the library. To see how the library was configured at runtime, use the o2scl::o2scl_settings class.

There is a define constant O2SCL_NO_SYSTEM_FUNC which permanently disables the shell command '!' in o2scl::cli (when the constant is defined, the shell command doesn't work even if o2scl::cli::shell_cmd_allowed is true).

The constant O2SCL_DATA_DIR is defined internally to provide the directory which contains the O2scl data files. After installation, this can be accessed in o2scl::o2scl_settings.

All of the header files have their own define constant of the form O2SCL_HEADER_FILE_NAME which ensures that the header file is only included once.

Finally, I sometimes comment out sections of code with

#ifdef O2SCL_NEVER_DEFINED
...
#endif

This constant should not be defined by the user as it will cause compilation to fail.

Parameter ordering

In functions where this makes sense, generally input parameters will appear first, while output parameters or parameters which handle both input and output will appear later.

Global objects

There are four global objects that are created in libo2scl:

All other global objects are to be avoided.

Thread safety

Most of the classes are thread-safe, meaning that two instances of the same class will not clash if their methods are called concurrently since static variables are only used for compile-time constants. However, two threads cannot, in general, safely manipulate the same instance of a class. In this respect, O2scl is no different from GSL.

Documentation design

The commands \comment and \endcomment delineate comments about the documentation that are present in the header files but don't ever show up in the HTML or LaTeX documentation.

Copyright notices

For files where it is appropriate to do so, I have followed the prescription suggested in http://lists.gnu.org/archive/html/help-gsl/2008-11/msg00017.html retaining the GSL copyright notices and putting the O2scl notices at the top. CERNLIB has no such standard, but their licensing information is outlined at http://cernlib.web.cern.ch/cernlib/conditions.html .

Design plans

Boost and linear algebra:
I would like to ensure this class is compatible with boost, and start integrating things accordingly. IMHO object-oriented linear algebra is in a rather sad state at the moment. uBlas and MTL are both promising, however, and I'd like to start implementing some sort of compatibility with uBlas vectors and matrices soon. The uBlas documentation is pretty sparse, but that's the pot calling the kettle a cheap piece of metal.

Other Improvements:
I'm particularly interested in improving the ODE and fitting classes, as well as updating the BFGS2 minimizer. Of course, more examples and better documentation are also a must.

Algorithms to include

Complex numbers
I'm not sure where to go with complex numbers. My guess is that std::complex is not significantly slower (or is faster) than gsl_complex, but it would be good to check this. Then there's the C99 standard, which is altogether different. Unfortunately the interfaces may be sufficiently different that it's not easy to make templated classes which operate on generic complex number types.

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).