2 回答

TA貢獻(xiàn)2021條經(jīng)驗(yàn) 獲得超8個(gè)贊
您最好的選擇可能是在 python 端創(chuàng)建數(shù)據(jù),以便對(duì)其進(jìn)行重新計(jì)數(shù)和垃圾收集。
test.py
import example
import numpy as np
array = np.zeros((3, 2, 4, 4), 'f4')
example.do_math(array, 3, 2)
print(array[0, 0])
例子.cpp
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <Eigen/Dense>
Eigen::Matrix4f get_dummy() {
Eigen::Matrix4f mat_a;
mat_a << 1, 2, 3, 4,
5, 6, 7, 8,
9, 8, 7, 6,
5, 4, 3, 2;
return mat_a;
}
PyObject * example_meth_do_math(PyObject * self, PyObject * args, PyObject * kwargs) {
static char * keywords[] = {"array", "rows", "cols", NULL};
PyObject * array;
int rows, cols;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oii", keywords, &array, &rows, &cols)) {
return NULL;
}
Py_buffer view = {};
if (PyObject_GetBuffer(array, &view, PyBUF_SIMPLE)) {
return NULL;
}
Eigen::Matrix4f * ptr = (Eigen::Matrix4f *)view.buf;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
ptr[i * cols + j] = get_dummy();
}
}
PyBuffer_Release(&view);
Py_RETURN_NONE;
}
PyMethodDef module_methods[] = {
{"do_math", (PyCFunction)example_meth_do_math, METH_VARARGS | METH_KEYWORDS, NULL},
{},
};
PyModuleDef module_def = {PyModuleDef_HEAD_INIT, "example", NULL, -1, module_methods};
extern "C" PyObject * PyInit_example() {
PyObject * module = PyModule_Create(&module_def);
return module;
}
setup.py
from setuptools import Extension, setup
ext = Extension(
name='example',
sources=['./example.cpp'],
extra_compile_args=['-fpermissive'],
include_dirs=['.'], # add the path of Eigen
library_dirs=[],
libraries=[],
)
setup(
name='example',
version='0.1.0',
ext_modules=[ext],
)
從這里添加第二個(gè)參數(shù)并使用兩個(gè)數(shù)組進(jìn)行計(jì)算應(yīng)該是微不足道的。
您可以使用python setup.py develop.
如果你想分發(fā)它,你可以創(chuàng)建一個(gè) wheel 文件python setup.py bdist_wheel。
我曾經(jīng)numpy創(chuàng)建數(shù)據(jù),這確保了數(shù)據(jù)的底層內(nèi)存是 C 連續(xù)的。
這個(gè)例子很簡單,它使用一個(gè) Matrix4f 指針來迭代一個(gè) 3x2 矩陣數(shù)組。隨意將 轉(zhuǎn)換ptr為Eigen::Array<Eigen::Matrix4f>, 3, 2>。您不能將其強(qiáng)制轉(zhuǎn)換為 an std::vector,因?yàn)?an 的內(nèi)部數(shù)據(jù)std::vector包含指針。
請(qǐng)注意,std::vector<std::array<...>>內(nèi)存中沒有單個(gè)連續(xù)數(shù)組。改用Eigen::Array。
編輯:
這是一個(gè)使用Eigen Array Map:
PyObject * example_meth_do_math(PyObject * self, PyObject * args, PyObject * kwargs) {
static char * keywords[] = {"array", NULL};
PyObject * array;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", keywords, &array)) {
return NULL;
}
Py_buffer view = {};
if (PyObject_GetBuffer(array, &view, PyBUF_SIMPLE)) {
return NULL;
}
Eigen::Map<Eigen::Array<Eigen::Matrix4f, 2, 3>> array_map((Eigen::Matrix4f *)view.buf, 2, 3);
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
array_map(i, j) = get_dummy();
}
}
PyBuffer_Release(&view);
Py_RETURN_NONE;
}

TA貢獻(xiàn)1789條經(jīng)驗(yàn) 獲得超10個(gè)贊
線性代數(shù)不會(huì)那么流暢(在那里很難擊敗 Eigen),但會(huì)類似于您在 numpy 中所做的(np.dot(A,B)
例如。
如果您想堅(jiān)持使用 Eigen,請(qǐng)注意使用 STL 有一些技術(shù)細(xì)節(jié)。由于您std::array
不再能夠包含固定數(shù)量的矩陣,因此當(dāng)您移動(dòng)到std::vector
您會(huì)遇到對(duì)齊問題(誠然,我不完全理解)。很快就會(huì)為您提供 xtensor 的有效實(shí)現(xiàn)。
添加回答
舉報(bào)