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

1
  • I'd start by covering the basics of extending Python first. See: docs.python.org/extending Commented Mar 9, 2011 at 19:33

1 Answer 1

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]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.