我有一个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++这样的东西也可以
我建议将所有输入作为数组/向量传递到 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);