将Python数组传递给使用SWIG的c ++函数 [英] Passing Python array to c++ function with SWIG

查看:1039
本文介绍了将Python数组传递给使用SWIG的c ++函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在python中写了一些代码,它工作得很好。但现在我扩大了我分析的问题的规模,python是可怕的慢。 python代码的慢部分是范围(0,H,1)中的i的

 
x1 =范围(0,W,1)中的j的长度
x2 = i + length

#print i,',',j#检查限制
y1 = j - length
y2 = j + length
IntRed [i,j] = np.mean(RawRed [x1:x2,y1:y2])

H和W等于1024时,函数大约需要5分钟。我写了一个简单的c ++程序/函数执行相同的计算,它排除在不到一秒钟相同的数据大小。

  double summ = 0; 
double total_num = 0;
double tmp_num = 0;
int avesize = 2;
for(i = 0 + avesize; i for(j = 0 + avesize; j {
//循环矩阵的子区域
//如果值不为零,则将它添加到sum
//中,并增加计数器。
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;

}

我有一些其他方法来对二维数组执行。所列举的是一个简单的例子。



我想做的是传递一个Python数组到我的c ++函数,并返回一个二维数组回到python。 >

我已经阅读了一些关于swig,并已经讨论过前面的问题,它似乎是一个可能的解决方案。但我似乎不知道我实际需要做什么。



我可以得到任何帮助吗?感谢

解决方案

您可以使用数组,如下所述: Doc - 5.4.5数组 carray.i std_vector.i
我发现更容易使用std :: vector从SWIG库 std_vector.i 将python列表发送到C ++ SWIG扩展。虽然在你的情况下,优化很重要,它可能不是最佳的。



在您的情况下,您可以定义:



test.i >

 %模块测试
%{
#includetest.h
%}

%includestd_vector.i

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

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

test.h


$ b b

  #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

  #includetest.h

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



如果你运行下面的python代码(我使用python 2.6.5)你可以看到C ++函数可以访问python列表:

 >>导入测试
>>> a = test.Array()
>>>> a = [[0,1],[2,3]]
>>>> test.print_array(a)
[0] [0] = [0]
[0] [1] = [1]
[1] [0] = [2]
[1] [1] = [3]


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

解决方案

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]

这篇关于将Python数组传递给使用SWIG的c ++函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