情報実習Ⅱ
第7回 (これまでの復習) 課題資料
• Javaのクラスの概形 クラス フィールド コンストラクタ メソッド mainメソッド ローカル変数宣言 オブジェクト生成 オブジェクトへのメッセージ(メソッド呼び出し) • 変数: 基本型, 参照型
• キーボード入力: Scannerの利用: nextInt(), nextDouble(),…
• 演算子: 算術演算子, 増減演算子, 代入演算子, 比較演算子, 論理演算子
• 書式付出力と書式指定子: printf(): %d, %f, %s, %c
• 条件分岐: if文, else-ifラダー, switch文
• 繰り返し: while文, do-while文, for文, break文, continue文
これまでの
習得事項
まだ初歩的な内容だけだが、これ らを利用するだけでも多くの実用 的なプログラムが記述できる
課題番号7
任意の2次関数の定
積分を近似計算する
ためのプログラムの
作成
3種類の近似法 • 区分求積法 • 台形則(今日の課題) • 合成シンプソン法 y = f(x) x0 x1 定積分値 = න 𝑥0 𝑥1 𝑓(𝑥) 𝑑𝑥 どのような複雑な関数 でも、積分公式を使わ ずに、かなり正確に計 算できる区分求積法(参考)
計算範囲をn等分し、n個の長 方形の面積(負になる場合もある)で近似 x0 x1 x2 x3 y = f(x) 積分値 ≒ f(x0) ×w + ... + f(x3)×w wは、(x4 –x0)/4で求まる1区間の幅 (n=4の場合) 一番簡単だが、精度はいまいち x4 w w w w grid grid spacing台形則(今日の課題)
計算範囲をn等分し、n個の台形 の面積(負になる場合もある)で近似 x0 x1 x2 x3 y = f(x) (f(x0) + f(x1))×w/2 + …+ (f(x3) + f(x4))×w/2 (n=4の場合) 簡単で、精度もそこそこ x4 w w w w 積分値 ≒合成シンプソン法(参考)
3点を通る2次関数でf(x)の 積分値を近似。区分数は 偶数でなければならない x0 x1 x2 x3 y = f(x) ちょっと複雑だが、精度は良い x4 w w w w 𝑤 3 (𝑓 𝑥0 + 𝑓 𝑥𝑛 + 2 σ𝑖=1 𝑛 2−1 𝑓(𝑥 2𝑖) + 4 σ𝑖=1 𝑛 2 𝑓(𝑥 2𝑖−1)) 積分値 ≒2次関数の3つの係数(整数)をスペースで区切って入力: 1 2 1 積分の始点と終点(実数)をスペースで区切って入力: -3.0 3.0 f(x) = 1x^2+2x+1 の定積分 [-3.0, 3.0] の近似値 1分割: 60.00 10分割: 24.36 100分割: 24.00 1000分割: 24.00 10000分割: 24.00 100000分割: 24.00 青文字は キーボード からの入力 実行例 𝑓(𝑥) = 𝑥2 + 2𝑥 + 1 のグラフの彩色部 分の面積を求める 場合
今日の課題
• 課題番号7-1, 7-2, 7-3, レポートの作成 • 提出するファイルは次の4つ 課題 7-1 QuadraticFunction.java 課題 7-2 TrapezoidalRule.java 課題 7-3 IntegralTester.java report7.pdf課題番号 7-1 積分の対象となる任意の2次関数を表すクラス、 QuadraticFunction.javaを作成せよ。 2次関数の3つの係数(整数)をスペースで区切って入力: 2 -3 -8 f(x) = 2x^2-3x-8 引数の値(実数)を入力: 6.7 f(6.7) = 61.68 2次関数の3つの係数(整数)をスペースで区切って入力: -6 5 0 f(x) = -6x^2+5x+0 引数の値(実数)を入力: -4.7 f(-4.7) = -156.04 2次関数の3つの係数(整数)をスペースで区切って入力: -1 0 1 f(x) = -1x^2+0x+1 引数の値(実数)を入力: 67.0 f(67.0) = -4488.00 青文字は キーボード からの入力 実行例 • 1次の係数と定数の値が負のときには演算子が – になるように工夫すること。例えば、1番目の実行例が f(x) = 2x^2+-3x+-8 では不可。 • 演算子が – になる際、式中に余分なスペースが入らないように工夫すること。 f(x) = 2x^2 -3x -8 では不可。 • 係数が -1 又は 0 又は 1 のとき、式を正しく表示するためには条件分岐が複雑になりすぎるので、今回の課題では2、3番目の実行例の ように工夫無しで各係数の値をそのまま表示して良い。(4.7節のStringクラスを学習すれば、正しい表示が比較的簡単に実装可能)
• 絶対値の計算にはMath.absメソッドを利用する。例えば b の絶対値を求めるには、int test = Math.abs(b) などとすれば良い。 表示上の注意
フィールド: a, b, c: int 2次関数の係数。 コンストラクタ: 3つの整数を引数として、フィールドを初期化 メソッド: evaluate(x: double): 関数の戻り値 ( a x^2 + b x + c の計算結果) を返す showFunction(): 前ページに示したように、関数の式を表示 mainメソッド: 前ページに示したように、キーボードから3つの整数を入力して、この クラスのオブジェクトを一つ生成する。 さらにキーボードから1つの実数を入力して関数の計算結果を表示 する。 課題番号7-1 QuadraticFunction クラスの仕様 フィールド、コンストラクタ、メソッドの修飾子はクラス図を参照
・・・ Scannerを使えるようにする準備 /** 課題番号、学籍番号などをドキュメンテーションコメントとして記入。 */ クラス宣言 { フィールドの宣言 コンストラクタの宣言 evaluateメソッドの宣言 showFunctionメソッドの宣言
public static void main(String[] args) {
/* キーボード入力の準備 */
Scanner kbScanner = new Scanner(System.in);
/* キーボードから2次関数の係数を入力する */
System.out.print("2次関数の3つの係数(整数)をスペースで区切って入力: ");
int a = kbScanner.nextInt();
int b = kbScanner.nextInt();
int c = kbScanner.nextInt();
/* 与えられた係数を元に、2次関数を表すオブジェクトを生成する */
QuadraticFunction qFunction = new QuadraticFunction(a,b,c);
qFunction.showFunction(); System.out.println();
/* キーボードから関数に与える引数の値を入力する */
System.out.print("引数の値(実数)を入力: ");
double x = kbScanner.nextDouble();
/* 関数の計算結果を表示 */
System.out.printf("f(%1.1f) = %8.2f",x,qFunction.evaluate(x));
kbScanner.close(); }
課題番号 7-2 台形則に基づいて、関数の定積分の近似値を計算する機 能を持つクラス、TrapezoidalRule.javaを作成せよ。 フィールド: startPoint: double 定積分の始点を表す endPoint: double 定積分の終点を表す qFunction: QuadraticFunction 積分対象の関数を表す コンストラクタ: 2つの整数とQuadraticFunction型の参照を引数として、 各フィールドを初期化 メソッド:
calcArea(x: double, gridSpacing: double): double
qFunction, x, gridSpacing を用いて、一区画の台形面積を計算して返す。
integrate(numOfGrid: int): double
startPointからendPointまでの定積分値を、numOfGrid個の台形の面積を合計 することで近似して返す。
例えばp. 25 の Rectangle.java において、moveメソ ッドの中からshowStateメソッドを呼び出し、move の 実行ごとに情報を表示させるようにするには、以下 のように記述すればよい。
メソッド内(mainは除く)から、同じクラス
の他のメソッドを呼び出すには
(integrateメソッドのヒント)public void move(int xMove, int yMove) {
xPosition = xPosition + xMove;
yPosition = yPosition + yMove;
showState();
2次関数の3つの係数(整数)をスペースで区切って入力: -3 -8 9 積分の始点と終点(実数)をスペースで区切って入力: -23.4 82.8 f(x) = -3x^2-8x+9 の定積分 [-23.4, 82.8] の近似値 1分割: -1203638.94 10分割: -610742.63 100分割: -604813.66 1000分割: -604754.37 10000分割: -604753.78 100000分割: -604753.78 課題7-3の実行例 課題番号7-3 区間分割数を1~100000に10倍ずつ変化させ、積分の近似計算をする mainメソッドのみのプログラム、IntegralTester.javaを作成せよ。 2次関数の3つの係数(整数)をスペースで区切って入力: 1 2 1 積分の始点と終点(実数)をスペースで区切って入力: -4.0 9.0 f(x) = 1x^2+2x+1 の定積分 [-4.0, 9.0] の近似値 1分割: 708.50 10分割: 346.00 100分割: 342.37 1000分割: 342.33 10000分割: 342.33 100000分割: 342.33 2次関数の3つの係数(整数)をスペースで区切って入力: 3 0 1 積分の始点と終点(実数)をスペースで区切って入力: -578.0 2345.9 f(x) = 3x^2+0x+1 の定積分 [-578.0, 2345.9] の近似値 1分割: 25601660256.94 10分割: 13228155068.37 100分割: 13104420016.49 1000分割: 13103182665.97 10000分割: 13103170292.47 100000分割: 13103170168.71 2次関数の3つの係数(整数)をスペースで区切って入力: 4 0 0 積分の始点と終点(実数)をスペースで区切って入力: 21.0 -21.0 積分区間が間違っています. 2次関数の3つの係数(整数)をスペースで区切って入力: 7 0 0 積分の始点と終点(実数)をスペースで区切って入力: 9.0 9.0 積分区間が間違っています.
・・・ Scannerを使えるようにする準備
/** ここに必ずこのクラスの役割を明記する。記述がいい加減な場合も再提出となる。 */
クラス宣言 { mainメソッド {
final int maxPartitionNumber = 100000; //分割数の上限。定数を扱う場合はfinal修飾子をつける。 /* キーボード入力の準備 */
Scanner …
/* キーボードから2次関数の係数を入力する */
System.out.print("2次関数の3つの係数(整数)をスペースで区切って入力: ");
…
/* 与えられた係数を元に、2次関数を表すオブジェクトを生成する */
QuadraticFunction …
/* キーボードから積分区間の始点と終点を入力する */
System.out.print("積分の始点と終点(実数)をスペースで区切って入力: ");
… (間違った積分区間を入力した際は、System.exit(1) で終了)
/* TrapezoidalRule クラスのオブジェクトを生成 */
TrapezoidalRule …
/* 積分対象の関数の表示 */
…
System.out.printf(" の定積分 [%2.1f, %2.1f] の近似値¥n", …);
/* 1〜maxPartitionNumber 分割したそれぞれの場合の積分の近似値を求め表示する */ for (… ここに100000という数値を直接書かないこと) { … } Scanner を閉じる } IntegralTester.javaの半完成品
学籍番号、名前、課題番号、提出日、再提出日 例 (ドキュメンテーションコメントを使用すること) /** * クラスの簡単な説明 * * @author 19-1-037-0999 近大太郎 課題 7-1 提出日 2019/10/29 再提出日 2019/11/19 (再提出時のみ) */