Казалось бы, вы не можете передать float ** в numpy C API, потому что они не совместимы с представлениями памяти априори.
В numpy данные в массиве должны находиться в одной непрерывной области памяти (могут быть дыры, но они должны располагаться в одном блоке, как выделено, например, malloc):
data -> | - | - | - | ..... | - | # this is allocated in one block
a0 a1 a2 an
При использовании float **, вероятно, ваша модель памяти:
float** a;
int n = 10, m = 20; // n,m matrix
a = malloc(sizeof(*a) * n) // ten rows
for (int i=0; i < n; ++i) {
a[i] = malloc(sizeof(*a[i]) * m); // one row of 29 items
}
То есть память:
a -> | a[0] | -> | a[0][0] | a[0][1] | a[0][2] |
| a[1] | -> | a[1][0] | ....
На самом деле это почти всегда плохой формат для числовых вычислений, потому что вы не можете передавать данные в одном блоке (плохо для локальности памяти и т. Д.), И почти каждая числовая библиотека стоит того, чтобы использовать ее в этом формате. Смотрите, например это для объяснения.
Тем не менее, предполагая, что вы не можете изменить свой код, вы можете легко преобразовать формат одного блока в формат с плавающей запятой ** без копирования (обратное невозможно):
void convert(float *in, int n, int m, float ***out)
{
float **data;
int i;
data = malloc(sizeof(*data) * n);
for(i = 0; i < n; ++i) {
data[i] = in + i * m:
}
*out = data;
}
И вы вызываете эту функцию как таковую
float **a;
convert((float*)numpy_data, n, m, &a);
Initialise(a, n, m);
На самом деле было бы лучше не выделять в функции из API POV, это просто для того, чтобы дать вам идею для преобразования между обоими форматами.