вызов C ++ с использованием функции Eigen Library в Python

Я делаю некоторые вычисления в C ++ с помощью Eigen Library, функция выглядит так:

MatrixXd Cov(MatrixXd Data)
{

VectorXd meanVector;
...
return Covariance;
}

..в функции обертывания Python:

static PyObject *Wrap_Cov(PyObject *self,PyObject *args)
{
Pyobject *Objectdata;

if(!PyArg_ParseTuple(args,"O", &ObjectData))
return NULL;

Cov(ObjectData);

return Py_BuildValue("O",&covariance_answer);

}

Очевидно, что Python не знает «объект», который я определил, он не может перевести «MatrixXd» в «объект», я думаю, что это некий «массив», а не «объект» ‘

Как я могу сделать это без использования наддува?

14

Решение

Если интерфейсные числовые модули написаны на разных языках, рекомендуется поддерживать обмен данными как можно более плоским.

Самым плоским представлением либеральной вещественной матрицы является массив c реального типа (float или double)

Вот пример C ++ ¹


#include <stdexcept>
#include <iostream>
#include <string>
#include <sstream>
#include <python2.7/Python.h>
#include <eigen3/Eigen/Dense>using std::size_t;
typedef double real_t;

typedef Eigen::Matrix<real_t, Eigen::Dynamic, Eigen::Dynamic>
Matrix;

static PyObject* p_eigen_python_error(NULL);

static PyObject *
randomDxDMatrix(PyObject *self, PyObject *args) {
PyObject* p(NULL);
PyObject* item(NULL);

try{
size_t d(0);

PyArg_ParseTuple(args, "L", &d);
Matrix M = Matrix::Random(d,d);

size_t length = d * d;

p = PyList_New(length);

if (p == NULL) {
std::stringstream msg;
msg << "Could not allocate a Pylist of "<< d << "x" << d << " = " << d*d
<< " size for the return Object";
throw std::runtime_error(msg.str().c_str());
} else {
for (size_t i = 0; i < length; ++i) {
item = PyFloat_FromDouble(M.data()[i]);
PyList_SET_ITEM(p, i, item);
}
}

} catch (const std::exception& e) {
delete p; p = NULL;
delete item; item = NULL;

std::string msg = ("randomDxDMatrix failed: ");
msg += e.what();
PyErr_SetString(p_eigen_python_error, msg.c_str());
}

return p;
}

static PyMethodDef EigenMethods[] = {
{"randomDxDMatrix",  randomDxDMatrix, METH_VARARGS,
"Gets a random DxD matrix column-major as a list of (python) floats"},
{NULL, NULL, 0, NULL}        /* Sentinel */
};

PyMODINIT_FUNC
initeigen_python(void) {

PyObject* p;

p = Py_InitModule("eigen_python", EigenMethods);
if (p == NULL)
return;

p_eigen_python_error = PyErr_NewException(
const_cast<char*>("eigen_python.error"),
NULL, NULL
);
Py_INCREF(p_eigen_python_error);
PyModule_AddObject(p, "error", p_eigen_python_error);
}

Вот setup_eigen_python.py


from distutils.core import setup, Extension

cpp_args = ['-Wall', '-pedantic']
cxx_args = ['-std=c++11'].extend(cpp_args)

module_eigen_python = Extension('eigen_python',
define_macros = [('MAJOR_VERSION', '0'),
('MINOR_VERSION', '1')],
include_dirs = ['/usr/local/include'],
sources = ['eigen_python.cpp'],
extra_compile_args = cpp_args
#                          sources = ['eigen_python.cxx'],
#                          extra_compile_args = cxx_args
)

setup (name = 'eigen_python',
version = '0.1',
description = 'This is just a demo',
author = 'Solkar',
url = 'http://stackoverflow.com/questions'
+ '/15573557/call-c-using-eigen-library-function-in-python',
long_description = 'just a toy',
ext_modules = [module_eigen_python])

использоваться как

python2.7 setup_eigen_python.py install --user

и вот небольшой тест-водитель


import eigen_python as ep
import numpy as np

DIM = 4

M = np.array(ep.randomDxDMatrix(DIM), order="F")
M.shape= DIM,DIM

print(M)

PeciallyОсобенно, но далеко не ограничиваясь, потому что, чтобы обойтись без повышения, предпочли бы использовать функции стандарта C ++ 2011, такие как auto а также std::unique_ptr но я не знал, имеет ли QO достаточную поддержку для этого.

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]