Keyword: 最小二乗, 双3次, スプライン, フィット
概要
本サンプルは最小二乗双3次スプライン曲面フィットを行うC言語によるサンプルプログラムです。 本サンプルは以下に示されるデータについて最小二乗双3次スプライン曲面フィットを行い、スプラインの値を求めて出力します。
※本サンプルはnAG Cライブラリに含まれる関数 nag_2d_spline_fit_panel() のExampleコードです。本サンプル及び関数の詳細情報は nag_2d_spline_fit_panel のマニュアルページをご参照ください。
ご相談やお問い合わせはこちらまで
入力データ
(本関数の詳細はnag_2d_spline_fit_panel のマニュアルページを参照)このデータをダウンロード |
nag_2d_spline_fit_panel (e02dac) Example Program Data 0.000001 30 8 10 -0.52 0.60 0.93 10. -0.61 -0.95 -1.79 10. 0.93 0.87 0.36 10. 0.09 0.84 0.52 10. 0.88 0.17 0.49 10. -0.70 -0.87 -1.76 10. 1.00 1.00 0.33 1. 1.00 0.10 0.48 1. 0.30 0.24 0.65 1. -0.77 -0.77 -1.82 1. -0.23 0.32 0.92 1. -1.00 1.00 1.00 1. -0.26 -0.63 8.88 1. -0.83 -0.66 -2.01 1. 0.22 0.93 0.47 1. 0.89 0.15 0.49 1. -0.80 0.99 0.84 1. -0.88 -0.54 -2.42 1. 0.68 0.44 0.47 1. -0.14 -0.72 7.15 1. 0.67 0.63 0.44 1. -0.90 -0.40 -3.34 1. -0.84 0.20 2.78 1. 0.84 0.43 0.44 1. 0.15 0.28 0.70 1. -0.91 -0.24 -6.52 1. -0.35 0.86 0.66 1. -0.16 -0.41 2.32 1. -0.35 -0.05 1.66 1. -1.00 -1.00 -1.00 1. -0.5 0.0
- 1行目はタイトル行で読み飛ばされます。
- 2行目に一次方程式の有効ランクを決定するための閾値(eps)を指定しています。
- 3行目にデータ点の数(m)を指定しています。
- 4行目に変数xのノット数の合計(px)を指定しています。
- 5行目に変数yのノット数の合計(py)を指定しています。
- 6〜35行目にデータ点yの座標、xの座標、fの座標、重み(w)を指定しています。
- 36〜37行目に変数yに関する内部ノット(mu)を指定しています。
出力結果
(本関数の詳細はnag_2d_spline_fit_panel のマニュアルページを参照)この出力例をダウンロード |
nag_2d_spline_fit_panel (e02dac) Example Program Results Interior y -knots -0.5000 0.0000 Interior x -knots None Sum of squares of residual RHS 1.467e+01 Rank 22 x and y have been interchanged X Y Data Fit Residual -0.9500 -0.6100 -1.7900 -1.7931 -3.126e-03 -0.8700 -0.7000 -1.7600 -1.7521 7.893e-03 -0.7700 -0.7700 -1.8200 -2.4301 -6.101e-01 -0.6300 -0.2600 8.8800 7.6346 -1.245e+00 -0.6600 -0.8300 -2.0100 -1.5815 4.285e-01 -0.5400 -0.8800 -2.4200 -2.6795 -2.595e-01 -0.7200 -0.1400 7.1500 7.5708 4.208e-01 -1.0000 -1.0000 -1.0000 -1.0228 -2.277e-02 -0.4000 -0.9000 -3.3400 -4.6955 -1.356e+00 -0.2400 -0.9100 -6.5200 -4.7072 1.813e+00 -0.4100 -0.1600 2.3200 2.7039 3.839e-01 -0.0500 -0.3500 1.6600 2.2865 6.265e-01 0.6000 -0.5200 0.9300 0.9441 1.407e-02 0.8700 0.9300 0.3600 0.3529 -7.097e-03 0.8400 0.0900 0.5200 0.5024 -1.761e-02 0.1700 0.8800 0.4900 0.4705 -1.951e-02 1.0000 1.0000 0.3300 0.6315 3.015e-01 0.1000 1.0000 0.4800 1.4910 1.011e+00 0.2400 0.3000 0.6500 0.9241 2.741e-01 0.3200 -0.2300 0.9200 -0.3692 -1.289e+00 1.0000 -1.0000 1.0000 1.0835 8.352e-02 0.9300 0.2200 0.4700 1.4912 1.021e+00 0.1500 0.8900 0.4900 0.4414 -4.861e-02 0.9900 -0.8000 0.8400 0.5495 -2.905e-01 0.4400 0.6800 0.4700 1.5862 1.116e+00 0.6300 0.6700 0.4400 0.6288 1.888e-01 0.2000 -0.8400 2.7800 1.7123 -1.068e+00 0.4300 0.8400 0.4400 0.6888 2.488e-01 0.2800 0.1500 0.7000 0.7713 7.134e-02 0.8600 -0.3500 0.6600 0.9347 2.747e-01 Sum of squared residuals 1.467e+01 Spline coefficients -1.0228 115.4668 -433.5558 -68.1973 24.8426 -140.1485 258.5042 15.6756 -29.4878 132.2933 -173.5103 20.0983 9.9575 -51.6200 67.6666 -5.8765 10.0577 4.7543 -15.3533 -0.3260 1.0835 -2.7932 7.7708 0.6315
- 3〜5行目に変数yの内部ノットが出力されています。
- 7〜8行目に変数xの内部ノットがないことが示されています。
- 10行目に残差平方和が出力されています。
- 12行目にランクが出力されています。
- 14行目にxとyが入れ替えられたことが示されています。
- 16〜46行目にx、y、f、フィットされた値、残差が出力されています。
- 48行目に残差平方和が出力されています。
- 50〜56行目にスプライン係数が出力されています。
ソースコード
(本関数の詳細はnag_2d_spline_fit_panel のマニュアルページを参照)
※本サンプルソースコードはnAG数値計算ライブラリ(Windows, Linux, MAC等に対応)の関数を呼び出します。
サンプルのコンパイル及び実行方法
このソースコードをダウンロード |
/* nag_2d_spline_fit_panel (e02dac) Example Program. * * CLL6I261D/CLL6I261DL Version. * * Copyright 2017 Numerical Algorithms Group. * * Mark 26.1, 2017. */ #include <stdio.h> #include <nag.h> #include <nag_stdlib.h> #include <nage02.h> int main(void) { /* Initialized data */ char label[] = "xy"; /* Scalars */ double d, eps, sigma, sum, temp; Integer exit_status = 0, i, iadres, itemp, j, m, nc, np, npoint, px, py, rank; /* Arrays */ double *dl = 0, *f = 0, *ff = 0, *lamda = 0, *mu = 0, *w = 0, *x = 0; double *y = 0; Integer *point = 0; /* Nag Types */ Nag_2dSpline spline; NagError fail; exit_status = 0; INIT_FAIL(fail); /* Initialize spline */ spline.lamda = 0; spline.mu = 0; spline.c = 0; printf("nag_2d_spline_fit_panel (e02dac) Example Program Results\n"); /* Skip heading in data file */ scanf("%*[^\n] "); while (scanf("%lf", &eps) != EOF && exit_status == 0) { /* Read data, interchanging X and Y axes if PX.LT.PY */ scanf("%ld%*[^\n] ", &m); if (m > 1) { /* Allocate memory */ if (!(f = nAG_ALLOC(m, double)) || !(ff = nAG_ALLOC(m, double)) || !(w = nAG_ALLOC(m, double)) || !(x = nAG_ALLOC(m, double)) || !(y = nAG_ALLOC(m, double)) ) { printf("Allocation failure\n"); exit_status = -1; goto END; } } else { printf("Invalid m.\n"); exit_status = 1; goto END; } scanf("%ld%ld%*[^\n] ", &px, &py); if (px < 8 && py < 8) { printf("px or py is too small.\n"); exit_status = 1; goto END; } nc = (px - 4) * (py - 4); np = (px - 7) * (py - 7); npoint = m + (px - 7) * (py - 7); /* Allocate memory */ if (!(dl = nAG_ALLOC(nc, double)) || !(point = nAG_ALLOC(npoint, Integer))) { printf("Allocation failure\n"); exit_status = -1; goto END; } if (px < py) { itemp = px; px = py; py = itemp; itemp = 1; /* Allocate memory */ if (!(lamda = nAG_ALLOC(px, double)) || !(mu = nAG_ALLOC(py, double)) ) { printf("Allocation failure\n"); exit_status = -1; goto END; } for (i = 0; i < m; ++i) scanf("%lf%lf%lf%lf", &y[i], &x[i], &f[i], &w[i]); scanf("%*[^\n] "); if (py > 8) { for (j = 4; j < py - 4; ++j) scanf("%lf", &mu[j]); scanf("%*[^\n] "); } if (px > 8) { for (j = 4; j < px - 4; ++j) scanf("%lf", &lamda[j]); scanf("%*[^\n] "); } } else { /* Allocate memory */ if (!(lamda = nAG_ALLOC(px, double)) || !(mu = nAG_ALLOC(py, double)) ) { printf("Allocation failure\n"); exit_status = -1; goto END; } itemp = 0; for (i = 0; i < m; ++i) scanf("%lf%lf%lf%lf", &x[i], &y[i], &f[i], &w[i]); scanf("%*[^\n] "); if (px > 8) { for (j = 4; j < px - 4; ++j) scanf("%lf", &lamda[j]); scanf("%*[^\n] "); } if (py > 8) { for (j = 4; j < py - 4; ++j) scanf("%lf", &mu[j]); scanf("%*[^\n] "); } } printf("\nInterior %1.1s -knots\n", label + itemp); for (j = 4; j < px - 4; ++j) printf("%11.4f\n", lamda[j]); if (px == 8) printf("None\n"); printf("\nInterior %1.1s -knots\n", label + (2 - itemp - 1)); for (j = 4; j < py - 4; ++j) printf("%1s%11.4f\n", "", mu[j]); if (py == 8) printf("None\n"); /* nag_2d_panel_sort (e02zac). * Sort two-dimensional data into panels for fitting bicubic * splines */ nag_2d_panel_sort(px, py, lamda, mu, m, x, y, point, &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_2d_panel_sort (e02zac).\n%s\n", fail.message); exit_status = 1; goto END; } /* Fit bicubic spline to data points */ spline.nx = px; spline.ny = py; if (!(spline.c = nAG_ALLOC((spline.nx - 4) * (spline.ny - 4), double)) || !(spline.lamda = nAG_ALLOC(spline.nx, double)) || !(spline.mu = nAG_ALLOC(spline.ny, double))) { printf("Allocation failure\n"); exit_status = -1; goto END; } for (i = 0; i < spline.nx; i++) spline.lamda[i] = lamda[i]; for (i = 0; i < spline.ny; i++) spline.mu[i] = mu[i]; /* nag_2d_spline_fit_panel (e02dac). * Least squares surface fit, bicubic splines */ nag_2d_spline_fit_panel(m, x, y, f, w, point, dl, eps, &sigma, &rank, &spline, &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_2d_spline_fit_panel (e02dac).\n%s\n", fail.message); exit_status = 1; goto END; } printf("\nSum of squares of residual RHS%16.3e\n", sigma); printf("\nRank%5ld\n", rank); /* nag_2d_spline_eval (e02dec). * Evaluation of bicubic spline, at a set of points */ nag_2d_spline_eval(m, x, y, ff, &spline, &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_2d_spline_eval (e02dec).\n%s\n", fail.message); exit_status = 1; goto END; } sum = 0.; if (itemp == 1) printf("\nx and y have been interchanged\n\n"); /*Output data points, fitted values and residuals */ printf(" X Y Data Fit Residual\n"); for (i = 0; i < np; ++i) { iadres = i + m; while ((iadres = point[iadres] - 1) >= 0) { temp = ff[iadres] - f[iadres]; printf("%11.4f%11.4f%11.4f%11.4f%12.3e\n", x[iadres], y[iadres], f[iadres], ff[iadres], temp); /* Computing 2nd power */ d = temp * w[iadres]; sum += d * d; } } printf("\nSum of squared residuals%16.3e\n", sum); printf("\nSpline coefficients\n"); for (i = 0; i < px - 4; ++i) { for (j = 0; j < py - 4; ++j) printf("%11.4f", spline.c[i * (py - 4) + j]); printf("\n"); } END: nAG_FREE(dl); nAG_FREE(f); nAG_FREE(ff); nAG_FREE(lamda); nAG_FREE(mu); nAG_FREE(w); nAG_FREE(x); nAG_FREE(y); nAG_FREE(point); nAG_FREE(spline.lamda); nAG_FREE(spline.mu); nAG_FREE(spline.c); } return exit_status; }