在 C++ 中高效执行数学 Python 表达式很多

问题描述 投票:0回答:1

我有一个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("%s\n",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++函数,并且可以有效地调用?或者有什么替代方案吗?使用像symbolicc++这样的东西也可以

python c++ math
1个回答
1
投票

我建议将所有输入作为数组/向量传递到 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);
© www.soinside.com 2019 - 2024. All rights reserved.