QuantLib::Mathtool::solver
今日はsolverについてです.
f(x) = 0 を解くsolverです.
クラスには複数種類あってざっとこんな感じ.
Brent,Bisection,Secant,Ridder,Newton,Falsepostion.
●アルゴリズム
Brent法
http://en.wikipedia.org/wiki/Brent's_method
Secant
http://en.wikipedia.org/wiki/Secant_method
Ridder,Falesepoint
後日(ググってもパットはでてこなかった)
どれもコンストラクタに引数はなし.
どのクラスにも2種類のsolve関数が用意されている.
f は解きたい関数.Newton以外のソルバーを使う場合,Fは演算子double operator(double) const を持っていれば十分.Newtonを使う時だけは double derivative(double) constも持っていなければならない.(実際solveのコードの部分を見てみるとf.derivative(_root)という形でderivativeを呼び出し,なければエラーを投げる形になっている)
実際にこれを使って円周率を計算させてみます.(sin(x)=0の解をもとめる).
コードはこんな感じになりました.
もちろんBrent法だけなら,
f(x) = 0 を解くsolverです.
クラスには複数種類あってざっとこんな感じ.
Brent,Bisection,Secant,Ridder,Newton,Falsepostion.
●アルゴリズム
Brent法
http://en.wikipedia.org/wiki/Brent's_method
Secant
http://en.wikipedia.org/wiki/Secant_method
Ridder,Falesepoint
後日(ググってもパットはでてこなかった)
どれもコンストラクタに引数はなし.
どのクラスにも2種類のsolve関数が用意されている.
step,xMin,xMaxは名前の通り.accuracyはソルバーのクラスによって意味が異なってくる.コードをみると,たとえばNewtonではReal solve ( const F& f, Real accuracy , Real guess ,Real step )Real solve ( const F& f, Real accuracy , Real guess ,Real xMin , Real xMax )
if (std::fabs(dx) < xAccuracy)return root_;ってあるのでxの変化がaccuracyを越えなければ終わりって感じですね.
f は解きたい関数.Newton以外のソルバーを使う場合,Fは演算子double operator(double) const を持っていれば十分.Newtonを使う時だけは double derivative(double) constも持っていなければならない.(実際solveのコードの部分を見てみるとf.derivative(_root)という形でderivativeを呼び出し,なければエラーを投げる形になっている)
実際にこれを使って円周率を計算させてみます.(sin(x)=0の解をもとめる).
コードはこんな感じになりました.
using namespace QuantLib;結果
class SquareClass{ public: //operatorとderivativeの定義 double operator()(const double x)const{ return std::sin(x); } double derivative(const double x)const{ return std::cos(x); } }; void testFunction3(){ //Brent法とNewton法を使う Newton newton;Brent brent; //各種パラメータ設定 Real accuracy =0.00001 , guess =2.0; Real min =1.0 , max =4.0; //関数(オブジェト)生成 SquareClass squareinst; //Brent法とNewton法で実際にとく.Brent法だけならderivativeは要らない. Real ans = newton.solve(squareinst,accuracy,guess,min,max); Real ans1 = brent.solve(squareinst,accuracy,guess,min,max); std::cout << "answer is " << ans << std::endl; std::cout << "answer is " << ans1<< std::endl; }
もちろんBrent法だけなら,
double f (double x) {return std::sin(x);}って関数つくってbrent.solve(f,accuracy,・・・とすることもできる.