我想使用numpy API進行泛化的ufunc。輸入是一個(n x m)
矩陣和一個標量,輸出是兩個矩陣((n x p)
和(p x m)
)。但我不知道該怎麼做。有人可以幫助我嗎? 在初始化函數我使用PyUFunc_FromFuncAndDataAndSignature
功能與簽名:numpy中的廣義通用函數
"(n,m),()->(n,p),(p,m)"
我可以讀取輸入(矩陣和標量),但我想用標量輸入像在簽名的p維。可能嗎?
下面一個例子代碼,只打印輸入:
#include "Python.h"
#include "math.h"
#include "numpy/ndarraytypes.h"
#include "numpy/ufuncobject.h"
static PyMethodDef nmfMethods[] = {
{NULL, NULL, 0, NULL}
};
static void double_nmf(char **args, npy_intp *dimensions,
npy_intp* steps, void* data)
{
npy_intp i, j,
n = dimensions[1], //dimensions of input matrix
m = dimensions[2]; //
printf("scalar: %d\n",*(int*)args[1]); // input scalar
// just print input matrix
printf("Input matrix:\n");
for(i=0;i<n;i++){
for(j=0;j<m;j++){
printf("%.1f ",*(double*)(args[0]+8*(i*m+j)));
}
printf("\n");
}
return;
}
static PyUFuncGenericFunction nmf_functions[] = { double_nmf };
static void * nmf_data[] = { (void *)NULL };
static char nmf_signatures[] = { PyArray_DOUBLE, PyArray_INT, PyArray_DOUBLE, PyArray_DOUBLE };
char *nmf_signature = "(n,m),()->(n,p),(p,m)";
PyMODINIT_FUNC initnmf(void)
{
PyObject *m, *d, *version, *nmf;
m = Py_InitModule("nmf", nmfMethods);
if (m == NULL) {
return;
}
import_array();
import_umath();
d = PyModule_GetDict(m);
version = PyString_FromString("0.1");
PyDict_SetItemString(d, "__version__", version);
Py_DECREF(version);
nmf = PyUFunc_FromFuncAndDataAndSignature(nmf_functions, nmf_data, nmf_signatures, 1,
2, 2, PyUFunc_None, "nmf",
"", 0, nmf_signature);
PyDict_SetItemString(d, "nmf", nmf);
Py_DECREF(nmf);
}
此代碼編譯和作品。的Python腳本是在這裏:
#/usr/bin/python
import numpy as np
import nmf
x = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]])
y,z = nmf.nmf(x,2)
print "Shapes of outputs: ", y.shape, z.shape
和端子輸出爲:
scalar: 2
Input matrix:
1.0 2.0 3.0 4.0 5.0
6.0 7.0 8.0 9.0 10.0
11.0 12.0 13.0 14.0 15.0
16.0 17.0 18.0 19.0 20.0
Shapes of outputs: (4, 1) (1, 5)
我的疑問是如何(在情況2)使用標量輸入等輸出矩陣的p維。在例子p = 1中,我沒有設置它。
請顯示原始數組,標量和最終數組的最小示例。 – wwii 2014-10-09 18:57:23
不幸的是,這是不可能的。通過gufuncs的簽名解析器工作,你的輸出數組總是有'p == 1'。如果你需要其他值,唯一的方法就是預先分配輸出數組,並使用你的gufunc的'out'關鍵字參數傳遞它們。 NumPy 1.10可能會帶來額外的功能,可能使你想要做的事情。 – Jaime 2014-10-09 19:13:22
你是說你想'p'由標量輸入的*值*決定嗎?如果是這樣,那麼你一個gufunc不是你想要的 - 只是做一個常規功能。 gufunc的想法是它可以在參數上進行廣播,但是假設我想傳遞兩個不同的標量[3,4] - 輸出形狀不能是(2,n,3),(2,3) ,m)和(2,n,4),(2,4,m)。 (2來自廣播輸入矢量。) – 2014-10-09 19:57:09