Keyword: 双3次, スプライン, フィット
概要
本サンプルは矩形格子データへの双3次スプラインフィットを行うC言語によるサンプルプログラムです。 本サンプルは以下に示されるデータについて双3次スプラインフィットを行いノットとBスプライン係数を求めて出力します。
※本サンプルはnAG Cライブラリに含まれる関数 nag_2d_spline_fit_grid() のExampleコードです。本サンプル及び関数の詳細情報は nag_2d_spline_fit_grid のマニュアルページをご参照ください。
ご相談やお問い合わせはこちらまで
入力データ
(本関数の詳細はnag_2d_spline_fit_grid のマニュアルページを参照)このデータをダウンロード |
nag_2d_spline_fit_grid (e02dcc) Example Program Data 11 9 0.0000E+00 5.0000E-01 1.0000E+00 1.5000E+00 2.0000E+00 2.5000E+00 3.0000E+00 3.5000E+00 4.0000E+00 4.5000E+00 5.0000E+00 0.0000E+00 5.0000E-01 1.0000E+00 1.5000E+00 2.0000E+00 2.5000E+00 3.0000E+00 3.5000E+00 4.0000E+00 1.0000E+00 8.8758E-01 5.4030E-01 7.0737E-02 -4.1515E-01 -8.0114E-01 -9.7999E-01 -9.3446E-01 -6.5664E-01 1.5000E+00 1.3564E+00 8.2045E-01 1.0611E-01 -6.2422E-01 -1.2317E+00 -1.4850E+00 -1.3047E+00 -9.8547E-01 2.0600E+00 1.7552E+00 1.0806E+00 1.5147E-01 -8.3229E-01 -1.6023E+00 -1.9700E+00 -1.8729E+00 -1.4073E+00 2.5700E+00 2.1240E+00 1.3508E+00 1.7684E-01 -1.0404E+00 -2.0029E+00 -2.4750E+00 -2.3511E+00 -1.6741E+00 3.0000E+00 2.6427E+00 1.6309E+00 2.1221E-01 -1.2484E+00 -2.2034E+00 -2.9700E+00 -2.8094E+00 -1.9809E+00 3.5000E+00 3.1715E+00 1.8611E+00 2.4458E-01 -1.4565E+00 -2.8640E+00 -3.2650E+00 -3.2776E+00 -2.2878E+00 4.0400E+00 3.5103E+00 2.0612E+00 2.8595E-01 -1.6946E+00 -3.2046E+00 -3.9600E+00 -3.7958E+00 -2.6146E+00 4.5000E+00 3.9391E+00 2.4314E+00 3.1632E-01 -1.8627E+00 -3.6351E+00 -4.4550E+00 -4.2141E+00 -2.9314E+00 5.0400E+00 4.3879E+00 2.7515E+00 3.5369E-01 -2.0707E+00 -4.0057E+00 -4.9700E+00 -4.6823E+00 -3.2382E+00 5.5050E+00 4.8367E+00 2.9717E+00 3.8505E-01 -2.2888E+00 -4.4033E+00 -5.4450E+00 -5.1405E+00 -3.5950E+00 6.0000E+00 5.2755E+00 3.2418E+00 4.2442E-01 -2.4769E+00 -4.8169E+00 -5.9300E+00 -5.6387E+00 -3.9319E+00 0.1 6 0.0 5.0 5 0.0 4.0
- 1行目はタイトル行で読み飛ばされます。
- 2行目にx軸の格子点の数(mx)、y軸の格子点の数(my)を指定しています。
- 3〜5行目にはx座標を指定しています。
- 6〜7行目にはy座標を指定しています。
- 8〜27行目にはデータ値(f)を指定しています。
- 28行目に平滑化因子(s)を指定しています。
- 29行目に矩形格子のx軸に沿った点の数(npx)、最小値(xlo)、最大値(xhi)を指定しています。
- 30行目に矩形格子のy軸に沿った点の数(npy)、最小値(ylo)、最大値(yhi)を指定しています。
出力結果
(本関数の詳細はnag_2d_spline_fit_grid のマニュアルページを参照)この出力例をダウンロード |
nag_2d_spline_fit_grid (e02dcc) Example Program Results Calling with smoothing factor s = 1.0000e-01: spline.nx = 10, spline.ny = 13. Distinct knots in x direction located at 0.0000 1.5000 2.5000 5.0000 Distinct knots in y direction located at 0.0000 1.0000 2.0000 2.5000 3.0000 3.5000 4.0000 The B-spline coefficients: 0.9918 1.5381 2.3913 3.9845 5.2138 5.9965 1.0546 1.5270 2.2441 4.2217 5.0860 6.0821 0.6098 0.9557 1.5587 2.3458 3.3860 3.7716 -0.2915 -0.4199 -0.7399 -1.1763 -1.5527 -1.7775 -0.8476 -1.3296 -1.8521 -3.3468 -4.3628 -5.0085 -1.0168 -1.5952 -2.4022 -3.9390 -5.4680 -6.1656 -0.9529 -1.3381 -2.2844 -3.9559 -5.0032 -5.8709 -0.7711 -1.0914 -1.8488 -3.2549 -3.9444 -4.7297 -0.6476 -1.0373 -1.5936 -2.5887 -3.3485 -3.9330 Sum of squared residuals fp = 1.0004e-01 Values of computed spline: x 0.00 1.00 2.00 3.00 4.00 5.00 y 4.00 -0.65 -1.36 -1.99 -2.61 -3.25 -3.93 3.00 -0.98 -1.97 -2.91 -3.91 -4.97 -5.92 2.00 -0.42 -0.83 -1.24 -1.66 -2.08 -2.48 1.00 0.54 1.09 1.61 2.14 2.71 3.24 0.00 0.99 2.04 3.03 4.01 5.02 6.00
- 3行目に呼び出される際の平滑化因子、spline.nx(変数xに関するスプラインのノットの数)、spline.ny(変数yに関するスプラインのノットの数)が出力されています。
- 5〜6行目にx方向のノットの位置が出力されています。
- 8〜10行目にy方向のノットの位置が出力されています。
- 12〜22行目にBスプライン係数が出力されています。
- 24行目に残差平方和が出力されています。
- 26〜34行目に計算されたスプラインの値が出力されています。
ソースコード
(本関数の詳細はnag_2d_spline_fit_grid のマニュアルページを参照)
※本サンプルソースコードはnAG数値計算ライブラリ(Windows, Linux, MAC等に対応)の関数を呼び出します。
サンプルのコンパイル及び実行方法
このソースコードをダウンロード |
/* nag_2d_spline_fit_grid (e02dcc) Example Program. * * CLL6I261D/CLL6I261DL Version. * * Copyright 2017 Numerical Algorithms Group. * * Mark 26.1, 2017. * */ #include <nag.h> #include <stdio.h> #include <nag_stdlib.h> #include <nage02.h> int main(void) { Integer exit_status = 0, i, j, mx, my, npx, npy, nx, ny; Nag_2dSpline spline; Nag_Comm warmstartinf; Nag_Start start; double delta, *f = 0, *fg = 0, fp, *px = 0, *py = 0, s, *x = 0, xhi, xlo, *y = 0, yhi; double ylo; NagError fail; INIT_FAIL(fail); /* Initialize spline */ spline.lamda = 0; spline.mu = 0; spline.c = 0; warmstartinf.nag_w = 0; warmstartinf.nag_iw = 0; printf("nag_2d_spline_fit_grid (e02dcc) Example Program Results\n"); scanf("%*[^\n]"); /* Skip heading in data file */ /* Input the number of x, y co-ordinates mx, my. */ scanf("%ld%ld", &mx, &my); if (mx >= 4 && my >= 4) { if (!(f = nAG_ALLOC(mx * my, double)) || !(x = nAG_ALLOC(mx, double)) || !(y = nAG_ALLOC(my, double))) { printf("Allocation failure\n"); exit_status = -1; goto END; } } else { printf("Invalid mx or my.\n"); exit_status = 1; return exit_status; } /* Input the x co-ordinates followed by the y co-ordinates. */ for (i = 0; i < mx; i++) scanf("%lf", &x[i]); for (i = 0; i < my; i++) scanf("%lf", &y[i]); /* Input the mx*my function values f at the grid points. */ for (i = 0; i < mx * my; i++) scanf("%lf", &f[i]); start = Nag_Cold; scanf("%lf", &s); /* Determine the spline approximation. */ /* nag_2d_spline_fit_grid (e02dcc). * Least squares bicubic spline fit with automatic knot * placement, two variables (rectangular grid) */ nag_2d_spline_fit_grid(start, mx, x, my, y, f, s, mx + 4, my + 4, &fp, &warmstartinf, &spline, &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_2d_spline_fit_grid (e02dcc).\n%s\n", fail.message); exit_status = 1; goto END; } nx = spline.nx; ny = spline.ny; printf("\nCalling with smoothing factor s = %13.4e:" " spline.nx = %2ld, spline.ny = %2ld.\n\n", s, nx, ny); /* Print the knot sets, lamda and mu. */ printf("Distinct knots in x direction located at\n"); for (j = 3; j < spline.nx - 3; j++) printf("%12.4f%s", spline.lamda[j], ((j - 3) % 5 == 4 || j == spline.nx - 4) ? "\n" : " "); printf("\nDistinct knots in y direction located at\n"); for (j = 3; j < spline.ny - 3; j++) printf("%12.4f%s", spline.mu[j], ((j - 3) % 5 == 4 || j == spline.ny - 4) ? "\n" : " "); printf("\nThe B-spline coefficients:\n\n"); for (i = 0; i < ny - 4; i++) { for (j = 0; j < nx - 4; j++) printf("%9.4f", spline.c[i + j * (ny - 4)]); printf("\n"); } printf("\nSum of squared residuals fp = %13.4e\n", fp); if (fp == 0.0) printf("\nThe spline is an interpolating spline\n"); else if (nx == 8 && ny == 8) printf("\nThe spline is the least squares bi-cubic polynomial\n"); /* Evaluate the spline on a rectangular grid at npx*npy points * over the domain (xlo to xhi) x (ylo to yhi). */ scanf("%ld%lf%lf", &npx, &xlo, &xhi); scanf("%ld%lf%lf", &npy, &ylo, &yhi); if (npx >= 1 && npy >= 1) { if (!(fg = nAG_ALLOC(npx * npy, double)) || !(px = nAG_ALLOC(npx, double)) || !(py = nAG_ALLOC(npy, double))) { printf("Allocation failure\n"); exit_status = -1; goto END; } } else { printf("Invalid npx or npy.\n"); exit_status = 1; return exit_status; } delta = (xhi - xlo) / (npx - 1); for (i = 0; i < npx; i++) px[i] = MIN(xlo + i * delta, xhi); for (i = 0; i < npy; i++) py[i] = MIN(ylo + i * delta, yhi); /* nag_2d_spline_eval_rect (e02dfc). * Evaluation of bicubic spline, at a mesh of points */ nag_2d_spline_eval_rect(npx, npy, px, py, fg, &spline, &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_2d_spline_eval_rect (e02dfc).\n%s\n", fail.message); exit_status = 1; goto END; } printf("\nValues of computed spline:\n"); printf("\n x"); for (i = 0; i < npx; i++) printf("%7.2f ", px[i]); printf("\n y\n"); for (i = npy - 1; i >= 0; i--) { printf("%7.2f ", py[i]); for (j = 0; j < npx; ++j) printf("%8.2f ", fg[npy * j + i]); printf("\n"); } END: nAG_FREE(spline.lamda); nAG_FREE(spline.mu); nAG_FREE(spline.c); nAG_FREE(warmstartinf.nag_w); nAG_FREE(warmstartinf.nag_iw); nAG_FREE(f); nAG_FREE(x); nAG_FREE(y); nAG_FREE(fg); nAG_FREE(px); nAG_FREE(py); return exit_status; }