7

Boost-Pythonプログラムを作成して、ユーザーからシンボリックpython関数を取得し、その派生物をプログラムで評価したいと思います。

たとえば、ユーザーはF = sin(x)* cos(x)のような関数を定義するPythonファイル(Function.py)を提供します。

次に、Sympyのシンボリック微分能力を使用してF'(x)(F(x)の導関数)にアクセスしたいと思います。数値微分は使いたくない。

Boost-Pythonを使用してC++でそのような関数F'(x)にアクセスできるようにする方法はありますか?

4

2 に答える 2

4

これがあなたが始めるのを助けるべきいくつかのコードです。

main.cpp:

#include <boost/python.hpp>
#include <iostream>

using namespace boost::python;

int main(void) {
    Py_Initialize();

    object main_module = import("__main__");
    object main_namespace = main_module.attr("__dict__");

    exec("from __future__ import division\n"
        "from sympy import *\n"
        "x = symbols('x')\n"
        "f = symbols('f', cls=Function)\n"
        "f = cos(x) * sin(x)\n"
        "f1 = lambda u: diff(f).subs(x, u);\n",
        main_namespace);

    exec("result = f1(1.0)", main_namespace);
    double res = extract<double>(main_namespace["result"]);
    std::cout << "Out: " << res << std::endl;

    return 0;
}

コマンドをコンパイルし、パスとコンパイラに置き換えます。

$ clang++ -I"/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/Current/Headers/" -L"/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/Current/lib/" -lpython2.7 main.cpp

コンパイルされますが、現在は機能しません。お役に立てば幸いです。

于 2012-12-25T21:00:56.917 に答える
3

私はSymPyの専門家ではありませんが、おそらくこれはあなたを助けることができます:

次のようなPythonメソッドを定義できます。

def f(x):
  return sin(x)*cos(x)

以下を使用して、 fの導関数として評価可能な関数f1を作成できます。

from sympy import *
x = symbols('x')
f1 = lambdify(x, diff(f(x)))

この関数f1は、boost::pythonを使用してC++から呼び出すことができます。関数f1のオブジェクトを作成し、()演算子を使用して関数を呼び出し、 extract<>を使用して結果をdoubleに変換できます。

次に例を示します。

  namespace py = boost::python;

  Py_Initialize();

  py::object main_module = py::import("__main__");
  py::object main_dict   = main_module.attr("__dict__");

  py::exec(
    "def f(x):\n"
    "  return  sin(x)*cos(x)\n",
    main_dict
  );

  py::exec(
    "from sympy import *\n"
    "x = symbols('x')\n"
    "f1 = lambdify(x, diff(f(x)))\n",
     main_dict
  );

  py::object f1 = main_dict["f1"];
  std::cout << py::extract<double>(f1(0.0)) << std::endl;
  std::cout << py::extract<double>(f1(1.0)) << std::endl;

  return 0;
于 2012-12-31T00:26:30.983 に答える