y = ax + bの関係が成り立つとして、最適なa, bを決定する。
void(*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t)という形式の静的外部関数(クラスに属するメンバー関数不可)を要求する。上記の参考サイトの見本を使うと
void FCN(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t flag)になる。で、それぞれの変数の意味は
npar : 最小化に含まれる自由パラメーターの数 gin : 計算された勾配値 (オプション) f : 関数値そのもの par : 定数および変数パラメーターのvector flag : FCN のいくつかのアクションを切り替えるらしい。よくわからんけど、fとparだけ使えば最低限のことは出来る。
void FCN(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t flag){
double a,b;
float realpeak[7] = {121.7817, 244.6975, 344.2785, 778.9040, 867.378, 964.079, 1408.006};
float rawpeak[7] = {259.4612, 521.1042, 733.0547, 1668.473, 1856.93, 2062.59, 3013.292};
double rss = 0;
a = par[0];
b = par[1];
for (int i=0; i<7; i++){
double y_calced = a * rawpeak[i] + b;
rss += (ealpeak[i] - y_calced) * (ealpeak[i] - y_calced);
}
f = rss;
}
int main(){
TMinuit *min = new TMinuit(2); // パラメータ数
min->SetPrintLevel(-1); // 途中経過を非表示 (-1:非表示, 0:標準, 1:冗長表示)
min->SetFCN(FCN); // 関数を設定
min->DefineParameter(0, "a", 0.4, 0.0000001, 0.2, 0.5); // パラメータ初期値と刻み幅を設定
min->DefineParameter(1, "b", 4.4, 0.001, -10, +10); // 第二引数の"a"とか"b"はnameを指定する。重複しないようにすれば適当でOK。
min->Migrad(); // 最小化処理を実行
double a,b,ea,eb;
min->GetParameter(0, a, dummy); // パラメータを取得
min->GetParameter(1, b, dummy);
printf("a : %f +- %f, b : %f +- %f \n", a, ea, b, eb);
return 0;
}g++ sample.cxx -o sample `root-config --cflags --libs` -lMinuit