在c++中高效地执行数学Python表达式

Efficiently execute mathematical Python expression in C++ many

本文关键字:Python 表达式 执行数 c++ 高效      更新时间:2023-10-16

我有一个python程序,它生成一个像

这样的数学表达式
exp(sin(x-y))**2

现在我想把它交给我的c++程序,它必须用不同的x,y值计算这个表达式。我的第一种方法是使用Python.h库和PyRun_String。

初始化代码:

func=function;
Py_Initialize();
    memset(pythonString,0,strlen(pythonString));
    // add whiteNoise Kernel
    sprintf(pythonString,"from math import *;func=lambda x,y:(%s+0.1*(x==y))",function);
    //printf("%sn",pythonString);
    PyRun_SimpleString(pythonString);

这里是被求值多次的代码:

char execString[200];
memset(execString,0,strlen(execString));
sprintf(execString,"result=func(%f,%f)",x1[0],  x2[0]);
PyObject* main = PyImport_AddModule("__main__");
PyObject* globalDictionary = PyModule_GetDict(main);
PyObject* localDictionary = PyDict_New();
//create the dictionaries as shown above
PyRun_String(execString, Py_file_input, globalDictionary, localDictionary);
double result = PyFloat_AsDouble(PyDict_GetItemString(localDictionary, "result"));

然而,我认为每次用PyRun_String解析字符串真的太慢了。是否有一种方法可以直接将Python表达式转换为可以有效调用的c++函数?或者还有其他选择吗?也可以使用symbolic++

我建议将您的所有输入作为数组/向量传递给您的c++ &立即解决所有问题。另外,试试Py_CompileString &用PyEval_EvalCode代替PyRun_String。我不得不解数以百万计的方程;发现速度提高了10倍

下面是一个简单的'a + b'的例子,但是有了更多的for循环,可以将其推广到具有任意数量变量的任何方程。对于下面的一百万个值,在我的机器上可以在不到一秒的时间内完成(相比之下,PyRun_String需要10秒)。

PyObject* main = PyImport_AddModule("__main__");
PyObject* globalDict = PyModule_GetDict(main);
PyCodeObject* code = (PyCodeObject*) Py_CompileString("a + b", "My Eqn", Py_eval_input);
for (millions of values in input) {
    PyObject* localDict = PyDict_New();
    PyObject* oA = PyFloat_FromDouble(a);  // 'a' from input
    PyObject* oB = PyFloat_FromDouble(b);  // 'b' from input
    PyDict_SetItemString(localDict, "a", oA);
    PyDict_SetItemString(localDict, "b", oB);
    PyObject* pyRes = PyEval_EvalCode(code, globalDict, localDict);
    r = PyFloat_AsDouble(pyRes);
    // put r in output array
    Py_DECREF(pyRes);
    Py_DECREF(localDict)
}
Py_DECREF(code);