回答編集履歴

1

暫定回答追加

2016/09/24 02:50

投稿

cesolution
cesolution

スコア217

test CHANGED
@@ -1,3 +1,111 @@
1
1
  sukiyaki様
2
2
 
3
3
  一通りコードを確認しましたが、少なくともシンプソン積分、2分法のコーディングは問題無さそうです。ちょっと被積分関数の形状がパッとは分からないのですが、恐らくかなり複雑な形状をしており、0~1の間に複数解を持つのではないでしょうか?今回は答えが分かっているようなので、2分法で挟む範囲を狭めてみてはどうでしょうか?
4
+
5
+
6
+
7
+ 2016/9/24追記
8
+
9
+  いくつか試してみましたが、現状の関数のままだと、関数の出力が初期値を入力した段階で#INDになってしまうようです。
10
+
11
+ 試しに被積分関数をtanh(x/(2*T))にしてみても同様でした。
12
+
13
+  ひとまず収束して解を得られるコードを以下、一例としてご紹介します。(スマートなコードではないですが、、、)
14
+
15
+ mainの中で以下のbisection2()を実行していただければと思います。
16
+
17
+
18
+
19
+ ```C++
20
+
21
+
22
+
23
+ double integrand2(double x, double T){
24
+
25
+ return tanh(x/(2*T))/max(0.000001,x);
26
+
27
+ };
28
+
29
+
30
+
31
+ double int_simpson2(int N, double a, double b, double T){
32
+
33
+ double dx=(b-a)/N;
34
+
35
+ double sum1=0.,sum2=0.;
36
+
37
+ for (int i=1; i<N/2; i++) {
38
+
39
+ sum1+=integrand2(a+2*i*dx, T);
40
+
41
+ sum2+=integrand2(a+(2*i-1)*dx, T);
42
+
43
+ }
44
+
45
+ sum2+=integrand2(a+(N-1)*dx, T);
46
+
47
+ return dx*(integrand2(a, T)+integrand2(b, T)+2*sum1+4*sum2)/3.;
48
+
49
+ }
50
+
51
+
52
+
53
+ void bisection2(){
54
+
55
+ int count=0;
56
+
57
+ double l=0.;
58
+
59
+ //double r=1.0;
60
+
61
+ double r=0.15;
62
+
63
+ double VN=0.4;//相互作用
64
+
65
+ double m;
66
+
67
+ do{
68
+
69
+ count++;
70
+
71
+ m=(l+r)/2.0;
72
+
73
+ if ((int_simpson2(100,0.,1.,m)-1.0/VN)*(int_simpson2(100,0.,1.,l)-1.0/VN)<0) r=m;
74
+
75
+ else l=m;
76
+
77
+ if(count==20){
78
+
79
+ cout << "収束しませんでした";
80
+
81
+ exit(1);
82
+
83
+ }
84
+
85
+ //cout << int_simpson2(100,0.,1.,m)-1.0/VN << endl;
86
+
87
+ //cout << m << endl;
88
+
89
+ }while (!(fabs(int_simpson2(100,0.,1.,m)-1.0/VN)<0.001));
90
+
91
+ cout << m << endl;
92
+
93
+ }
94
+
95
+
96
+
97
+ ```
98
+
99
+
100
+
101
+ なお、2分法の範囲を狭めていますが、理由は以下になります。
102
+
103
+
104
+
105
+ ![イメージ説明](8969fd648079968432c9badb9ac3fc1b.png)
106
+
107
+
108
+
109
+ ![イメージ説明](de5452d0acd5976e83ab5cc50ce610d7.png)
110
+
111
+