質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.91%

二分法と積分を組み合わせて方程式を解くことについて

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 1,803

score 50

前提・実現したいこと

∫[0,a]dx/1+sin(x/2)-2=0が成立するaを計算せよ。
ただし、0<a<10とする。

発生している問題・エラーメッセージ

aの答えは1.24994です。
おそらく本当の答えは円周率πと同じ3.1415...になると思われるが(手計算)、そうならなかった。

該当のソースコード

#include <stdio.h>
#include <math.h>
double Nibun(double a,double b);
double Kansu(double x);
double Sekibun(double b);
double f(double x);

int main(){

    double a,b,x;

    a=0;
    b=10.0;

    x = Nibun(a,b);

    printf("aの答えは%fです。",x);

    return 0;
}

double Nibun(double a,double b){

    double c;
    double e = 0.0001; //誤差
    int flag = 1;

    while(flag){

    c = (a+b)/2.0;

    if(Kansu(a)*Kansu(b)<0){ b=c; }
    else{ a=c; }

    if( b-a < e){ flag = 0; }

    }

    return a;
}

double Kansu(double x){

    double y;

    y = Sekibun(x) - 2.0;

    return y;
}

double Sekibun(double b){

    double x,h,a,sum;
    int i,num;


    h = 0.0001;
    a = 0.0; //積分区間。bがもう片方の積分区間になり、aは固定されている。
    num = (b-a)/h;
    sum = 0;

    for(i=0; i<num; i=i+2){
        x=a + h*i;
        sum = sum + (f(x)+4*(x+h)+f(x+2*h))/3*h;
    }

    return sum;
}

double f(double x){

    double y;

    y = 1.0 / 1.0 + sin(x/2.0);

    return y;
}

試したこと

プログラムの流れとしては、Nibunに引数を渡し、ここで二分法を行い方程式を解きます。
その時に、検査したい方程式をKansuに渡します。Kansuの中で積分が入った式があるので、これを別に計算してもらうSekibunに渡します。
どこがうまくいっていないのか、一日考えたのですがわかりません。
ご教授お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+6

1.0 / 1.0 + sin(x/2.0);

1.0 /( 1.0 + sin(x/2.0) );
の間違いでは?


(∫ dx (1.0 + sin(x/2.0)) from x = 0 to a ) = 2
だとしても
a≒1.487らしいので
他にも間違っているんでしょうが。


二分法も間違えてます。
比較すべきはKansu(a)*Kansu(b)ではなくKansu(c)*Kansu(b)です。
参考


積分も間違えてます。
これは
f(x) = 1 としてSekibun(1)を計算してみれば
明らかにおかしいことに気づけます。


ただ眺めてもバグを見つけるのは難しいです。
プログラムの構成要素を一つ一つに分解して
正しい動作をしているか実際に動かして確かめましょう。

今回であれば、

  • 適当な簡単な関数に対して、定積分が正しく行えるか。
  • 適当な簡単な方程式に対して、二分法で解が正しく求められるか。

・・・
みたいにです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/21 16:36

    ありがとうございます。
    理解できました。指定箇所を直せば3.14に近い値が出ました。
    二分法、積分ともに理解が不十分でした。参考文献とともにもう一度勉強しようと思います。

    キャンセル

  • 2016/06/21 17:00

    思うに、あなたが一日中悩んだのは、
    二分法や数値積分の理解が足らなかったのが原因ではなく、
    デバッグのやり方を知らなかっただけではないかと。

    対象を充分理解していてもバグなく一発で実装できる事のほうが稀ですし、
    理解が充分であるとむしろ正しく書いたと思い込んじゃうので
    読んでも自分ではわかりません

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る