private static void rbf_interp_nd_test01() //****************************************************************************80 // // Purpose: // // RBF_INTERP_ND_TEST01 tests RBF_WEIGHTS and RBF_INTERP_ND with PHI1. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 01 July 2012 // // Author: // // John Burkardt // { int i; int j; const int m = 2; const int n1d = 5; typeMethods.r8vecDPData data = new(); Console.WriteLine(""); Console.WriteLine("RBF_INTERP_ND_TEST01:"); Console.WriteLine(" RBF_WEIGHT computes weights for RBF interpolation."); Console.WriteLine(" RBF_INTERP_ND evaluates the RBF interpolant."); Console.WriteLine(" Use the multiquadratic basis function PHI1(R)."); double a = 0.0; double b = 2.0; double[] x1d = typeMethods.r8vec_linspace_new(n1d, a, b); int nd = (int)Math.Pow(n1d, m); double[] xd = new double[m * nd]; for (i = 0; i < m; i++) { typeMethods.r8vec_direct_product(ref data, i, n1d, x1d, m, nd, ref xd); } typeMethods.r8mat_transpose_print(m, nd, xd, " The product points:"); double r0 = (b - a) / n1d; Console.WriteLine(""); Console.WriteLine(" Scale factor R0 = " + r0 + ""); double[] fd = new double[nd]; for (j = 0; j < nd; j++) { fd[j] = xd[0 + j * m] * xd[1 + j * m] * Math.Exp(-xd[0 + j * m] * xd[1 + j * m]); } typeMethods.r8vec_print(nd, fd, " Function data:"); double[] w = RadialBasisFunctions.rbf_weight(m, nd, xd, r0, RadialBasisFunctions.phi1, fd); typeMethods.r8vec_print(nd, w, " Weight vector:"); // // #1: Interpolation test. Does interpolant match function at interpolation points? // int ni = nd; double[] xi = typeMethods.r8mat_copy_new(m, ni, xd); double[] fi = RadialBasisFunctions.rbf_interp_nd(m, nd, xd, r0, RadialBasisFunctions.phi1, w, ni, xi); double int_error = typeMethods.r8vec_norm_affine(nd, fd, fi) / nd; Console.WriteLine(""); Console.WriteLine(" L2 interpolation error averaged per interpolant node = " + int_error + ""); // // #2: Approximation test. Estimate the integral (f-interp(f))^2. // ni = 1000; int seed = 123456789; xi = UniformRNG.r8mat_uniform_ab_new(m, ni, a, b, ref seed); fi = RadialBasisFunctions.rbf_interp_nd(m, nd, xd, r0, RadialBasisFunctions.phi1, w, ni, xi); double[] fe = new double[ni]; for (j = 0; j < ni; j++) { fe[j] = xi[0 + j * m] * xi[1 + j * m] * Math.Exp(-xi[0 + j * m] * xi[1 + j * m]); } double app_error = Math.Pow(b - a, m) * typeMethods.r8vec_norm_affine(ni, fi, fe) / ni; Console.WriteLine(""); Console.WriteLine(" L2 approximation error averaged per 1000 samples = " + app_error + ""); }
private static void test01(int prob, int g, Func <int, double[], double, double[], double[]> phi, string phi_name) //****************************************************************************80 // // Purpose: // // RBF_INTERP_2D_TEST01 tests RBF_INTERP_2D. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 06 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int PROB, the index of the problem. // // Input, int G, the index of the grid. // // Input, void PHI ( int n, double r[], double r0, double v[] ), the // radial basis function. // // Input, string PHI_NAME, the name of the radial basis function. // { const bool debug = false; int i; Console.WriteLine(""); Console.WriteLine("RBF_INTERP_2D_TEST01:"); Console.WriteLine(" Interpolate data from TEST_INTERP_2D problem #" + prob + ""); Console.WriteLine(" using grid #" + g + ""); Console.WriteLine(" using radial basis function \"" + phi_name + "\"."); int nd = Data_2D.g00_size(g); Console.WriteLine(" Number of data points = " + nd + ""); double[] xd = new double[nd]; double[] yd = new double[nd]; Data_2D.g00_xy(g, nd, ref xd, ref yd); double[] zd = new double[nd]; Data_2D.f00_f0(prob, nd, xd, yd, ref zd); switch (debug) { case true: typeMethods.r8vec3_print(nd, xd, yd, zd, " X, Y, Z data:"); break; } const int m = 2; double[] xyd = new double[2 * nd]; for (i = 0; i < nd; i++) { xyd[0 + i * 2] = xd[i]; xyd[1 + i * 2] = yd[i]; } double xmax = typeMethods.r8vec_max(nd, xd); double xmin = typeMethods.r8vec_min(nd, xd); double ymax = typeMethods.r8vec_max(nd, yd); double ymin = typeMethods.r8vec_min(nd, yd); double volume = (xmax - xmin) * (ymax - ymin); const double e = 1.0 / m; double r0 = Math.Pow(volume / nd, e); Console.WriteLine(" Setting R0 = " + r0 + ""); double[] w = RadialBasisFunctions.rbf_weight(m, nd, xyd, r0, phi, zd); // // #1: Does interpolant match function at interpolation points? // double[] xyi = typeMethods.r8mat_copy_new(2, nd, xyd); double[] zi = RadialBasisFunctions.rbf_interp(m, nd, xyd, r0, phi, w, nd, xyi); double int_error = typeMethods.r8vec_norm_affine(nd, zi, zd) / nd; Console.WriteLine(""); Console.WriteLine(" L2 interpolation error averaged per interpolant node = " + int_error + ""); }
private static void test01(int prob, Func <int, double[], double, double[], double[]> phi, string phi_name, double r0) //****************************************************************************80 // // Purpose: // // TEST01 tests RBF_INTERP_1D. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 05 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int PROB, the index of the problem. // // Input, double PHI ( int n, double r[], double r0, double v[] ), // the name of the radial basis function. // // Input, string PHI_NAME, the name of the radial basis function. // // Input, double R0, the scale factor. Typically, this might be // a small multiple of the average distance between points. // { const bool debug = false; int i; Console.WriteLine(""); Console.WriteLine("TEST01:"); Console.WriteLine(" Interpolate data from TEST_INTERP problem #" + prob + ""); Console.WriteLine(" using radial basis function \"" + phi_name + "\"."); Console.WriteLine(" Scale factor R0 = " + r0 + ""); int nd = TestInterp.p00_data_num(prob); Console.WriteLine(" Number of data points = " + nd + ""); double[] xy = TestInterp.p00_data(prob, 2, nd); switch (debug) { case true: typeMethods.r8mat_transpose_print(2, nd, xy, " Data array:"); break; } double[] xd = new double[nd]; double[] yd = new double[nd]; for (i = 0; i < nd; i++) { xd[i] = xy[0 + i * 2]; yd[i] = xy[1 + i * 2]; } int m = 1; double[] w = RadialBasisFunctions.rbf_weight(m, nd, xd, r0, phi, yd); // // #1: Does interpolant match function at interpolation points? // int ni = nd; double[] xi = typeMethods.r8vec_copy_new(ni, xd); double[] yi = RadialBasisFunctions.rbf_interp(m, nd, xd, r0, phi, w, ni, xi); double int_error = typeMethods.r8vec_norm_affine(ni, yi, yd) / ni; Console.WriteLine(""); Console.WriteLine(" L2 interpolation error averaged per interpolant node = " + int_error + ""); // // #2: Compare estimated curve length to piecewise linear (minimal) curve length. // Assume data is sorted, and normalize X and Y dimensions by (XMAX-XMIN) and // (YMAX-YMIN). // double xmax = typeMethods.r8vec_max(nd, xd); double xmin = typeMethods.r8vec_min(nd, xd); double ymax = typeMethods.r8vec_max(nd, yd); double ymin = typeMethods.r8vec_min(nd, yd); ni = 501; xi = typeMethods.r8vec_linspace_new(ni, xmin, xmax); yi = RadialBasisFunctions.rbf_interp(m, nd, xd, r0, phi, w, ni, xi); double ld = 0.0; for (i = 0; i < nd - 1; i++) { ld += Math.Sqrt(Math.Pow((xd[i + 1] - xd[i]) / (xmax - xmin), 2) + Math.Pow((yd[i + 1] - yd[i]) / (ymax - ymin), 2)); } double li = 0.0; for (i = 0; i < ni - 1; i++) { li += Math.Sqrt(Math.Pow((xi[i + 1] - xi[i]) / (xmax - xmin), 2) + Math.Pow((yi[i + 1] - yi[i]) / (ymax - ymin), 2)); } Console.WriteLine(" Normalized length of piecewise linear interpolant = " + ld + ""); Console.WriteLine(" Normalized length of polynomial interpolant = " + li + ""); }