472,093 Members | 2,510 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,093 software developers and data experts.

Python/C API, Numeric Python, Type Conversion

1
Hi,

I am posting here to seek for help on type conversion between Python (Numeric Python) and C.

Attachment A is a math function written in C, which is called by a Python program. I had studied SWIG and Python/C API a bit. I was able to pass numeric array (Numeric Python) into the C function and access/change these arrays.

Problem I am having is that I couldn't quite get the array converted back to some PyObject or something that Python Interpreter can understand. So, alternatively I passed an empty numeric array as well as other arguments, and had return value(result) stored in that chunk of place. It sort of worked. However, if such function was called few times, it would result in segmentation fault.

This is a lousy way to get around the return type matter, and probably is causing seg fault. Besides a correct type conversion, a proper SWIG interface probably could've saved all the fuss, maybe? ( attachment B is the SWIG interface I am using for this function)

I am trying to study more on C API section of NumPy document, and to gain more knowledge off SWIG(which I only understand very basic way of it). Any feedback will be great. Thanks for your time, friends. Truly appreicate your precious time.

Ronnie


P.S. Those PyObject pointers are created with Numeric.Array( data, Numeric,Float64).


Attachment A
Expand|Select|Wrap|Line Numbers
  1. /*
  2. *******************************************************************************
  3. *
  4. *  Function Name : 
  5. *     cressman()
  6. *  
  7. *  Usage :
  8. *     PyObject* cressman
  9. *     (int nx,int ny,PyObject* result,PyObject* us,PyObject* rlats, PyObject* 
  10. *      rlons, int nst,float disinf,float slon,float elon,float slat,float elat)
  11. *
  12. *  Description :
  13. *     Objective analysis by Cressman method
  14. *
  15. *  Aumument :
  16. *     nx(I)    : x-dimension of grid data 
  17. *     ny(I)    : y-dimension of grid data
  18. *     result(I): an empty result set
  19. *     us(I)    : input station data                
  20. *     rlons(I) : x-coordinate of station
  21. *     rlats(I) : y-coordinate of station
  22. *     nst(I)   : number of station data
  23. *     disinf(I): influence radius distance(km)
  24. *     slon(I)  : x-coordinate of start grid longitude
  25. *     elon(I)  : x-coordinate of end grid longitude
  26. *     slat(I)  : y-coordinate of start grid latitude
  27. *     elat(I)  : y-coordinate of end grid latitude
  28. *     
  29. *   Data Files : None
  30. *  
  31. *   Called Function :
  32. *     ardist()    
  33. *
  34. *   Return Value : 
  35. *      data    : grid data value    
  36. *
  37. *   Linking Lib : None
  38. *
  39. ***************************************************************************                         
  40. */
  41. PyObject* cressman
  42. (int nx,int ny,PyObject* result,PyObject* us,PyObject* rlats, PyObject* rlons, int nst,float disinf,float slon,float elon,float slat,float elat)
  43. {
  44.    if( nst < 1)
  45.        return;
  46.  
  47.    // initialization    
  48.    float xdelta,ydelta,disinf2,wsum,usum,xx,yy;
  49.    float **data;
  50.    float data_ave, sum;
  51.    int i,j,k,count;
  52.  
  53.    // PyObject(python-C API) related 
  54.    PyArrayObject *p_us, *p_rlats, *p_rlons, *p_result;
  55.    double *array_us, *array_rlats, *array_rlons, *array_result;
  56.  
  57.    p_us= (PyArrayObject *) us;
  58.    p_rlats= (PyArrayObject *) rlats;
  59.    p_rlons= (PyArrayObject *) rlons;
  60.    p_result= (PyArrayObject *) result;
  61.  
  62.    if ( nst != p_us->dimensions[0])
  63.        return;
  64.  
  65.    array_us = (double*) p_us->data;
  66.    array_rlats = (double*) p_rlats->data;
  67.    array_rlons = (double*) p_rlons->data;
  68.    array_result = (double*) p_result->data;
  69.  
  70.    // find out data avg
  71.    sum=0;
  72.    count=0;
  73.    for (i=0;i<nst;i++)
  74.    { 
  75.        if (array_us[i]>spv)
  76.        {
  77.            sum+=array_us[i];
  78.            count++;
  79.        }
  80.    }
  81.    if (count!=0)
  82.        data_ave= sum / count;
  83.  
  84.    xdelta = (elon - slon)/(nx -1);  
  85.    ydelta = (elat- slat)/(ny -1);
  86.    disinf2 = pow(disinf,2);
  87.  
  88.    for( i = 0; i < ny; i++)
  89.    {
  90.         for( j = 0; j < nx; j++)
  91.         {
  92.              wsum = 0.;
  93.              usum = 0.;
  94.              xx = slon + j*xdelta;
  95.              yy = slat + i*ydelta;
  96.  
  97.              for( k = 0; k < nst; k++)
  98.              {
  99.                   if( array_us[k] <= spv )
  100.                       continue;
  101.  
  102.                   //ardist just a function that calculates distance between 2 points
  103.                   float adist = ardist(array_rlons[k],array_rlats[k],xx,yy);
  104.                   if( adist > disinf )
  105.                       continue;
  106.                   float adist2 =  pow(adist,2);
  107.                   float w = (disinf2 - adist2)/(disinf2+adist2);
  108.  
  109.                   wsum = wsum + w;
  110.                   usum = usum + (w*array_us[k]);       
  111.              }
  112.              if( wsum != 0 )
  113.                  //data[i][j] = usum/wsum;
  114.                  array_result[i*nx+j] = usum/wsum;
  115.              else
  116.                  //data[i][j] = data_ave;
  117.                  array_result[i*nx+j] = data_ave;
  118.  
  119.         }
  120.    }
  121.    return result;       
  122. }
  123.  
Attachment B - SWIG interface
Expand|Select|Wrap|Line Numbers
  1.  /* objmod.i */
  2.  %module objmod
  3.  %{
  4.  /* Put header files here or function declarations like below */
  5.  PyObject* cressman(int nx,int ny,PyObject* result,PyObject* us,
  6.                      PyObject* rlats,PyObject* rlons,int nst,float disinf,
  7.                      float slon,float elon,float slat,float elat);
  8.  float ardist(float rlon,float rlat,float xx,float yy);
  9.  %}
  10.  
  11.  extern PyObject* cressman(int nx,int ny,PyObject* result,PyObject* us,
  12.                             PyObject* rlats,PyObject* rlons,int nst,float disinf,
  13.                             float slon,float elon,float slat,float elat);
  14.  extern float ardist(float rlon,float rlat,float xx,float yy);
  15.  
Aug 6 '07 #1
0 1999

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

467 posts views Thread by mike420 | last post: by
1 post views Thread by youngdubliner | last post: by
2 posts views Thread by martino | last post: by
96 posts views Thread by Gustav Hållberg | last post: by
2 posts views Thread by ajikoe | last post: by
135 posts views Thread by robinsiebler | last post: by
3 posts views Thread by Ethan Furman | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.