недопустимые типы 'float [int]' для ошибки индексации массива и передачи переменных в scipy.weave.inline - PullRequest
0 голосов
/ 28 сентября 2011

Я играл с встроенным инструментом Сципи (через переплетение) для развлечения, но у меня возникли некоторые проблемы.Мой C ржавый, и у меня такое ощущение, что я упускаю что-то простое.

Функция, приведенная ниже, предназначена для работы с массивом 3D float32.Я использую огромный набор атмосферных данных в сетке, но это должно работать с любым трехмерным массивом.Затем он берет сетку и получает среднее арифметическое по оси i для каждой точки j, k (то есть, если i - это ось времени, j и k - широта / долгота, то я усредняю ​​по времени для каждой точки сетки).

Я надеюсь, что мой код делает это и избегает непонятных 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 ]

1 голос
/ 29 сентября 2011

вы можете сначала создать массив out в python и передать его в C ++. В C ++ вы можете получить форму x с помощью Nx [0], Nx [1], Nx [2]. И вы можете использовать макросы, определенные для массива, для доступа к его элементам. Например: X3 (k, j, i) - это то же самое, что x [k, j, i] в python, а OUT2 (j, i) - это то же самое, что out [j, i] в python. Вы можете просмотреть автоматически созданный код 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)

Вы также можете использовать блиц-конвертер для доступа к массиву в C ++. Для получения подробной информации, попробуйте Google: weave.converters.blitz

0 голосов
/ 29 сентября 2011

C не поддерживает динамический размер массива, например out [xj] [xk]. Вы должны либо жестко закодировать размеры, либо использовать malloc или что-то, поддерживаемое Weave, для динамического распределения данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...