• 検索結果がありません。

£Ã¥×¥í¥°¥é¥ß¥ó¥°ÆþÌç (2018) - Â裱£²²ó ¡Ý½ÉÂꣲ¤Î²òÀ⡤±é½¬£²¡Ý

N/A
N/A
Protected

Academic year: 2021

シェア "£Ã¥×¥í¥°¥é¥ß¥ó¥°ÆþÌç (2018) - Â裱£²²ó ¡Ý½ÉÂꣲ¤Î²òÀ⡤±é½¬£²¡Ý"

Copied!
16
0
0

読み込み中.... (全文を見る)

全文

(1)

.

.

Cプログラミング入門

(2018)

第12回

−宿題2の解説,演習2−

松田七美男

(2)

宿題2:概要

.

.

ある関数

f (x)

の区間

[

−1, 1]

における定積分値を,

3

点における積

和で近似する,

3

次のガウス積分公式

1 −1

f (x) dx

3

i=1

c

i

f (x

i

)

=

5

9

f

(

3

5

)

+

8

9

f (0) +

5

9

f

(√

3

5

)

を用いて,試行関数

1

1 + sin(x)

に対して,定積分

θ 0

1

1 + sin x

dx = tan

(

θ

2

π

4

)

+ 1

を数値的に確かめなさい.

(3)

宿題2:注意と実行例

. . 1

3

次のガウス積分公式を内部で用いた,積分区間

[a, b]

定積分を求める関数を,関数

f

へのポインタと

a, b

を仮

引数として以下のように定義しなさい.

double G3(double (*f)(), double a, double b)

. . 2

試行関数

tfunc

を以下のように定義しなさい.

double tfunc(double x)

. . 3

積分の上限

θ

は,学生番号を

50

で割った値としなさい.

例)

1Y17B123

→ θ = 2.46

.

実行画面例

.

.

$ ./hw2018-2

(4)

宿題2:ヒント

ガウス積分公式を適用するには,積分区間を

[a, b]

から

[

−1, 1]

に変換しなければなりません.それには,一次変換

ux + v = ξ

[

u = 2/(b

− a), v = −(b + a)/(b − a)

]

を用

いて,

b a

f (x) dx =

1

u

1 −1

f

(

ξ

− v

u

)

とすればよいことは明かです.

(5)

解答例





double G3(double (*f)(), double a, double b) {

double x[] = {-sqrt(0.6), 0, sqrt(0.6)}, c[] = {5.0/9, 8.0/9, 5.0/9}, u = 2/(b - a), v = (b + a)/(a - b), s = 0;

int i;

for (i = 0; i < 3; i++) s += c[i]*f((x[i] - v)/u);

return s / u; }

double tfunc(double x) { return 1/(1+sin(x)); }

int main(int argc, char **argv) {

double q = 2.46;

printf("q = %.3f, I1 = %.3f, I2 = %.3f\n",

q, G3(tfunc, 0, q), tan(q/2 - M_PI/4) + 1);

return 0; }





.

関数へのポインタを用いた汎用関数

.

f

は仮の名前,実際には

cos

が渡される

.

試行関数

tfunc

と積分区間

0, q

を引数に呼び出し

(6)

解答例





double G3(double (*f)(), double a, double b) {

double x[] = {-sqrt(0.6), 0, sqrt(0.6)}, c[] = {5.0/9, 8.0/9, 5.0/9}, u = 2/(b - a), v = (b + a)/(a - b), s = 0;

int i;

for (i = 0; i < 3; i++) s += c[i]*f((x[i] - v)/u);

return s / u; }

double tfunc(double x) { return 1/(1+sin(x)); }

int main(int argc, char **argv) {

double q = 2.46;

printf("q = %.3f, I1 = %.3f, I2 = %.3f\n",

q, G3(tfunc, 0, q), tan(q/2 - M_PI/4) + 1);

return 0; }





.

.

関数へのポインタを用いた汎用関数

.

f

は仮の名前,実際には

cos

が渡される

.

試行関数

tfunc

と積分区間

0, q

を引数に呼び出し

(7)

解答例





double G3(double (*f)(), double a, double b) {

double x[] = {-sqrt(0.6), 0, sqrt(0.6)}, c[] = {5.0/9, 8.0/9, 5.0/9}, u = 2/(b - a), v = (b + a)/(a - b), s = 0;

int i;

for (i = 0; i < 3; i++) s += c[i]*f((x[i] - v)/u);

return s / u; }

double tfunc(double x) { return 1/(1+sin(x)); }

int main(int argc, char **argv) {

double q = 2.46;

printf("q = %.3f, I1 = %.3f, I2 = %.3f\n",

q, G3(tfunc, 0, q), tan(q/2 - M_PI/4) + 1);

return 0; }





.

関数へのポインタを用いた汎用関数

.

f

は仮の名前,実際には

cos

が渡される

.

試行関数

tfunc

と積分区間

0, q

を引数に呼び出し

(8)

メイン関数の引数:文字へのポインタ配列





int main(int argc, char **argv){

double foo = 1.0;

int num = 10;

if (argc > 1)

foo = atof(argv[1]);

if (argc > 2)

num = atoi(argv[2]);

printf("ac = %d, foo = %f, num = %d\n", argc, foo, num);

return 0;

}





