数组下标错误的无效类型'float [int]'并将变量传递给scipy.weave.inline

时间:2011-09-28 18:32:03

标签: python c numpy scipy

我一直在玩Scipy的内联工具(通过编织)以获得乐趣,但我遇到了一些麻烦。我的C生锈了,我觉得我错过了一些简单的东西。

以下功能旨在采用3D float32 numpy数组。我正在使用大量网格化大气数据,但这适用于任何3D阵列。然后,这将获取网格并获得跨越轴i的算术平均值,对于每个点j,k(即,如果i是时间轴,则j和k是纬度/经度,那么我对于每个网格点对时间进行平均)。

我希望我的代码正在执行此操作并避免使用nunky NaN(我相信isnan()适用于内联C / C ++ ......?)。但是,无论是否这样做,我都无法在没有错误的情况下编译代码,例如:

tools.py: In function ‘PyObject* compiled_func(PyObject*, PyObject*)’:
tools.py:93:45: error: invalid types ‘float[int]’ for array subscript
tools.py:95:51: error: invalid types ‘float[int]’ for array subscript
tools.py: In function ‘PyObject* compiled_func(PyObject*, PyObject*)’:
tools.py:93:45: error: invalid types ‘float[int]’ for array subscript
tools.py:95:51: error: invalid types ‘float[int]’ for array subscript

我认为我正在宣布和正确地进行初始化,所以也许某些东西没有按照我认为的方式传递给编织?如果有人可以帮我解决这个问题,我会很高兴。这是功能:

from scipy.weave import inline

def foo(x):
    xi = np.shape(x)[0]
    xj = np.shape(x)[1]
    xk = np.shape(x)[2]
    code = """
           #line 87 "tools.py"
           int n;
           float out[xj][xk];
           for (int k = 0; k < xk; k++) {
               for (int j = 0; j < xj; j++) {
                   n = 0;
                   for (int i = 0; i < xi; i++) {
                       if (!isnan(x[i][j][k])) {
                           n += 1;
                           out[j][k] += x[i][j][k];
                       }
                   }
                   out[j][k] = out[j][k]/n;
               }
           }
           return_val = out;
           """
    awesomeness = inline(code, ['x', 'xi', 'xj', 'xk'], compiler = 'gcc')
    return(awesomeness)

2 个答案:

答案 0 :(得分:1)

您可以先在python中创建out数组,然后将其传递给C ++。在C ++中,您可以通过Nx [0],Nx [1],Nx [2]得到x的形状。您可以使用为数组定义的宏来访问它的元素。例如:X3(k,j,i)与python中的x [k,j,i]相同,而OUT2(j,i)与python中的out [j,i]相同。您可以查看自动创建的C ++代码,以了解可用于数组的变量和宏。获取C ++代码的文件夹:

from scipy import weave
print weave.catalog.default_dir()

我的编译器不支持isnan(),所以我使用tmp == tmp来检查它。

# -*- coding: utf-8 -*-
import scipy.weave as weave
import numpy as np

def foo(x):
    out = np.zeros(x.shape[1:])
    code = """
    int i,j,k,n;
    for(i=0;i<Nx[2];i++)
    {
        for(j=0;j<Nx[1];j++)
        {
            n = 0;
            for(k=0;k<Nx[0];k++)
            {
                double tmp = X3(k,j,i);
                if(tmp == tmp) // if isnan() is not available
                {
                    OUT2(j,i) += tmp;
                    n++;
                }
            }
            OUT2(j,i) /= n;
        }
    }
    """
    weave.inline(code, ["x","out"], headers=["<math.h>"], compiler="gcc")
    return out

np.random.seed(0)    
x = np.random.rand(3,4,5)
x[0,0,0] = np.nan
mx = np.ma.array(x, mask=np.isnan(x))
avg1 = foo(x)
avg2 = np.ma.average(mx, axis=0)
print np.all(avg1 == avg2)

您还可以使用blitz converter在C ++中访问数组。有关详细信息,请尝试使用google:weave.converters.blitz

答案 1 :(得分:0)

C不支持像[xj] [xk]那样的动态数组大小调整。你要么必须硬编码大小,要么使用malloc或Weave支持的东西来动态分配数据。