4回目 課題解答・解説
課題1)
#include <stdio.h> struct Point2D{ double x; double y; }; //ラグランジュ補間の関数 double LagrangeInterp(const Point2D pnt[], const int n, const double x) /* * pnt : 点群を表す配列 * n : 点群の個数 * x : 求めたいxの値 * 戻り値 : xに対応する関数値 y */ { int i,j; /* 計算用変数の初期化 */ double p, s = 0.0; for (i = 0; i < n; i++) { p = pnt[i].y; /* 積の計算 */ for (j = 0; j < n; j++) { if (i != j) { p *= (x - pnt[j].x) / (pnt[i].x - pnt[j].x); } } s += p; } return s; } int main(){ const int N = 5; Point2D points[N] = { {-3.5, -2.2}, {-2.2, -0.3}, {-1.0, 1.5}, { 0.2, 1.9}, { 2.3, 2.2} }; FILE *fp; fp = fopen("Lagrange.csv", "w"); if(fp == NULL){ printf("file cannot be opened.\n"); return -1; } /* xの値を変化させながら LagrangeInterp 関数により y の値を順次計算,出力 */ for(float x = -4.0; x <= 3.0; x += 0.1){ //-4から3まで計算する fprintf(fp,"%f,%f\n",x,LagrangeInterp(points,N,x)); } fclose(fp); printf("出力完了!\n"); return 0; } |
構造体 関数の設定,引数の表記 constにすることで書き換え不可 構造体初期化,数値代入 ファイルポインタ |
課題2)
#include <stdio.h> struct Point2D { double x; double y; }; const int N = 5; /* データ個数 */ double spline(const Point2D pnt[], const double x) /* * スプライン補間関数 * pnt : 既知の点群 * x : xの値 * 戻り値 : xに対応する関数の値 */ { int idx = -1, k; double h[N-1], b[N-1], d[N-1], g[N-1], u[N-1], r[N]; int i; for (i=1; i<N-1 && idx<0; i++) { if (x < pnt[i].x ) idx = i - 1; } if (idx < 0) idx = N-2; for(i=0; i<N-1; i++) { h[i] = pnt[i+1].x - pnt[i].x; } for (i=1; i<N-1; i++) { b[i] = 2.0 * (h[i] + h[i-1]); d[i] = 3.0 * ((pnt[i+1].y - pnt[i ].y) / h[i ] - (pnt[i ].y - pnt[i-1].y) / h[i-1]); } g[1] = h[1] / b[1]; for (i=2; i<N-2; i++) { g[i] = h[i] / (b[i] - h[i-1] * g[i-1]); } u[1] = d[1] / b[1]; for(i=2; i<N-1; i++) { u[i] = (d[i]-h[i-1] * u[i-1]) / (b[i] - h[i-1] * g[i-1]); } if(idx > 1) { k = idx; } else { k = 1; } r[0] = 0.0; r[N-1] = 0.0; r[N-2] = u[N-2]; for (i=N-3; i>=k; i--) { r[i] = u[i] - g[i] * r[i+1]; } double dx = x - pnt[idx].x; double q = (pnt[idx+1].y - pnt[idx].y) / h[idx] - h[idx] * (r[idx+1] + 2.0 * r[idx]) / 3.0; double s = (r[idx+1] - r[idx]) / (3.0 * h[idx]); return pnt[idx].y + dx * (q + dx * (r[idx] + s * dx)); } int main(){ Point2D points[N] = {{-3.5, -2.2}, {-2.2, -0.3}, {-1.0, 1.5}, { 0.2, 1.9}, { 2.3, 2.2} }; FILE *fp; fp = fopen("spline.csv", "w"); if(fp == NULL){ printf("file cannot be opened\n"); return -1; } /* spline関数を利用して,あるxの範囲についてyを計算,ファイル出力. */ for(float x = -4.0; x <= 3.0; x += 0.1){ //-4から3まで計算する fprintf(fp,"%f,%f\n",x,spline(points,x)); } fclose(fp); printf("出力完了!\n"); return 0; } |
構造体 constにより数値を固定 スプライン補間の関数 構造体初期化,数値代入 |