Передача массива Python в функцию c ++ с помощью SWIG - PullRequest
7 голосов
/ 09 марта 2011

Я написал немало кода на python, и он прекрасно работает.Но теперь я увеличиваю размер анализируемых проблем, а python ужасно медленен.Медленная часть кода Python:

    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])

При значениях H и W, равных 1024, для выполнения функции требуется около 5 минут.Я написал простую программу / функцию на С ++, которая выполняет те же вычисления и выполняет менее чем за секунду с тем же размером данных.

   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;

       }

У меня есть несколько других методов для работы с двумерным массивом.Перечисленные примеры - это простые примеры.

Я хочу передать 2D-массив python моей функции c ++ и вернуть 2D-массив обратно в python.

Я немного прочитало глотке, и уже разыскивал предыдущие вопросы, и кажется, что это возможное решение.Но я не могу понять, что мне действительно нужно делать.

Могу ли я получить какую-либо помощь?Спасибо

1 Ответ

11 голосов
/ 25 марта 2011

Вы можете использовать массивы, как описано здесь: Doc - 5.4.5 Массивы , carray.i или std_vector.i из библиотеки SWIG.Мне проще работать со std :: vector из библиотеки SWIG std_vector.i, чтобы отправить список Python в расширение C ++ SWIG.Хотя в вашем случае, когда оптимизация имеет значение, она не может быть оптимальной.

В вашем случае вы можете определить:

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]);
}

Если вы запустите следующий код Python (я использовал Python 2.6.5), вы увидите, что функция C ++ может получить доступ к Pythonсписок:

>>> 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]
...