1.3.1節 引数としての手続き
最初は懸命にファンクタ使って、抽象ファンクタテンプレートを作り、スライシングに悩み、std::functionテンプレートクラスの使い方に悩み、後でラムダ出るしなあとテストしてもうまく行かなくてとか散々悩んで何度もコードを書き直し。
ラムダだけで押したらどうなるのかなと試してみたらなんと、すっげえよラムダ、ヤバイよラムダ、ラムダかわいいよラムダ。コードが一気にコンパクト化。これでやっと少し光が見えてきたか。
総和手続きと問題1.29
--------
template<typename
TermResult, typename TermArgument,
typename NextResult,typename NextArgument>
const
TermResult sum
(const
function<TermResult(TermArgument)>& term,
const NextArgument& lower,
const
function<NextResult(NextArgument)>& next,
const NextArgument& upper)
{
if(lower>upper){return(0.0);}
return(term(lower)+sum(term,next(lower),next,upper));
}
const
function<int(int)> identity=
[](const int x){return(x);};
const
function<int(int)> increment=
[](const int x){return(x+1);};
template<typename
ResultType>
const
ResultType squareFun(const ResultType x){return(x*x);}
template<typename
ResultType>
const
ResultType cubeFun(const ResultType x){return(pow(x,3));}
function<double(double)>
piTerm=
[](const double x){return(1.0/x/(x+2.0));};
function<double(double)>
piNext=
[](const double x){return(x+4);};
const
int sumIntegers(const int lower, const int upper)
{
return(sum(identity, lower,increment,
upper));
}
const
int sumSquareIntegers(const int lower, const int upper)
{
const function<int(int)>
square=squareFun<int>;
return(sum(square, lower, increment,
upper));
}
const
double piSum(const int lower,const int upper)
{
return(sum(piTerm,static_cast<double>(lower),
piNext,static_cast<double>(upper))*8.0);
}
const
double integral
(const
function<double(double)>& f,
const double lower, const double upper, const
double dx)
{
const function<double(double)> addDx
=[dx](const double x){return(x+dx);};
return(sum(f, lower+dx/2.0, addDx,
upper)*dx);
}
const
double simpsonIntegral
(const
function<double(double)>& f,
const double lower, const double upper, const
double dx)
{
const function<double(double)> add2Dx
=[dx](const double x){return(x+2.0*dx);};
const function<double(double)>
simpsonF=[dx,&f](const double x){
return(f(x-dx)+4.0*f(x)+f(x+dx));
};
return(sum(simpsonF, lower+dx, add2Dx,
upper)*dx/3.0);
}
int
main(int argc, char** argv)
{
int lower(1);
int upper(1000);
cout<<"sum_{i="<<lower<<"}^{"<<upper
<<"}
i="<<sumIntegers(lower,upper)<<endl;
upper=10;
cout<<"sum_{i="<<lower<<"}^{"<<upper
<<"}
i^2="<<sumSquareIntegers(lower,upper)<<endl;
upper=1000;
cout<<"sum_{i="<<lower<<"}^{"<<upper
<<"} 1/((4i+1)(4i+3))="<<piSum(lower,upper)<<endl;
lower=0;
upper=1;
const double dx(0.001);
const function<double(double)>
cube=cubeFun<double>;
cout<<setprecision(16)<<"integral_{"<<lower
<<"}^{"<<upper<<"}
cube(x) dx="
<<integral(cube,static_cast<double>(lower),
static_cast<double>(upper),dx)<<endl;
cout<<endl<<"Problem
1.29:"<<endl;
cout<<setprecision(16)<<"integral_{"<<lower
<<"}^{"<<upper<<"}
cube(x) dx="
<<simpsonIntegral(cube,static_cast<double>(lower),
static_cast<double>(upper),dx)<<endl;
return(0);
}
----
出力
----
sum_{i=1}^{1000}
i=500500
sum_{i=1}^{10}
i^2=385
sum_{i=1}^{1000}
1/((4i+1)(4i+3))=3.13959
integral_{0}^{1}
cube(x) dx=0.2499998750000006
integral_{0}^{1}
cube(x) dx=0.2500000000000006
0 件のコメント :
コメントを投稿