2012-08-01

SCIP in C++11 ― 1.3.4節 その1


1.3.4 値として返される手続き

最初はラムダを多用していたのだが、
普通に関数が使える場所、例えばグローバルスコープでラムダ使うと、
関数型の宣言が2重になってしまう。
関数を返すとか関数内関数とかで、ラムダを使う必要があれば別だが、
そうでない局面ではラムダを使わないほうが良い。

関数への参照を引数に取る関数内で、引数の関数をラムダでキャプチャするときは、
その関数はすでに参照なのだから参照キャプチャしないこと。これで少しハマった。
-----
const double fixedPoint
(const function<double(double)>& f, const double firstGuess)
{
    const double tolerance(0.00001);
    const function<bool(double,double)> isCloseEnough=
    [tolerance](const double v1,const double v2)
    {return(abs(v1-v2)<tolerance);};
    function<double(double)> Try;
    Try=[f,&isCloseEnough,&Try](const double guess)->const double{
        const double next(f(guess));
        if(isCloseEnough(guess,next)){return(next);}
        else{return(Try(next));}
    };
    return(Try(firstGuess));
}

const double average(const double a,const double b)
{return((a+b)/2.0);}

const function<double(double)>
averageDamp(const function<double(double)>& f)
{
    return([f](const double x){return(average(x,f(x)));});
}

const double sqrtFixed(const double x){
    return(fixedPoint
           (averageDamp([x](const double y){return(x/y);}),
            1.0));
}

const double cbrtFixed(const double x){
    return(fixedPoint
           (averageDamp([x](const double y){return(x/y/y);}),
            1.0));
}

int main(int argc, char** argv)
{
    cout<<setprecision(16)<<"sqrt(2)="<<sqrtFixed(2.0)<<endl;
    cout<<setprecision(16)<<"cbrt(2)="<<cbrtFixed(2.0)<<endl;
    return(0);
}
-----
出力
-----
sqrt(2)=1.414204706074303
cbrt(2)=1.259918703725256

0 件のコメント :

コメントを投稿