.

.

引数文字列の数

.

引数文字列の配列

.

*argv[ ]

でもよい

.

ポインタ配列

argv

の第

1

要素

.

実行例:(実引数)文字列の配列

.

.

.

$ ./execname

12.90

1000

.

(9)

メイン関数の引数:文字へのポインタ配列





int main(int argc, char **argv){

double foo = 1.0;

int num = 10;

if (argc > 1)

foo = atof(argv[1]);

if (argc > 2)

num = atoi(argv[2]);

printf("ac = %d, foo = %f, num = %d\n", argc, foo, num);

return 0;

}





.

引数文字列の数

.

引数文字列の配列

.

*argv[ ]

でもよい

.

ポインタ配列

argv

の第

1

要素

.

実行例:(実引数)文字列の配列

.

.

.

$ ./execname

12.90

1000

.

(10)

メイン関数の引数:文字へのポインタ配列





int main(int argc, char **argv){

double foo = 1.0;

int num = 10;

if (argc > 1)

foo = atof(argv[1]);

if (argc > 2)

num = atoi(argv[2]);

printf("ac = %d, foo = %f, num = %d\n", argc, foo, num);

return 0;

}





.

.

引数文字列の数

.

引数文字列の配列

.

*argv[ ]

でもよい

.

ポインタ配列

argv

の第

1

要素

.

実行例:(実引数)文字列の配列

.

.

.

$ ./execname

12.90

1000

.

(11)

メイン関数の引数:文字へのポインタ配列





int main(int argc, char **argv){

double foo = 1.0;

int num = 10;

if (argc > 1)

foo = atof(argv[1]);

if (argc > 2)

num = atoi(argv[2]);

printf("ac = %d, foo = %f, num = %d\n", argc, foo, num);

return 0;

}





.

.

引数文字列の数

.

引数文字列の配列

.

*argv[ ]

でもよい

.

ポインタ配列

argv

の第

1

要素

.

実行例:

(実引数)文字列の配列

.

.

.

$ ./execname

12.90

1000

(12)

メイン関数の引数:文字へのポインタ配列





int main(int argc, char **argv){

double foo = 1.0;

int num = 10;

if (argc > 1)

foo = atof(argv[1]);

if (argc > 2)

num = atoi(argv[2]);

printf("ac = %d, foo = %f, num = %d\n", argc, foo, num);

return 0;

}





.

.

引数文字列の数

.

引数文字列の配列

.

*argv[ ]

でもよい

.

ポインタ配列

argv

の第

1

要素

.

実行例:

(実引数)文字列の配列

.

.

.

$ ./execname

12.90

1000

.

.argv[0]

.argv[1]

.argv[2]

(13)

文字列の配列と関数へのポインタ配列

.

.

char *fname[] = {"cos", "sinh", "exp"};

double (*fa[])() = { cos, sinh, exp };

double (*Ifa[])() = { sin, cosh, exp };

この宣言により,関数名を

fname[i]

,対応する数学関数およ

び不定積分関数へのポインタを

fa[i],Ifa[i]

により参照で

きるようになり,ループで処理することが可能となる.

(14)

演習2:概要

.

概要

.

.

.

1

引数に試行関数

f

の名前

cos, sinh, exp

を,第

2,3

引数に

実数値

a, b

をオプション指定し,定積分

b a

f (x) dx

の値を,3次ガウス積分および解析解(原始関数)によりそれ

ぞれ求め,それらを表示するプログラムを考えなさい.なお,

指定がない場合(既定)は,

f = cos, a = 0, b = 1

としなさい.

(15)

演習2:実行画面例

宿題

2

と同様に,パラメータ

b

を(学籍番号÷

50

)として確

かめなさい.

.

実行例

.

.

[matuda@yuuko Slides]$ ./ex2018-2

Int( cos, 0.000, 1.000) = 0.841, 0.841

$ ./ex2018-2 cos 0 2.64

Int( cos, 0.000, 2.640) = 0.481, 0.481

$ ./ex2018-2 sinh 0 2.64

Int(sinh, 0.000, 2.640) = 6.041, 6.042

$ ./ex2018-2 exp 1 2.64

(16)

演習2提出に関する注意

I

waseda.jp

あるいは

waseda.ac.jp

ドメインのメールアド

レスから提出しなさい.

I

宛先は

matuda-namio@aoni.waseda.jp

I

件名には,学生番号(英数半角)

,名前,

「演習2」をこの

順に記述しなさい.

例)

1y13b999

,△○ ×□,演習

2

I

〆切は,

7

5

10:30

I

送信控えの保存を忘れずに

I

ソースをメール本文に含めること

添付は不可

I

ソースには空白を挿入したり,字下げをほどこすなど読

みやすくなる工夫をしなさい.

参照

関連したドキュメント

[r]

注意:

[r]

③ 新産業ビジョン岸和田本編の 24 ページ、25 ページについて、説明文の最終段落に経営 者の年齢別に分析した説明があり、本件が今回の新ビジョンの中で謳うデジタル化の

[r]

飼料用米・WCS 用稲・SGS

0.1uF のポリプロピレン・コンデンサと 10uF を並列に配置した 100M

7.法第 25 条第 10 項の規定により準用する第 24 条の2第4項に定めた施設設置管理