{"id":953,"date":"2009-04-16T11:07:06","date_gmt":"2009-04-16T10:07:06","guid":{"rendered":"http:\/\/www.walkingrandomly.com\/?p=953"},"modified":"2009-05-13T19:31:45","modified_gmt":"2009-05-13T18:31:45","slug":"pythonnag-part-4-structures","status":"publish","type":"post","link":"https:\/\/walkingrandomly.com\/?p=953","title":{"rendered":"Python\/NAG Part 4 &#8211; Structures"},"content":{"rendered":"<p>This is part 4 of a series of articles devoted to demonstrating how to call the <a href=\"http:\/\/www.nag.co.uk\/numeric\/CL\/cldescription.asp\">Numerical Algorithms Group (NAG) C library<\/a> from Python.  Click <a href=\"..\/?p=830\">here for the index<\/a> to this series.<\/p>\n<p>The NAG C library makes extensive use of <a href=\"http:\/\/publications.gbdirect.co.uk\/c_book\/chapter6\/structures.html\">C structures<\/a> throughout its code base and so we will need to know how to represent them in Python.\u00a0 For example, the NAG routine <a href=\"www.nag.co.uk\/numeric\/CL\/nagdoc_cl08\/pdf\/D01\/d01ajc.pdf \">d01ajc<\/a> is a general purpose one dimensional numerical integrator and one of it&#8217;s arguments is a structure called Nag_QuadProgress with the following prototype (found in the <strong>nag_types.h<\/strong> file that comes with the NAG C library)<br \/>\n<strong><\/strong><\/p>\n<pre><strong>  typedef struct\r\n  {\r\n    Integer num_subint;\r\n    Integer fun_count;\r\n    double *sub_int_beg_pts;\r\n    double *sub_int_end_pts;\r\n    double *sub_int_result;\r\n    double *sub_int_error;\r\n  } Nag_QuadProgress;<\/strong><\/pre>\n<p>following the ctypes documentation on <a href=\"http:\/\/docs.python.org\/library\/ctypes.html#structures-and-unions\">Structures and Unions<\/a>, I came up with the following Python representation of this structure and it seems to work just fine.<br \/>\n<strong> <\/strong><\/p>\n<pre><strong>class Nag_QuadProgress(Structure):\r\n    _fields_ = [(\"num_subint\", c_int),\r\n                (\"funcount\", c_int),\r\n\t\t(\"sub_int_beg_pts\",POINTER(c_double) ),\r\n                (\"sub_int_end_pts\",POINTER(c_double)),\r\n\t\t(\"sub_int_result\",POINTER(c_double)  ),\r\n\t\t(\"sub_int_error\",POINTER(c_double)  )\r\n\t\t]\r\n<\/strong><\/pre>\n<p><strong><\/strong><\/p>\n<p>This is the only extra information we need in order to write a Python program that calculates the numerical approximation to an integral using the NAG routine d01ajc.  Let&#8217;s calculate the integral of the function 4\/(1.0+x*x) over the interval [0,1].  The code is as follows:<\/p>\n<pre><strong>#!\/usr\/bin\/env python\r\n#Example 3 using NAG C library and ctypes\r\n#d01ajc - one dimensional quadrature\r\n#Mike Croucher - April 2008\r\n#Concept introduced : Creating and using Python versions of structures such as Nag_QuadProgress\r\nfrom ctypes import *\r\nlibnag = cdll.LoadLibrary(\"\/opt\/NAG\/cllux08dgl\/lib\/libnagc_nag.so.8\")\r\n\r\nd01ajc = libnag.d01ajc\r\nd01ajc.restype=None\r\n\r\nclass Nag_QuadProgress(Structure):\r\n    _fields_ = [(\"num_subint\", c_int),\r\n                (\"funcount\", c_int),\r\n\t\t(\"sub_int_beg_pts\",POINTER(c_double) ),\r\n                (\"sub_int_end_pts\",POINTER(c_double)),\r\n\t\t(\"sub_int_result\",POINTER(c_double)  ),\r\n\t\t(\"sub_int_error\",POINTER(c_double)  )\r\n\t\t]\r\n\r\n#define python function\r\ndef py_func(x):\r\n\treturn 4.\/(1.0+x*x)\r\n\r\n#create the prototype for the c callback function\r\nC_FUNC = CFUNCTYPE(c_double,c_double )\r\n\r\n#now create the c callback function\r\nc_func = C_FUNC(py_func)\r\n\r\n#set up the problem\r\na = c_double(0.0)\r\nb = c_double(1.0)\r\nnlimit = c_int(100)\r\nepsr = c_double(0.00001)\r\nifail = c_int(0)\r\n\r\nmax_num_subint=c_int(200)\r\nnlimit = c_int(0)\r\nresult=c_double(0.0)\r\nepsabs= c_double(0.0)\r\nepsrel=c_double(0.0001);\r\nabserr=c_double(0.0);\r\nqp=Nag_QuadProgress()\r\n\r\nd01ajc(c_func,a,b,epsabs,epsrel,max_num_subint,byref(result) ,byref(abserr),byref(qp),ifail )\r\nprint \"Approximation of integral= %s\" %(result.value)\r\nprint \"Number of function evaluations=%s\" % qp.funcount\r\nprint \"Number of subintervals used= %s\" % qp.num_subint\r\n<\/strong><\/pre>\n<p><strong><\/strong><br \/>\nCopy and paste (or download) this to a file called <a href=\"..\/images\/NAG\/d01ajc.py\">d01ajc.py<\/a>, make it executable and run it by typing the following at a bash prompt.<br \/>\n<strong><code><br \/>\nchmod +x .\/d01ajc.py<br \/>\n.\/d01ajc.py<br \/>\n<\/code><\/strong><br \/>\nIf all has gone well then you should get following result<br \/>\n<strong><\/strong><\/p>\n<pre><strong>Approximation of integral= 3.14159265359\r\nNumber of function evaluations=21\r\nNumber of subintervals used= 1\r\n<\/strong><\/pre>\n<p><strong><\/strong><\/p>\n<p>Note that in order to create an instance of the Nag_QuadProgress structure I just do<br \/>\n<code><br \/>\n<strong>qp=Nag_QuadProgress()<\/strong><br \/>\n<\/code><br \/>\nIt is also useful to compare the C prototype of d01ajc<br \/>\n<code><br \/>\n<strong>void nag_1d_quad_gen (double (*f)(double x),<br \/>\ndouble a, double b, double epsabs, double epsrel,<br \/>\nInteger max_num_subint, double *result, double *abserr,<br \/>\nNag_QuadProgress *qp, NagError *fail)<\/strong><br \/>\n<\/code><br \/>\nwith the way I called it in Python<br \/>\n<code><strong><br \/>\nd01ajc(c_func,a,b,epsabs,epsrel,max_num_subint,byref(result) ,byref(abserr),byref(qp),ifail )<\/strong><br \/>\n<\/code><br \/>\nNote how pointer arguments such as<br \/>\n<code><br \/>\n<strong>double *abserr<\/strong><br \/>\n<\/code><br \/>\nare called as follows<br \/>\n<code><br \/>\n<strong>byref(abserr)<\/strong><br \/>\n<\/code><\/p>\n<p>Yet again I have cheated with the NagError parameter and just used <strong>c_int(0)<\/strong> instead of a proper NagError structure.  NagError will be treated properly in a future article.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is part 4 of a series of articles devoted to demonstrating how to call the Numerical Algorithms Group (NAG) C library from Python. Click here for the index to this series. The NAG C library makes extensive use of C structures throughout its code base and so we will need to know how to [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[28,7,31],"tags":[],"class_list":["post-953","post","type-post","status-publish","format-standard","hentry","category-nag-library","category-programming","category-python"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3swhs-fn","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=953"}],"version-history":[{"count":24,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/953\/revisions"}],"predecessor-version":[{"id":1253,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/953\/revisions\/1253"}],"wp:attachment":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}