Thursday, 29 August 2013

A nag4py update

In a previous post “A quick and dirty way to use the NAG C Library Mark 23 from Python” my colleagues described a method for parsing the NAG C library headers to create Python interfaces using the ctypes modules. Since then we have written a parser in Python to do this, modularised the package into chapters and polished the examples a little. We now have packages for Windows, Mac and Linux available to download.

Python is a great language for getting results quickly. It's often referred to as a batteries included language due to it’s large standard library that includes modules for almost anything you may need. Add that to it’s super clean syntax and the Python Package Index and you can see why it’s so popular. Thanks to packages like Numpy, Scipy and Matplotlib, Python has grown significantly in the area of scientific computing and is gaining ground as the FOSS alternative to MATLAB ®.

Using higher level languages for prototyping such as Python, Matlab or VBA is an excellent way to initially model a problem. Our customers find it extremely beneficial to be able to call the same NAG Library when moving into the production phase and still get same results as the underlying code hasn't changed.


Python e04ccc example


The benefit of parsing the C header files and using gccxml to generate the Python interfaces is all 1700+ NAG Library routines can be called from Python automatically. The drawback with this approach is you don’t get the most pythonic interfaces. One solution is to wrap the ctypes interface with a pure Python interface for the functions you frequently use. Take the simple function g01eac for calculating the one or two tail probability for the standard normal distribution, it’s ctypes specification is as follows:

g01eac.restype = c_double
g01eac.argtypes = [Nag_TailProbability, c_double, POINTER(NagError)]


You will be familiar with the structures used such as NagError if you have used the NAG C Library before. If you want to use Python exceptions to catch errors from the Nag C Library you can find the associated codes and messages in nag_errlist.h. All the header files can be found in the include folder of your C Library distribution. Lets take a look at defining a more pythonic interface normal_prob to wrap nag_prob_normal:


from ctypes import c_double
from nag4py.util import NagError, Nag_LowerTail, Nag_UpperTail, INIT_FAIL
from nag4py.g01 import nag_prob_normal

def normal_prob(x, tail=Nag_LowerTail):
       """
       The lower tail probability for the standard Normal distribution
       >>> normal_prob(1.0)
       0.841344746069
       >>> normal_prob(1.0, tail=Nag_UpperTail)
       0.158655253931
       >>> normal_prob(1.0, tail=1)
       Exception: Argument tail has an illegal value: 1
      """
       x
= c_double(x)
       fail
= NagError()
       INIT_FAIL(fail)

       res
= nag_prob_normal(tail,x,fail)
       
if (fail.code == 70):
             
raise Exception("Argument tail has an illegal value:" , tail)

       
return res

def main():
       
print normal_prob(1.0)
       
print normal_prob(1.0, tail=Nag_UpperTail)
       
print normal_prob(1.0, tail=1)


if __name__ == "__main__": main()


NAG has interfaces for the majority of the languages that are often ranked in the 10 most popular  (TIOBE) and we can now add Python to that list. Would you like to see a fully pythonic NAG Library? We'd like know to know the demand for Python here at NAG so leave us a comment on this post or send in any thoughts to support@nag.co.uk.    

No comments:

Post a Comment

NAG moderates all replies and reserves the right to not publish posts that are deemed inappropriate.