public static double[] vandermonde_coef_1d(int nd, double[] xd, double[] yd) //****************************************************************************80 // // Purpose: // // VANDERMONDE_COEF_1D computes coefficients of a 1D Vandermonde interpolant. // // Discussion: // // We assume the interpolant has the form // // p(x) = c1 + c2 * x + c3 * x^2 + ... + cn * x^(n-1). // // We have n data values (x(i),y(i)) which must be interpolated: // // p(x(i)) = c1 + c2 * x(i) + c3 * x(i)^2 + ... + cn * x(i)^(n-1) = y(i) // // This can be cast as an NxN linear system for the polynomial // coefficients: // // [ 1 x1 x1^2 ... x1^(n-1) ] [ c1 ] = [ y1 ] // [ 1 x2 x2^2 ... x2^(n-1) ] [ c2 ] = [ y2 ] // [ ...................... ] [ ... ] = [ ... ] // [ 1 xn xn^2 ... xn^(n-1) ] [ cn ] = [ yn ] // // and if the x values are distinct, the system is theoretically // invertible, so we can retrieve the coefficient vector c and // evaluate the interpolant. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 07 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int ND, the number of data points. // // Input, double XD[ND], YD[ND], the data values. // // Output, double VANDERMONDE_COEF_1D[ND], the coefficients of the // interpolating polynomial. // { double[] ad = vandermonde_matrix_1d(nd, xd); double[] cd = QRSolve.qr_solve(nd, nd, ad, yd); return(cd); }
public static double[] pwl_approx_1d(int nd, double[] xd, double[] yd, int nc, double[] xc) //****************************************************************************80 // // Purpose: // // PWL_APPROX_1D determines the control values for a PWL approximant. // // Discussion: // // The piecewise linear approximant is defined by NC control pairs // (XC(I),YC(I)) and approximates ND data pairs (XD(I),YD(I)). // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 10 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int ND, the number of data points. // ND must be at least 1. // // Input, double XD[ND], the data points. // // Input, double YD[ND], the data values. // // Input, int NC, the number of control points. // NC must be at least 1. // // Input, double XC[NC], the control points. Set these with a // command like // xc = r8vec_linspace_new ( nc, xmin, xmax ); // // Output, double PWL_APPROX_1D[NC], the control values. // { // // Define the NDxNC linear system that determines the control values. // double[] a = pwl_approx_1d_matrix(nd, xd, yd, nc, xc); // // Solve the system. // double[] yc = QRSolve.qr_solve(nd, nc, a, yd); return(yc); }
public static void emstrong(ref typeMethods.r8vecNormalData data, ref int seed, int m, int n, int p_max, ref double[] dtvals, ref double[] xerr) //****************************************************************************80 // // Purpose: // // EMSTRONG tests the strong convergence of the EM method. // // Discussion: // // The SDE is // // dX = lambda * X dt + mu * X dW, // X(0) = Xzero, // // where // // lambda = 2, // mu = 1, // Xzero = 1. // // The discretized Brownian path over [0,1] has dt = 2^(-9). // // The Euler-Maruyama method uses 5 different timesteps: // 16*dt, 8*dt, 4*dt, 2*dt, dt. // // We are interested in examining strong convergence at T=1, // that is // // E | X_L - X(T) |. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 28 September 2012 // // Author: // // Original Matlab version by Desmond Higham. // C++ version by John Burkardt. // // Reference: // // Desmond Higham, // An Algorithmic Introduction to Numerical Simulation of // Stochastic Differential Equations, // SIAM Review, // Volume 43, Number 3, September 2001, pages 525-546. // // Parameters: // // Input/output, int &SEED, a seed for the random // number generator. // // Input, int M, the number of simulations to perform. // A typical value is M = 1000. // // Input, int N, the number of time steps to take. // A typical value is N = 512. // // Input, int P_MAX, the number of time step sizes to use. // A typical value is 5. // // Output, double DTVALS[P_MAX], the time steps used. // // Output, double XERR[P_MAX], the averaged absolute error in the // solution estimate at the final time. // { int i; int p; int s; // // Set problem parameters. // const double lambda = 2.0; const double mu = 1.0; const double xzero = 1.0; // // Set stepping parameters. // const double tmax = 1.0; double dt = tmax / n; for (p = 0; p < p_max; p++) { dtvals[p] = dt * Math.Pow(2.0, p); } // // Sample over discrete Brownian paths. // for (p = 0; p < p_max; p++) { xerr[p] = 0.0; } for (s = 0; s < m; s++) { // // Define the increments dW. // double[] dw = typeMethods.r8vec_normal_01_new(n, ref data, ref seed); int j; for (j = 0; j < n; j++) { dw[j] = Math.Sqrt(dt) * dw[j]; } // // Sum the increments to get the Brownian path. // double[] w = new double[n + 1]; w[0] = 0.0; for (j = 1; j <= n; j++) { w[j] = w[j - 1] + dw[j - 1]; } // // Determine the true solution. // double xtrue = xzero * Math.Exp(lambda - 0.5 * mu * mu + mu * w[n]); // // Use the Euler-Maruyama method with 5 different time steps dt2 = r * dt // to estimate the solution value at time TMAX. // for (p = 0; p < p_max; p++) { double dt2 = dtvals[p]; int r = (int)Math.Pow(2, p); int l = n / r; double xtemp = xzero; for (j = 0; j < l; j++) { double winc = 0.0; int k; for (k = r * j; k < r * (j + 1); k++) { winc += dw[k]; } xtemp = xtemp + dt2 * lambda * xtemp + mu * xtemp * winc; } xerr[p] += Math.Abs(xtemp - xtrue); } } for (p = 0; p < p_max; p++) { xerr[p] /= m; } // // Least squares fit of error = c * dt^q. // double[] a = new double[p_max * 2]; double[] rhs = new double[p_max]; for (i = 0; i < p_max; i++) { a[i + 0 * p_max] = 1.0; a[i + 1 * p_max] = Math.Log(dtvals[i]); rhs[i] = Math.Log(xerr[i]); } double[] sol = QRSolve.qr_solve(p_max, 2, a, rhs); Console.WriteLine(""); Console.WriteLine("EMSTRONG:"); Console.WriteLine(" Least squares solution to Error = c * dt ^ q"); Console.WriteLine(" (Expecting Q to be about 1/2.)"); Console.WriteLine(" Computed Q = " + sol[1] + ""); double resid = 0.0; for (i = 0; i < p_max; i++) { double e = a[i + 0 * p_max] * sol[0] + a[i + 1 * p_max] * sol[1] - rhs[i]; resid += e * e; } resid = Math.Sqrt(resid); Console.WriteLine(" Residual is " + resid + ""); }
private static void test02(int prob) //****************************************************************************80 // // Purpose: // // TEST02 tests VANDERMONDE_INTERP_1D_MATRIX. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 02 June 2013 // // Author: // // John Burkardt // // Parameters: // // Input, int PROB, the problem index. // { List <string> command_unit = new(); List <string> data_unit = new(); int i; List <string> interp_unit = new(); int j; Console.WriteLine(""); Console.WriteLine("TEST02:"); Console.WriteLine(" VANDERMONDE_INTERP_1D_MATRIX sets the Vandermonde linear system"); Console.WriteLine(" for the interpolating polynomial."); Console.WriteLine(" Interpolate data from TEST_INTERP problem #" + prob + ""); int nd = TestInterp.p00_data_num(prob); Console.WriteLine(" Number of data points = " + nd + ""); double[] xy = TestInterp.p00_data(prob, 2, nd); typeMethods.r8mat_transpose_print(2, nd, xy, " Data array:"); double[] xd = new double[nd]; double[] yd = new double[nd]; for (i = 0; i < nd; i++) { xd[i] = xy[0 + 2 * i]; yd[i] = xy[1 + 2 * i]; } // // Compute Vandermonde matrix and get condition number. // double[] ad = Vandermonde.vandermonde_matrix_1d(nd, xd); // // Solve linear system. // double[] cd = QRSolve.qr_solve(nd, nd, ad, yd); // // Create data file. // string data_filename = "data" + prob + ".txt"; for (j = 0; j < nd; j++) { data_unit.Add(" " + xd[j] + " " + yd[j] + ""); } File.WriteAllLines(data_filename, data_unit); Console.WriteLine(""); Console.WriteLine(" Created graphics data file \"" + data_filename + "\"."); // // Create interp file. // int ni = 501; double xmin = typeMethods.r8vec_min(nd, xd); double xmax = typeMethods.r8vec_max(nd, xd); double[] xi = typeMethods.r8vec_linspace_new(ni, xmin, xmax); double[] yi = Vandermonde.vandermonde_value_1d(nd, cd, ni, xi); string interp_filename = "interp" + prob + ".txt"; for (j = 0; j < ni; j++) { interp_unit.Add(" " + xi[j] + " " + yi[j] + ""); } File.WriteAllLines(interp_filename, interp_unit); Console.WriteLine(" Created graphics interp file \"" + interp_filename + "\"."); // // Plot the data and the interpolant. // string command_filename = "commands" + prob + ".txt"; string output_filename = "plot" + prob + ".png"; command_unit.Add("# " + command_filename + ""); command_unit.Add("#"); command_unit.Add("# Usage:"); command_unit.Add("# gnuplot < " + command_filename + ""); command_unit.Add("#"); command_unit.Add("set term png"); command_unit.Add("set output '" + output_filename + "'"); command_unit.Add("set xlabel '<---X--->'"); command_unit.Add("set ylabel '<---Y--->'"); command_unit.Add("set title 'Data versus Vandermonde polynomial interpolant'"); command_unit.Add("set grid"); command_unit.Add("set style data lines"); command_unit.Add("plot '" + data_filename + "' using 1:2 with points pt 7 ps 2 lc rgb 'blue',\\"); command_unit.Add(" '" + interp_filename + "' using 1:2 lw 3 linecolor rgb 'red'"); File.WriteAllLines(command_filename, command_unit); Console.WriteLine(" Created graphics command file \"" + command_filename + "\"."); }
private static void test01(int prob) //****************************************************************************80 // // Purpose: // // TEST01 tests VANDERMONDE_INTERP_1D. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 07 October 2012 // // Author: // // John Burkardt // { const bool debug = false; int i; Console.WriteLine(""); Console.WriteLine("TEST01:"); Console.WriteLine(" Interpolate data from TEST_INTERP problem #" + prob + ""); 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]; } // // Compute Vandermonde matrix and get condition number. // double[] ad = Vandermonde.vandermonde_matrix_1d(nd, xd); double condition = Matrix.condition_hager(nd, ad); Console.WriteLine(""); Console.WriteLine(" Condition of Vandermonde matrix is " + condition + ""); // // Solve linear system. // double[] cd = QRSolve.qr_solve(nd, nd, ad, yd); // // #1: Does interpolant match function at interpolation points? // int ni = nd; double[] xi = typeMethods.r8vec_copy_new(ni, xd); double[] yi = Vandermonde.vandermonde_value_1d(nd, cd, 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 xmin = typeMethods.r8vec_min(nd, xd); double xmax = typeMethods.r8vec_max(nd, xd); double ymin = typeMethods.r8vec_min(nd, yd); double ymax = typeMethods.r8vec_max(nd, yd); ni = 501; xi = typeMethods.r8vec_linspace_new(ni, xmin, xmax); yi = Vandermonde.vandermonde_value_1d(nd, cd, 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(""); Console.WriteLine(" Normalized length of piecewise linear interpolant = " + ld + ""); Console.WriteLine(" Normalized length of polynomial interpolant = " + li + ""); }
public static void emweak(ref typeMethods.r8vecNormalData data, ref int seed, int method, int m, int p_max, ref double[] dtvals, ref double[] xerr) //****************************************************************************80 // // Purpose: // // EMWEAK tests the weak convergence of the Euler-Maruyama method. // // Discussion: // // The SDE is // // dX = lambda * X dt + mu * X dW, // X(0) = Xzero, // // where // // lambda = 2, // mu = 1, // Xzero = 1. // // The discretized Brownian path over [0,1] has dt = 2^(-9). // // The Euler-Maruyama method will use 5 different timesteps: // // 2^(p-10), p = 1,2,3,4,5. // // We examine weak convergence at T=1: // // | E (X_L) - E (X(T)) |. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 25 September 2012 // // Author: // // Original MATLAB version by Desmond Higham. // C++ version by John Burkardt. // // Reference: // // Desmond Higham, // An Algorithmic Introduction to Numerical Simulation of // Stochastic Differential Equations, // SIAM Review, // Volume 43, Number 3, September 2001, pages 525-546 // // Parameters: // // Input, int &SEED, a seed for the random number generator. // // Input, int METHOD. // 0, use the standard Euler-Maruyama method; // 1, use the weak Euler-Maruyama method. // // Input, int M, the number of simulations to perform. // A typical value is M = 1000. // // Input, int P_MAX, the number of time step sizes to use. // A typical value is 5. // // Output, double DTVALS[P_MAX], the time steps used. // // Output, double XERR[P_MAX], the averaged absolute error in the // solution estimate at the final time. // { int i; int p; // // Problem parameters; // const double lambda = 2.0; const double mu = 0.1; const double xzero = 1.0; // // Stepping parameters. // for (p = 0; p < p_max; p++) { dtvals[p] = Math.Pow(2.0, p - 9); } // // Take various Euler timesteps. // For stepsize dt, we will need to take L Euler steps to reach time TMAX. // double[] xtemp = new double[m]; double[] xem = new double[p_max]; for (p = 0; p < p_max; p++) { int l = (int)Math.Pow(2, 9 - p); double dt = dtvals[p]; for (i = 0; i < m; i++) { xtemp[i] = xzero; } int j; for (j = 0; j < l; j++) { double[] winc = typeMethods.r8vec_normal_01_new(m, ref data, ref seed); switch (method) { case 0: { for (i = 0; i < m; i++) { winc[i] = Math.Sqrt(dt) * winc[i]; } break; } default: { for (i = 0; i < m; i++) { winc[i] = Math.Sqrt(dt) * typeMethods.r8_sign(winc[i]); } break; } } for (i = 0; i < m; i++) { xtemp[i] = xtemp[i] + dt * lambda * xtemp[i] + mu * xtemp[i] * winc[i]; } } // // Average the M results for this stepsize. // xem[p] = typeMethods.r8vec_mean(m, xtemp); } // // Compute the error in the estimates for each stepsize. // for (p = 0; p < p_max; p++) { xerr[p] = Math.Abs(xem[p] - Math.Exp(lambda)); } // // Least squares fit of error = c * dt^q. // double[] a = new double[p_max * 2]; double[] rhs = new double[p_max]; for (i = 0; i < p_max; i++) { a[i + 0 * p_max] = 1.0; a[i + 1 * p_max] = Math.Log(dtvals[i]); rhs[i] = Math.Log(xerr[i]); } double[] sol = QRSolve.qr_solve(p_max, 2, a, rhs); Console.WriteLine(""); Console.WriteLine("EMWEAK:"); switch (method) { case 0: Console.WriteLine(" Using standard Euler-Maruyama method."); break; default: Console.WriteLine(" Using weak Euler-Maruyama method."); break; } Console.WriteLine(" Least squares solution to Error = c * dt ^ q"); Console.WriteLine(" (Expecting Q to be about 1.)"); Console.WriteLine(" Computed Q = " + sol[1] + ""); double resid = 0.0; for (i = 0; i < p_max; i++) { double e = a[i + 0 * p_max] * sol[0] + a[i + 1 * p_max] * sol[1] - rhs[i]; resid += e * e; } resid = Math.Sqrt(resid); Console.WriteLine(" Residual is " + resid + ""); }
public static double[] vandermonde_approx_1d_coef(int n, int m, double[] x, double[] y) //****************************************************************************80 // // Purpose: // // VANDERMONDE_APPROX_1D_COEF computes a 1D polynomial approximant. // // Discussion: // // We assume the approximating function has the form // // p(x) = c0 + c1 * x + c2 * x^2 + ... + cm * x^m. // // We have n data values (x(i),y(i)) which must be approximated: // // p(x(i)) = c0 + c1 * x(i) + c2 * x(i)^2 + ... + cm * x(i)^m = y(i) // // This can be cast as an Nx(M+1) linear system for the polynomial // coefficients: // // [ 1 x1 x1^2 ... x1^m ] [ c0 ] = [ y1 ] // [ 1 x2 x2^2 ... x2^m ] [ c1 ] = [ y2 ] // [ .................. ] [ ... ] = [ ... ] // [ 1 xn xn^2 ... xn^m ] [ cm ] = [ yn ] // // In the typical case, N is greater than M+1 (we have more data and equations // than degrees of freedom) and so a least squares solution is appropriate, // in which case the computed polynomial will be a least squares approximant // to the data. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 10 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int N, the number of data points. // // Input, int M, the degree of the polynomial. // // Input, double X[N], Y[N], the data values. // // Output, double VANDERMONDE_APPROX_1D_COEF[M+1], the coefficients of // the approximating polynomial. C(0) is the constant term, and C(M) // multiplies X^M. // { double[] a = VandermondeMatrix.vandermonde_approx_1d_matrix(n, m, x); double[] c = QRSolve.qr_solve(n, m + 1, a, y); return(c); }
public static double[] vandermonde_approx_2d_coef(int n, int m, double[] x, double[] y, double[] z) //****************************************************************************80 // // Purpose: // // VANDERMONDE_APPROX_2D_COEF computes a 2D polynomial approximant. // // Discussion: // // We assume the approximating function has the form of a polynomial // in X and Y of total degree M. // // p(x,y) = c00 // + c10 * x + c01 * y // + c20 * x^2 + c11 * xy + c02 * y^2 // + ... // + cm0 * x^(m) + ... + c0m * y^m. // // If we let T(K) = the K-th triangular number // = sum ( 1 <= I <= K ) I // then the number of coefficients in the above polynomial is T(M+1). // // We have n data locations (x(i),y(i)) and values z(i) to approximate: // // p(x(i),y(i)) = z(i) // // This can be cast as an NxT(M+1) linear system for the polynomial // coefficients: // // [ 1 x1 y1 x1^2 ... y1^m ] [ c00 ] = [ z1 ] // [ 1 x2 y2 x2^2 ... y2^m ] [ c10 ] = [ z2 ] // [ 1 x3 y3 x3^2 ... y3^m ] [ c01 ] = [ z3 ] // [ ...................... ] [ ... ] = [ ... ] // [ 1 xn yn xn^2 ... yn^m ] [ c0m ] = [ zn ] // // In the typical case, N is greater than T(M+1) (we have more data and // equations than degrees of freedom) and so a least squares solution is // appropriate, in which case the computed polynomial will be a least squares // approximant to the data. // // The polynomial defined by the T(M+1) coefficients C could be evaluated // at the Nx2-vector x by the command // // pval = r8poly_value_2d ( m, c, n, x ) // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 12 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int N, the number of data points. // // Input, int M, the maximum degree of the polynomial. // // Input, double X[N], Y[N] the data locations. // // Input, double Z[N], the data values. // // Output, double VANDERMONDE_APPROX_2D_COEF[T(M+1)], the // coefficients of the approximating polynomial. // { int tm = typeMethods.triangle_num(m + 1); double[] a = VandermondeMatrix.vandermonde_approx_2d_matrix(n, m, tm, x, y); double[] c = QRSolve.qr_solve(n, tm, a, z); return(c); }
public static double[] chebyshev_coef_1d(int nd, double[] xd, double[] yd, ref double xmin, ref double xmax) //****************************************************************************80 // // Purpose: // // CHEBYSHEV_COEF_1D determines the Chebyshev interpolant coefficients. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 28 September 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int ND, the number of data points. // ND must be at least 1. // // Input, double XD[ND], the data locations. // // Input, double YD[ND], the data values. // // Output, double &XMIN, &XMAX, the interpolation interval. // // Output, double CHEBYSHEV_COEF_1D[ND], the Chebyshev coefficients. // { double[] c; int i; int j; switch (nd) { case 1: xmin = xd[0]; xmax = xd[0]; c = new double[nd]; c[0] = 1.0; return(c); } xmin = typeMethods.r8vec_min(nd, xd); xmax = typeMethods.r8vec_max(nd, xd); // // Map XD to [-1,+1]. // double[] x = new double[nd]; for (i = 0; i < nd; i++) { x[i] = (2.0 * xd[i] - xmin - xmax) / (xmax - xmin); } // // Form the Chebyshev Vandermonde matrix. // double[] a = new double[nd * nd]; for (j = 0; j < nd; j++) { for (i = 0; i < nd; i++) { a[i + j * nd] = Math.Cos(Math.Acos(x[i]) * j); } } // // Solve for the expansion coefficients. // c = QRSolve.qr_solve(nd, nd, a, yd); return(c); }
public static void milstrong(ref typeMethods.r8vecNormalData data, ref int seed, int p_max, ref double[] dtvals, ref double[] xerr) //****************************************************************************80 // // Purpose: // // MILSTRONG tests the strong convergence of the Milstein method. // // Discussion: // // This function solves the stochastic differential equation // // dX = sigma * X * ( k - X ) dt + beta * X dW, // X(0) = Xzero, // // where // // sigma = 2, // k = 1, // beta = 1, // Xzero = 0.5. // // The discretized Brownian path over [0,1] has dt = 2^(-11). // // The Milstein method uses timesteps 128*dt, 64*dt, 32*dt, 16*dt // (also dt for reference). // // We examine strong convergence at T=1: // // E | X_L - X(T) |. // // The code is vectorized: all paths computed simultaneously. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 28 September 2012 // // Author: // // Original MATLAB version by Desmond Higham. // C++ version by John Burkardt. // // Reference: // // Desmond Higham, // An Algorithmic Introduction to Numerical Simulation of // Stochastic Differential Equations, // SIAM Review, // Volume 43, Number 3, September 2001, pages 525-546. // // Parameters: // // Input/output, int &SEED, a seed for the random // number generator. // // Input, int P_MAX, the number of time step sizes to use. // A typical value is 4. // // Output, double DTVALS[P_MAX], the time steps used. // // Output, double XERR[P_MAX], the averaged absolute error in the // solution estimate at the final time. // { int i; int j; int p; // // Set problem parameters. // const double sigma = 2.0; const double k = 1.0; const double beta = 0.25; const double xzero = 0.5; // // Set stepping parameters. // const double tmax = 1.0; int n = (int)Math.Pow(2, 11); double dt = tmax / n; // // Number of paths sampled. // const int m = 500; // // Define the increments dW. // double[] dw = typeMethods.r8mat_normal_01_new(m, n, ref data, ref seed); for (j = 0; j < n; j++) { for (i = 0; i < m; i++) { dw[i + j * m] = Math.Sqrt(dt) * dw[i + j * m]; } } // // Estimate the reference solution at time T M times. // double[] xref = new double[m]; for (i = 0; i < m; i++) { xref[i] = xzero; } for (j = 0; j < n; j++) { for (i = 0; i < m; i++) { xref[i] = xref[i] + dt * sigma * xref[i] * (k - xref[i]) + beta * xref[i] * dw[i + j * m] + 0.5 * beta * beta * xref[i] * (dw[i + j * m] * dw[i + j * m] - dt); } } // // Now compute M Milstein approximations at each of 4 timesteps, // and record the average errors. // for (p = 0; p < p_max; p++) { dtvals[p] = dt * 8.0 * Math.Pow(2.0, p + 1); } for (p = 0; p < p_max; p++) { xerr[p] = 0.0; } double[] xtemp = new double[m]; for (p = 0; p < p_max; p++) { int r = 8 * (int)Math.Pow(2, p + 1); double dtp = dtvals[p]; int l = n / r; for (i = 0; i < m; i++) { xtemp[i] = xzero; } for (j = 0; j < l; j++) { for (i = 0; i < m; i++) { double winc = 0.0; int i2; for (i2 = r * j; i2 < r * (j + 1); i2++) { winc += dw[i + i2 * m]; } xtemp[i] = xtemp[i] + dtp * sigma * xtemp[i] * (k - xtemp[i]) + beta * xtemp[i] * winc + 0.5 * beta * beta * xtemp[i] * (winc * winc - dtp); } } xerr[p] = 0.0; for (i = 0; i < m; i++) { xerr[p] += Math.Abs(xtemp[i] - xref[i]); } xerr[p] /= m; } // // Least squares fit of error = C * dt^q // double[] a = new double[p_max * 2]; double[] rhs = new double[p_max]; for (p = 0; p < p_max; p++) { a[p + 0 * p_max] = 1.0; a[p + 1 * p_max] = Math.Log(dtvals[p]); rhs[p] = Math.Log(xerr[p]); } double[] sol = QRSolve.qr_solve(p_max, 2, a, rhs); Console.WriteLine(""); Console.WriteLine("MILSTEIN:"); Console.WriteLine(" Least squares solution to Error = c * dt ^ q"); Console.WriteLine(" Expecting Q to be about 1."); Console.WriteLine(" Computed Q = " + sol[1] + ""); double resid = 0.0; for (i = 0; i < p_max; i++) { double e = a[i + 0 * p_max] * sol[0] + a[i + 1 * p_max] * sol[1] - rhs[i]; resid += e * e; } resid = Math.Sqrt(resid); Console.WriteLine(" Residual is " + resid + ""); }
public static void line_fekete_chebyshev(int m, double a, double b, int n, double[] x, ref int nf, ref double[] xf, ref double[] wf) //****************************************************************************80 // // Purpose: // // LINE_FEKETE_CHEBYSHEV: approximate Fekete points in an interval [A,B]. // // Discussion: // // We use the Chebyshev basis. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 13 April 2014 // // Author: // // John Burkardt // // Reference: // // Len Bos, Norm Levenberg, // On the calculation of approximate Fekete points: the univariate case, // Electronic Transactions on Numerical Analysis, // Volume 30, pages 377-397, 2008. // // Parameters: // // Input, int M, the number of basis polynomials. // // Input, double A, B, the endpoints of the interval. // // Input, int N, the number of sample points. // M <= N. // // Input, double X(N), the coordinates of the sample points. // // Output, int &NF, the number of Fekete points. // If the computation is successful, NF = M. // // Output, double XF(NF), the coordinates of the Fekete points. // // Output, double WF(NF), the weights of the Fekete points. // { int i; int j; if (n < m) { Console.WriteLine(""); Console.WriteLine("LINE_FEKETE_CHEBYSHEV - Fatal error!"); Console.WriteLine(" N < M."); return; } // // Compute the Chebyshev-Vandermonde matrix. // double[] v = VandermondeMatrix.cheby_van1(m, a, b, n, x); // // MOM(I) = Integral ( A <= x <= B ) Tab(A,B,I;x) dx // double[] mom = new double[m]; mom[0] = Math.PI * (b - a) / 2.0; for (i = 1; i < m; i++) { mom[i] = 0.0; } // // Solve the system for the weights W. // double[] w = QRSolve.qr_solve(m, n, v, mom); // // Extract the data associated with the nonzero weights. // nf = 0; for (j = 0; j < n; j++) { if (w[j] == 0.0) { continue; } if (nf >= m) { continue; } xf[nf] = x[j]; wf[nf] = w[j]; nf += 1; } }
public static void line_fekete_monomial(int m, double a, double b, int n, double[] x, ref int nf, ref double[] xf, ref double[] wf) //****************************************************************************80 // // Purpose: // // LINE_FEKETE_MONOMIAL: approximate Fekete points in an interval [A,B]. // // Discussion: // // We use the uniform weight and the monomial basis: // // P(j) = x^(j-1) // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 13 April 2014 // // Author: // // John Burkardt // // Reference: // // Alvise Sommariva, Marco Vianello, // Computing approximate Fekete points by QR factorizations of Vandermonde // matrices, // Computers and Mathematics with Applications, // Volume 57, 2009, pages 1324-1336. // // Parameters: // // Input, int M, the number of basis polynomials. // // Input, double A, B, the endpoints of the interval. // // Input, int N, the number of sample points. // M <= N. // // Input, double X(N), the coordinates of the sample points. // // Output, int &NF, the number of Fekete points. // If the computation is successful, NF = M. // // Output, double XF(NF), the coordinates of the Fekete points. // // Output, double WF(NF), the weights of the Fekete points. // { int j; if (n < m) { Console.WriteLine(""); Console.WriteLine("LINE_FEKETE_MONOMIAL - Fatal error!"); Console.WriteLine(" N < M."); return; } // // Form the moments. // double[] mom = Monomial.line_monomial_moments(a, b, m); // // Form the rectangular Vandermonde matrix V for the polynomial basis. // double[] v = new double[m * n]; for (j = 0; j < n; j++) { v[0 + j * m] = 1.0; int i; for (i = 1; i < m; i++) { v[i + j * m] = v[i - 1 + j * m] * x[j]; } } // // Solve the system for the weights W. // double[] w = QRSolve.qr_solve(m, n, v, mom); // // Extract the data associated with the nonzero weights. // nf = 0; for (j = 0; j < n; j++) { if (w[j] == 0.0) { continue; } if (nf >= m) { continue; } xf[nf] = x[j]; wf[nf] = w[j]; nf += 1; } }
public static double[] lagrange_approx_1d(int m, int nd, double[] xd, double[] yd, int ni, double[] xi) //****************************************************************************80 // // Purpose: // // LAGRANGE_APPROX_1D evaluates the Lagrange approximant of degree M. // // Discussion: // // The Lagrange approximant L(M,ND,XD,YD)(X) is a polynomial of // degree M which approximates the data (XD(I),YD(I)) for I = 1 to ND. // // We can represent any polynomial of degree M+1 as the sum of the Lagrange // basis functions at the M+1 Chebyshev points. // // L(M)(X) = sum ( 1 <= I <= M+1 ) C(I) LB(M,XC)(X) // // Given our data, we can seek the M+1 unknown coefficients C which minimize // the norm of || L(M)(XD(1:ND)) - YD(1:ND) ||. // // Given the coefficients, we can then evaluate the polynomial at the // points XI. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 09 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the polynomial degree. // // Input, int ND, the number of data points. // ND must be at least 1. // // Input, double XD[ND], the data points. // // Input, double YD[ND], the data values. // // Input, int NI, the number of interpolation points. // // Input, double XI[NI], the interpolation points. // // Output, double LAGRANGE_APPROX_1D[NI], the interpolated values. // { int nc = m + 1; // // Evaluate the Chebyshev points. // const double a = -1.0; const double b = +1.0; double[] xc = typeMethods.r8vec_cheby_extreme_new(nc, a, b); // // Evaluate the Lagrange basis functions for the Chebyshev points // at the data points. // double[] ld = lagrange_basis_1d(nc, xc, nd, xd); // // The value of the Lagrange approximant at each data point should // approximate the data value: LD * YC = YD, where YC are the unknown // coefficients. // double[] yc = QRSolve.qr_solve(nd, nc, ld, yd); // // Now we want to evaluate the Lagrange approximant at the "interpolant // points": LI * YC = YI // double[] li = lagrange_basis_1d(nc, xc, ni, xi); double[] yi = typeMethods.r8mat_mv_new(ni, nc, li, yc); return(yi); }
private static void test01(int prob, int m) //****************************************************************************80 // // Purpose: // // TEST01 tests VANDERMONDE_APPROX_1D_MATRIX. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 10 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int PROB, the problem number. // // Input, int M, the polynomial degree. // { const bool debug = false; int i; Console.WriteLine(""); Console.WriteLine("TEST01:"); Console.WriteLine(" Approximate data from TEST_INTERP problem #" + prob + ""); 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]; } // // Compute the Vandermonde matrix. // Console.WriteLine(" Using polynomial approximant of degree " + m + ""); double[] a = VandermondeMatrix.vandermonde_approx_1d_matrix(nd, m, xd); // // Solve linear system. // double[] c = QRSolve.qr_solve(nd, m + 1, a, yd); // // #1: Does approximant match function at data points? // int ni = nd; double[] xi = typeMethods.r8vec_copy_new(ni, xd); double[] yi = Polynomial.r8poly_values(m, c, ni, xi); double app_error = typeMethods.r8vec_norm_affine(ni, yi, yd) / ni; Console.WriteLine(""); Console.WriteLine(" L2 data approximation error = " + app_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 xmin = typeMethods.r8vec_min(nd, xd); double xmax = typeMethods.r8vec_max(nd, xd); double ymin = typeMethods.r8vec_min(nd, yd); double ymax = typeMethods.r8vec_max(nd, yd); ni = 501; xi = typeMethods.r8vec_linspace_new(ni, xmin, xmax); yi = Polynomial.r8poly_values(m, c, 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(""); Console.WriteLine(" Normalized length of piecewise linear interpolant = " + ld + ""); Console.WriteLine(" Normalized length of polynomial interpolant = " + li + ""); }
private static void qr_solve_test() //****************************************************************************80 // // Purpose: // // QR_SOLVE_TEST tests QR_SOLVE. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 21 April 2012 // // Author: // // John Burkardt // { int prob; Console.WriteLine(""); Console.WriteLine("QR_SOLVE_TEST"); Console.WriteLine(" QR_SOLVE is a function with a simple interface which"); Console.WriteLine(" solves a linear system A*x = b in the least squares sense."); Console.WriteLine(" Compare a tabulated solution X1 to the QR_SOLVE result X2."); int prob_num = ProbabilityFunctions.p00_prob_num(); Console.WriteLine(""); Console.WriteLine(" Number of problems = " + prob_num + ""); Console.WriteLine(""); Console.WriteLine(" Index M N ||B|| ||X1 - X2|| ||X1|| ||X2|| ||R1|| ||R2||"); Console.WriteLine(""); for (prob = 1; prob <= prob_num; prob++) { // // Get problem size. // int m = ProbabilityFunctions.p00_m(prob); int n = ProbabilityFunctions.p00_n(prob); // // Retrieve problem data. // double[] a = ProbabilityFunctions.p00_a(prob, m, n); double[] b = ProbabilityFunctions.p00_b(prob, m); double[] x1 = ProbabilityFunctions.p00_x(prob, n); double b_norm = typeMethods.r8vec_norm(m, b); double x1_norm = typeMethods.r8vec_norm(n, x1); double[] r1 = typeMethods.r8mat_mv_new(m, n, a, x1); int i; for (i = 0; i < m; i++) { r1[i] -= b[i]; } double r1_norm = typeMethods.r8vec_norm(m, r1); // // Use QR_SOLVE on the problem. // double[] x2 = QRSolve.qr_solve(m, n, a, b); double x2_norm = typeMethods.r8vec_norm(n, x2); double[] r2 = typeMethods.r8mat_mv_new(m, n, a, x2); for (i = 0; i < m; i++) { r2[i] -= b[i]; } double r2_norm = typeMethods.r8vec_norm(m, r2); // // Compare tabulated and computed solutions. // double x_diff_norm = typeMethods.r8vec_norm_affine(n, x1, x2); // // Report results for this problem. // Console.WriteLine(" " + prob.ToString(CultureInfo.InvariantCulture).PadLeft(5) + " " + m.ToString(CultureInfo.InvariantCulture).PadLeft(4) + " " + n.ToString(CultureInfo.InvariantCulture).PadLeft(4) + " " + b_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12) + " " + x_diff_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12) + " " + x1_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12) + " " + x2_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12) + " " + r1_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12) + " " + r2_norm.ToString(CultureInfo.InvariantCulture).PadLeft(12) + ""); } }
private static void test01(int prob, int grd, int m) //****************************************************************************80 // // Purpose: // // VANDERMONDE_APPROX_2D_TEST01 tests VANDERMONDE_APPROX_2D_MATRIX. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 11 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int PROB, the problem number. // // Input, int GRD, the grid number. // (Can't use GRID as the name because that's also a plotting function.) // // Input, int M, the total polynomial degree. // { Console.WriteLine(""); Console.WriteLine("TEST01:"); Console.WriteLine(" Approximate data from TEST_INTERP_2D problem #" + prob + ""); Console.WriteLine(" Use grid from TEST_INTERP_2D with index #" + grd + ""); Console.WriteLine(" Using polynomial approximant of total degree " + m + ""); int nd = Data_2D.g00_size(grd); Console.WriteLine(" Number of data points = " + nd + ""); double[] xd = new double[nd]; double[] yd = new double[nd]; Data_2D.g00_xy(grd, nd, ref xd, ref yd); double[] zd = new double[nd]; Data_2D.f00_f0(prob, nd, xd, yd, ref zd); switch (nd) { case < 10: typeMethods.r8vec3_print(nd, xd, yd, zd, " X, Y, Z data:"); break; } // // Compute the Vandermonde matrix. // int tm = typeMethods.triangle_num(m + 1); double[] a = VandermondeMatrix.vandermonde_approx_2d_matrix(nd, m, tm, xd, yd); // // Solve linear system. // double[] c = QRSolve.qr_solve(nd, tm, a, zd); // // #1: Does approximant match function at data points? // int ni = nd; double[] xi = typeMethods.r8vec_copy_new(ni, xd); double[] yi = typeMethods.r8vec_copy_new(ni, yd); double[] zi = Polynomial.r8poly_values_2d(m, c, ni, xi, yi); double app_error = typeMethods.r8vec_norm_affine(ni, zi, zd) / ni; Console.WriteLine(""); Console.WriteLine(" L2 data approximation error = " + app_error + ""); }
private static void test01(int prob, int m) //****************************************************************************80 // // Purpose: // // TEST01 tests VANDERMONDE_INTERP_2D_MATRIX. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 07 October 2012 // // Author: // // John Burkardt // // Parameters: // // Input, int PROB, the problem number. // // Input, int M, the degree of interpolation. // { const bool debug = false; Console.WriteLine(""); Console.WriteLine("TEST01:"); Console.WriteLine(" Interpolate data from TEST_INTERP_2D problem #" + prob + ""); Console.WriteLine(" Create an interpolant of total degree " + m + ""); int tmp1 = typeMethods.triangle_num(m + 1); Console.WriteLine(" Number of data values needed is " + tmp1 + ""); int seed = 123456789; double[] xd = UniformRNG.r8vec_uniform_01_new(tmp1, ref seed); double[] yd = UniformRNG.r8vec_uniform_01_new(tmp1, ref seed); double[] zd = new double[tmp1]; Data_2D.f00_f0(prob, tmp1, xd, yd, ref zd); switch (debug) { case true: typeMethods.r8vec3_print(tmp1, xd, yd, zd, " X, Y, Z data:"); break; } // // Compute the Vandermonde matrix. // double[] a = Vandermonde.vandermonde_interp_2d_matrix(tmp1, m, xd, yd); // // Solve linear system. // double[] c = QRSolve.qr_solve(tmp1, tmp1, a, zd); // // #1: Does interpolant match function at data points? // int ni = tmp1; double[] xi = typeMethods.r8vec_copy_new(ni, xd); double[] yi = typeMethods.r8vec_copy_new(ni, yd); double[] zi = Polynomial.r8poly_values_2d(m, c, ni, xi, yi); double app_error = typeMethods.r8vec_norm_affine(ni, zi, zd) / ni; Console.WriteLine(""); Console.WriteLine(" L2 data interpolation error = " + app_error + ""); }