7

I have written a good bit of code in python and it works great. But now I'm scaling up the size of the problems that I'm analyzing and python is dreadfully slow. The slow part of the python code is

    for i in range(0,H,1):
       x1 = i - length
       x2 = i + length
       for j in range(0,W,1):
          #print i, ',', j    # check the limits
          y1 = j - length
          y2 = j + length
          IntRed[i,j] = np.mean(RawRed[x1:x2,y1:y2])

With H and W equal to 1024 the function takes around 5 minutes to excute. I've written a simple c++ program/function that performs the same computation and it excutes in less than a second with the same data size.

   double summ = 0;
   double total_num = 0;
   double tmp_num = 0 ;
   int avesize = 2;
   for( i = 0+avesize; i <X-avesize ;i++)
     for(j = 0+avesize;j<Y-avesize;j++)
       {
         // loop through sub region of the matrix
         // if the value is not zero add it to the sum
         // and increment the counter. 
         for( int ii = -2; ii < 2; ii ++)
           {
             int iii = i + ii;
             for( int jj = -2; jj < 2 ; jj ++ )
               {
                 int jjj = j + jj; 
                 tmp_num = gsl_matrix_get(m,iii,jjj); 
                 if(tmp_num != 0 )
                   {
                     summ = summ + tmp_num;
                     total_num++;
                   }


               }
           }
         gsl_matrix_set(Matrix_mean,i,j,summ/total_num);
         summ = 0;
         total_num = 0;

       }

I have some other methods to perform on the 2D array. The one listed is a simple examples.

What I want to do is pass a python 2D array to my c++ function and return a 2D array back to python.

I've read a bit about swig, and have sereached pervious questions, and it seems like it's a possible solution. But I can't seem to figure out what I actually need to do.

Can I get any help? Thanks

JMD
  • 405
  • 1
  • 9
  • 17
  • I'd start by covering the basics of extending Python first. See: http://docs.python.org/extending/ – Santa Mar 09 '11 at 19:33

1 Answers1

11

You can use arrays as it is described here: Doc - 5.4.5 Arrays, the carray.i or std_vector.i from the SWIG library. I find it easier to work with std::vector from the SWIG library std_vector.i to send a python list to a C++ SWIG extension. Though in your case where optimization matters, it may not be the optimal.

In your case you can define:

test.i

%module test
%{
#include "test.h"
%}

%include "std_vector.i"

namespace std {
%template(Line)  vector < int >;
    %template(Array) vector < vector < int> >;
}   

void print_array(std::vector< std::vector < int > > myarray);

test.h

#ifndef TEST_H__
#define TEST_H__

#include <stdio.h>
#include <vector>

void print_array(std::vector< std::vector < int > > myarray);

#endif /* TEST_H__ */

test.cpp

#include "test.h"

void print_array(std::vector< std::vector < int > > myarray)
{
    for (int i=0; i<2; i++)
        for (int j=0; j<2; j++)
            printf("[%d][%d] = [%d]\n", i, j, myarray[i][j]);
}

If you run the following python code (I used python 2.6.5), you can see that the C++ function can access the python list:

>>> import test
>>> a = test.Array()
>>> a = [[0, 1], [2, 3]]
>>> test.print_array(a)
[0][0] = [0]
[0][1] = [1]
[1][0] = [2]
[1][1] = [3]
sherve
  • 300
  • 2
  • 10