How to call the NAG C library from Python using ctypes
The NAG library is possibly the most comprehensive numerical library available today with over 1500 functions and a long and distinguished history going back almost 40 years. Although it is commercial, NAG is a not-for-profit company and has donated large amounts of code to the open source community over the years. The library covers many application areas including special functions, optimization, curve fitting, statistics, numerical differentiation and linear algebra among others with even more coming up in the next release. It has been available in several different programming languages over the years but these days you can get it in essentially four flavours – The NAG Fortran Library, The NAG C Library, the Maple-NAG connector and the NAG Toolbox for MATLAB.
I have been supporting users of the NAG library at Manchester University for a few years now and one of the most common reactions I get from a potential user of the NAG libraries when they see the list of available languages is to say ‘I don’t program in any of those – I program in XYZ – so the NAG library is no use to me.’ where XYZ might be Java, Perl, Visual Basic, Python, R or one of any number of weird and wonderful possibilities.
It turns out that YOUR choice of language almost doesn’t matter as far as NAG is concerned since, with a bit of work, you can call the NAG routines from pretty much any language you care to mention. Put another way, NAG program in Fortran (and C) so you don’t have to. One language that has been mentioned a lot recently is Python.
Mat Cross, an employee of NAG, wrote a guide a little while ago giving detailed instructions on how to call the NAG Fortran library from Python using a module called F2PY and very nice it is too. However, some people are never happy and almost as soon as the article was published I started getting queries about the NAG C library and Python. As far as I could tell this particular combination hadn’t been covered by anyone before so I rolled up my sleeves to see what I could come up with.
After all, how hard could it be?
I have lost count of the number of times I have regretted uttering that particular phrase but in this case, thanks to a wonderful Python module called ctypes, the answer turns out to be ‘Not nearly as hard as you might expect’.
The results of my investigations will be posted on Walking Randomly over the next few weeks and will include several examples of how to use the NAG C library within Python. I’ll start off with the simplest of NAG functions and steadily move towards some of the most complex. On the way we will cover several areas of numerical mathematics including special functions, numerical quadrature, root finding and optimization.
I will initially be concentrating on Ubuntu Linux since that is my favourite development environment but I am aware that users of both NAG and Python make use of many platforms including Windows and Mac OS X. If there is sufficient interest then I will make other platform-specific articles available in the future.
The list below contains links to all of the articles published in the series so far and will be expanded as new ones come online so this post will eventually serve as an index to the whole series. Extra topics may be considered on request.
Topic List (will be expanded as new articles are available)
- Making simple NAG C functions available to Python
- Plotting the Cosine Integral using NAG and matplotlib
- Callback functions (The example code given is for finding the zero’s of an equation)
- Structures (The example code given is for Numerical Integration)
- Callback functions with communication (The example code solves a simple 1d minimization problem)
- PyNAG – A Python package for interfacing with the NAG C Library
The NAG C library is available for a wide range of platforms and C compilers (representing 26 different combinations when I last counted) but I only wanted to focus on one for the sake of sanity! In particular, I am using cllux08dgl throughout this series which is for 32bit Linux and was compiled using the gcc compiler. I am using version 8.10 of Ubuntu Linux.
I imagine that most of what I write will be directly transferable, with minor modifications, to other versions of the NAG C library. After all Python is quite portable but there may be some differences if you are using a platform wildly different from mine. Where I am able, I will help people get the examples working on their platform of choice but reserve the right to refer you to the NAG support team if necessary.
Finally, I have developed all of this series using 2.5.2 and have no idea if it will work in later versions or not.