2012-08-01

SCIP in C++11 ― 1.3.3節 その4


連分数:問題1.371.39
再帰使うと、以前シルヴァーマンで反復で書いた時よりはだいぶすっきりするな。
シルヴァーマンで使ったコードを修正したい誘惑に駆られるが、
末尾再帰(5章)を装備するまでは、メモリ消費が読めないので却下。
1.37bの反復版はあまり興味ないのでパス。
                                 
-----
const double continuedFraction
(const function<double(int)>& numeratorSequence,
 const function<double(int)>& denominatorSequence,
 const int orderMax)
{
    function<double(int)> partialContinuedFraction;
    partialContinuedFraction=
        [&partialContinuedFraction,
         &numeratorSequence,&denominatorSequence,orderMax]
        (const int order){
        if(order==orderMax){return(numeratorSequence(order)
                                   /denominatorSequence(order));}
        else{return(numeratorSequence(order)
                    /(denominatorSequence(order)
                      +partialContinuedFraction(order+1)));}
    };
    return(partialContinuedFraction(0));
}

const double denominatorE_2(const int order){
    if(1==order%3){return(static_cast<double>((order/3+1)*2));}
    else{return(1.0);}
}

const double tanCF(const double x, const double orderMax)
{
    const function<double(int)>
        numerator=[x](const int order){
        if(0==order){return(x);}
        else{return(-x*x);}
    };
    const function<double(int)>
        denominator=[](const int order){
        return(static_cast<double>(order*2+1));
    };
    return(continuedFraction(numerator,denominator,orderMax));
}

int main(int argc, char** argv)
{
    int orderMax(15);
    const double goldenRatio((sqrt(5.0)+1)/2);
    for(int order=0;order<orderMax;++order){
        const double goldenRatioCF
            (1.0/continuedFraction([](const int i){return(1.0);},
                                   [](const int i){return(1.0);},
                                   order));
        const double relativeError
            (abs((goldenRatio-goldenRatioCF)/goldenRatio));
        if(relativeError<0.0001){
            cout<<setprecision(16)<<"Excersize 1.37:"<<endl
                <<"k="<<order+1<<endl
                <<"golden ratio with CF="<<goldenRatioCF<<endl
                <<"exact value="<<goldenRatio<<endl
                <<"relative error="<<relativeError
                <<endl<<endl;
            break;
        }
    }

    cout<<"Excersize 1.38:"<<endl<<"e with CF="
        <<continuedFraction([](const int i){return(1.0);},
                           denominatorE_2,orderMax)+2.0<<endl
        <<"e="<<exp(1.0)<<endl<<endl;

    const double pi(3.1415926535897932384626);
    cout<<"Excersize 1.39:"<<endl
        <<"tan(pi/4) with CF="<<tanCF(pi/4.0,orderMax)<<endl
        <<"tan(pi/3) with CF="<<tanCF(pi/3.0,orderMax)<<endl;


    return(0);
}
-----
出力
-----
Problem 1.37:
k=10
golden ratio with CF=1.618181818181818
exact value=1.618033988749895
relative error=9.136361346630259e-05

Problem 1.38:
e with CF=2.718281828458563
e=2.718281828459045

Problem 1.39:
tan(pi/4) with CF=0.9999999999999999
tan(pi/3) with CF=1.732050807568877

0 件のコメント :

コメントを投稿