A brief discussion of the context of this object-oriented scientific computing library.
O2scl takes advantage of homebrew and travis-ci.org to make sure installation and testing works.
Function objects can now be defined and manipulated very succinctly:
double a=-0.9, b=0.9; o2scl::root_brent_gsl<> solver; std::function<double(double)> f=[](double x){ return sin(x)-0.1; }; solver.solve(a,b,f); cout << a << endl;(adapted from O2scl's ex_lambda.cpp example)
Python has enabled fast development, but we still want fast execution from C++. GSL is great for many problems, but Fourier transforms are better done in FFTW and linear algebra is better implemented in uBlas, Eigen, or Armadillo.
Among these options are uBlas, Eigen, Armadillo, and more. However, none of them seem to agree on the basics of how these objects should be written. For example, consider the basic reallocation method, resize(). In the C++11 standard, this is written
void std::vector::resize(size_type n)
and it is assumed that the action of resize() is destructive. On the other hand, in uBlas, resizes are non-destructive by default
void ublas::vector::resize(size_type n, bool preserve=true)
Armadillo vectors follow the same behavior of std::vector for destructive resizes, but introduce a new notation for non-destructive ones
void arma::row::set_size(size_t n)Eigen operates similarly, but uses the name conservativeResize() for non-destructive resizes. O2scl, for the time being, presumes that all resizes are destructive, and uses a notation similar to the C++11 standard for its resize methods.
(Eventually, a set of linear algebra type traits is necessary to describe how linear algebra types behave and how they interact with each other. )
Obtaining rows and columns of matrices (without a copy) is also not trivial. In uBlas, the row of a matrix is obtained by using the constructor of a matrix_row object. In Armadillo and Eigen, this is performed by using the .row() method, resulting in a vector object of an unusual type. O2scl subsumes some of this complexity into a function o2scl::matrix_row, which can be used with any of these linear algebra libraries
// With uBlas typedef boost::numeric::ublas::matrix<double> matrix; typedef boost::numeric::ublas::matrix_row<ubmatrix> matrix_row; matrix_row r1=o2scl::matrix_row<matrix,matrix_row>(m1,2); // With Eigen Eigen::MatrixXd::RowXpr r2= o2scl::matrix_row<Eigen::MatrixXd,Eigen::MatrixXd::RowXpr>(m2,2); // With Armadillo arma::subview_row<double> m1= o2scl::matrix_row<arma::mat,arma::subview_row<double> >(m3,2);
Heterogeneous architectures also naturally lead to more data types to help contain and manipulate data on them. The issues described above will likely become more commonplace.
At the same time, C++ offers quite a bit of syntactic simplicitly, with relatively little cost in speed. Even though linear algebra libraries do not agree on the details of the interface, they can speed up development time considerably.
GSL does, of course, but is more difficult to use with C++ member functions and generic vector types. Two-dimensional interpolation has only recently found its way into the GSL repository yet has been in O2scl for many years. (In fact, some GSL improvements were guided by O2scl development.)
O2scl is still in beta, so this is a perfect time to let me know if it is useful to you (or not), and feel free to make comments or suggestions.