このサイトのチュートリアルが非常に良さげなので、このサイトを参考にしてROOTを使ったC++プログラミングを学習してみる。
PythonとC++統合にROOTを使う¶
PyROOT is not just a set of Python bindings to C++ functions; it dynamically generates bindings for all C++ classes and functions in its namespace.
PyROOTはC++関数に対するただの一連のPythonバインディングではなく、自身のネームスペース内に、全てのC++クラスと関数用のバインディングを生成する。
Including new functions that you define.
もちろん、ユーザー定義関数も含まれている。
import ROOT
In a script, use gInterpreter.ProcessLine or gInterpreter.Declare to run C++ code.
スクリプト内では、gInterpreter.ProcessLine、もしくは、gInterpreter.Declareを用いてC++コードを実行する。
ROOT.gInterpreter.Declare("""
double dostuff(double a, double b) {
return a + b;
}
""")
ROOT.dostuff(3.14, 100)
Suppose we want to change the dostuff function, common on a prompt or in a notebook.
dostuff関数を変えたいと仮定しよう。
ROOT.gInterpreter.Declare("""
double dostuff(double a, double b) {
return (a + b) / sqrt(a*a + b*b);
}
""")
Ouch! Of course it doesn’t let us replace a definition (not legal in C++), but we really want to.
もちろん、定義を差し替えることは(C++では不正なため)許されないのだが、どうしても定義を変えたい。
This is what I do:
そういう場合は以下のようにするとよい。
tmpname = "dostuffv1" # keep changing the C++ name
ROOT.gInterpreter.Declare("""
double %s(double a, double b) {
return (a + b) / sqrt(a*a + b*b);
}
""" % tmpname)
dostuff = getattr(ROOT, tmpname) # but assign to the same Python name
dostuff(3.14, 100)
Towers of Hanoi (ハノイの塔)¶
このサイトからTowers of Hanoiコードを拝借する。
ROOT.gInterpreter.Declare("""
void moveDisks (int n, char fromPeg, char toPeg, char auxPeg) {
if (n == 1) { // stopping case
cout << setw(6) << n
<< " " << fromPeg
<< " " << toPeg << endl;
}
else { // recursive step
moveDisks(n-1, fromPeg, auxPeg, toPeg);
cout << setw(6) << n
<< " " << fromPeg
<< " " << toPeg << endl;
moveDisks(n-1, auxPeg, toPeg, fromPeg);
}
}
""")
ROOT.moveDisks(4, 'A', 'C', 'B')
Pythonのprint関数を使って出力を参照サイトの出力と同じにする。
print("Move Disk # From Peg To Peg")
ROOT.moveDisks(4, 'A', 'C', 'B')
C++ magic %%cppを先頭行に付け足して以下のコードを実行すると、上と同じ結果が得られる。
%%cpp
cout << "Move Disk# From Peg To Peg" << endl;
moveDisks(4, 'A', 'C', 'B');
以上のように、%%cpp magicを使えば、C++の書式をそのまま使えるし、ROOT.gInterpreter.Declareを使えば、C++とPythonを一緒に使える。
cpp magicによる関数定義¶
%%cpp magicによる関数定義には%%cpp -dを使う。
%%cpp -d
int add (int a, int b)
{
return a+b;
}
ROOT.add(2,4)
%%cpp
cout << add(2,4) << endl;
%%cpp
add(2,4)
#include "stdio.h"
class A{
public:
A(int i):m_i(i){}
int getI() const {return m_i;}
private:
int m_i=0;
};
void printA(const A& a ){
printf ("The value of A instance is %i.\n",a.getI());
}
ROOT.gInterpreter.ProcessLine('#include "cpp2pythonExample.h"')
a = ROOT.A(123)
ROOT.printA(a)