public static double monte_carlo_nd(Func <int, double[], double> func, int dim_num, double[] a, double[] b, int eval_num, ref int seed) //****************************************************************************80 // // Purpose: // // MONTE_CARLO_ND estimates a multidimensional integral using Monte Carlo. // // Discussion: // // Unlike the other routines, this routine requires the user to specify // the number of function evaluations as an INPUT quantity. // No attempt at error estimation is made. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 25 February 2007 // // Author: // // John Burkardt // // Reference: // // Philip Davis, Philip Rabinowitz, // Methods of Numerical Integration, // Second Edition, // Dover, 2007, // ISBN: 0486453391, // LC: QA299.3.D28. // // Parameters: // // Input, double FUNC ( int dim_num, double x[] ), evaluates // the function to be integrated. // // Input, int DIM_NUM, the spatial dimension. // // Input, double A[DIM_NUM], B[DIM_NUM], the integration limits. // // Input, int EVAL_NUM, the number of function evaluations. // // Input/output, int *SEED, a seed for the random number generator. // // Output, double MONTE_CARLO_ND, the approximate value of the integral. // { int dim; int i; double result = 0.0; for (i = 0; i < eval_num; i++) { double[] x = UniformRNG.r8vec_uniform_01_new(dim_num, ref seed); result += func(dim_num, x); } double volume = 1.0; for (dim = 0; dim < dim_num; dim++) { volume *= b[dim] - a[dim]; } result = result * volume / eval_num; return(result); }
public static double[] uniform_on_simplex01_map(int dim_num, int n, ref int seed) //****************************************************************************80 // // Purpose: // // UNIFORM_ON_SIMPLEX01_MAP maps uniform points onto the unit simplex. // // Discussion: // // The surface of the unit DIM_NUM-dimensional simplex is the set of points // X(1:DIM_NUM) such that each X(I) is nonnegative, // every X(I) is no greater than 1, and // // ( X(I) = 0 for some I, or sum ( X(1:DIM_NUM) ) = 1. ) // // In DIM_NUM dimensions, there are DIM_NUM sides, and one main face. // This code picks a point uniformly with respect to "area". // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 18 August 2004 // // Author: // // John Burkardt // // Reference: // // Reuven Rubinstein, // Monte Carlo Optimization, Simulation, and Sensitivity // of Queueing Networks, // Krieger, 1992, // ISBN: 0894647644, // LC: QA298.R79. // // Parameters: // // Input, int DIM_NUM, the dimension of the space. // // Input, int N, the number of points. // // Input/output, int &SEED, a seed for the random number generator. // // Output, double UNIFORM_ON_SIMPLEX01_MAP[DIM_NUM*N], the points. // { int j; // // The construction begins by sampling DIM_NUM points from the // exponential distribution with parameter 1. // double[] e = new double[dim_num]; double[] x = new double[dim_num * n]; for (j = 0; j < n; j++) { UniformRNG.r8vec_uniform_01(dim_num, ref seed, ref e); int i; for (i = 0; i < dim_num; i++) { e[i] = -Math.Log(e[i]); } double total = 0.0; for (i = 0; i < dim_num; i++) { total += e[i]; } // // Based on their relative areas, choose a side of the simplex, // or the main face. // for (i = 0; i < dim_num; i++) { x[i + j * dim_num] = e[i] / total; } double area1 = Math.Sqrt(dim_num); double area2 = dim_num; double r = UniformRNG.r8_uniform_01(ref seed); if (!(area1 / (area1 + area2) < r)) { continue; } i = UniformRNG.i4_uniform_ab(0, dim_num - 1, ref seed); x[i + j * dim_num] = 0.0; } return(x); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for FEM2D_POISSON_SPARSE. // // Discussion: // // This program uses a sparse matrix storage format and an iterative solver, // which allow it to solve larger problems faster. // // This program solves the Poisson equation // // -DEL H(X,Y) DEL U(X,Y) + K(X,Y) * U(X,Y) = F(X,Y) // // in a triangulated region in the plane. // // Along the boundary of the region, Dirichlet conditions // are imposed: // // U(X,Y) = G(X,Y) // // The code uses continuous piecewise linear basis functions on // triangles. // // Problem specification: // // The user defines the geometry by supplying two data files // which list the node coordinates, and list the nodes that make up // each element. // // The user specifies the right hand side of the Dirichlet boundary // conditions by supplying a function // // void dirichlet_condition ( int node_num, double node_xy[2*node_num], // double node_bc[node_num] ) // // The user specifies the coefficient function H(X,Y) of the Poisson // equation by supplying a routine of the form // // void h_coef ( int node_num, double node_xy[2*node_num], // double node_h[node_num] ) // // The user specifies the coefficient function K(X,Y) of the Poisson // equation by supplying a routine of the form // // void k_coef ( int node_num, double node_xy[2*node_num], // double node_k[node_num] ) // // The user specifies the right hand side of the Poisson equation // by supplying a routine of the form // // void rhs ( int node_num, double node_xy[2*node_num], // double node_f[node_num] ) // // Usage: // // fem2d_poisson_sparse prefix // // where 'prefix' is the common filename prefix so that: // // * prefix_nodes.txt contains the coordinates of the nodes; // * prefix_elements.txt contains the indices of nodes forming each element. // // Files created include: // // * prefix_values.txt, the value of the solution at every node. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 25 January 2013 // // Author: // // John Burkardt // // Local parameters: // // Local, double A[NZ_NUM], the coefficient matrix. // // Local, int ELEMENT_NODE[3*ELEMENT_NUM]; // ELEMENT_NODE(I,J) is the global index of local node I in element J. // // Local, int ELEMENT_NUM, the number of elements. // // Local, integer ELEMENT_ORDER, the element order. // // Local, double F[NODE_NUM], the right hand side. // // Local, int IA[NZ_NUM], the row indices of the nonzero entries // of the coefficient matrix. // // Local, int JA[NZ_NUM], the column indices of the nonzero entries // of the coefficient matrix. // // Local, bool NODE_BOUNDARY[NODE_NUM], is TRUE if the node is // found to lie on the boundary of the region. // // Local, int NODE_CONDITION[NODE_NUM], // indicates the condition used to determine the variable at a node. // 0, there is no condition (and no variable) at this node. // 1, a finite element equation is used; // 2, a Dirichlet condition is used. // 3, a Neumann condition is used. // // Local, int NODE_NUM, the number of nodes. // // Local, double NODE_U[NODE_NUM], the finite element coefficients. // // Local, double NODE_XY[2*NODE_NUM], the coordinates of nodes. // // Local, int NZ_NUM, the number of nonzero entries // in the coefficient matrix. // // Local, integer QUAD_NUM, the number of quadrature points used for // assembly. This is currently set to 3, the lowest reasonable value. // Legal values are 1, 3, 4, 6, 7, 9, 13, and for some problems, a value // of QUAD_NUM greater than 3 may be appropriate. // { const bool debug = false; int node; double[] node_u = null; string prefix; const int quad_num = 3; int seed = 123456789; Console.WriteLine(""); Console.WriteLine("FEM2D_POISSON_SPARSE:"); Console.WriteLine(""); Console.WriteLine(" A finite element method solver for the Poisson problem"); Console.WriteLine(" in an arbitrary triangulated region in 2 dimensions,"); Console.WriteLine(" using sparse storage and an iterative solver."); Console.WriteLine(""); Console.WriteLine(" - DEL H(x,y) DEL U(x,y) + K(x,y) * U(x,y) = F(x,y) in the region"); Console.WriteLine(""); Console.WriteLine(" U(x,y) = G(x,y) on the boundary."); Console.WriteLine(""); Console.WriteLine(" The finite element method is used,"); Console.WriteLine(" with triangular elements,"); Console.WriteLine(" which must be a 3 node linear triangle."); // // Get the filename prefix. // try { prefix = args[0]; } catch { Console.WriteLine(""); Console.WriteLine(" Please enter the filename prefix:"); prefix = Console.ReadLine(); } if (prefix != "baffle" && prefix != "ell" && prefix != "lake") { Console.WriteLine("Supported prefix value in this test is one of : baffle, ell, lake"); return; } // // Create the file names. // string node_filename = prefix + "_nodes.txt"; string element_filename = prefix + "_elements.txt"; string solution_filename = prefix + "_values.txt"; Console.WriteLine(""); Console.WriteLine(" Node file is \"" + node_filename + "\"."); Console.WriteLine(" Element file is \"" + element_filename + "\"."); // // Read the node coordinate file. // TableHeader h = typeMethods.r8mat_header_read(node_filename); int dim_num = h.m; int node_num = h.n; Console.WriteLine(" Number of nodes = " + node_num + ""); int[] node_condition = new int[node_num]; double[] node_xy = typeMethods.r8mat_data_read(node_filename, dim_num, node_num); typeMethods.r8mat_transpose_print_some(dim_num, node_num, node_xy, 1, 1, 2, 10, " First 10 nodes"); // // Read the triangle description file. // h = typeMethods.i4mat_header_read(element_filename); int element_order = h.m; int element_num = h.n; Console.WriteLine(""); Console.WriteLine(" Element order = " + element_order + ""); Console.WriteLine(" Number of elements = " + element_num + ""); if (element_order != 3) { Console.WriteLine(""); Console.WriteLine("FEM2D_POISSON_SPARSE - Fatal error!"); Console.WriteLine(" The input triangulation has order " + element_order + ""); Console.WriteLine(" However, a triangulation of order 3 is required."); return; } int[] element_node = typeMethods.i4mat_data_read(element_filename, element_order, element_num); typeMethods.i4mat_transpose_print_some(3, element_num, element_node, 1, 1, 3, 10, " First 10 elements"); Console.WriteLine(""); Console.WriteLine(" Quadrature order = " + quad_num + ""); // // Determine which nodes are boundary nodes and which have a // finite element unknown. Then set the boundary values. // bool[] node_boundary = Boundary.triangulation_order3_boundary_node(node_num, element_num, element_node); // // Determine the node conditions. // For now, we'll just assume all boundary nodes are Dirichlet. // for (node = 0; node < node_num; node++) { node_condition[node] = node_boundary[node] switch { true => 2, _ => 1 }; } // // Determine the element neighbor array, just so we can estimate // the nonzeros. // int[] element_neighbor = new int[3 * element_num]; element_neighbor = Neighbor.triangulation_order3_neighbor_triangles(element_num, element_node); // // Count the number of nonzeros. // int[] adj_col = new int[node_num + 1]; int nz_num = Adjacency.triangulation_order3_adj_count(node_num, element_num, element_node, element_neighbor, adj_col); Console.WriteLine(""); Console.WriteLine(" Number of nonzero coefficients NZ_NUM = " + nz_num + ""); // // Set up the sparse row and column index vectors. // int[] ia = new int[nz_num]; int[] ja = new int[nz_num]; Adjacency.triangulation_order3_adj_set2(node_num, element_num, element_node, element_neighbor, nz_num, adj_col, ia, ja); // // Allocate space for the coefficient matrix A and right hand side F. // double[] a = new double[nz_num]; double[] f = new double[node_num]; // // Assemble the finite element coefficient matrix A and the right-hand side F. // switch (prefix) { case "baffle": DSP.assemble_poisson_dsp(node_num, node_xy, element_num, element_node, quad_num, nz_num, ia, ja, ref a, ref f, baffle.rhs, baffle.h_coef, baffle.k_coef); break; case "ell": DSP.assemble_poisson_dsp(node_num, node_xy, element_num, element_node, quad_num, nz_num, ia, ja, ref a, ref f, ell.rhs, ell.h_coef, ell.k_coef); break; case "lake": DSP.assemble_poisson_dsp(node_num, node_xy, element_num, element_node, quad_num, nz_num, ia, ja, ref a, ref f, lake.rhs, lake.h_coef, lake.k_coef); break; } switch (debug) { // // Print a portion of the matrix. // case true: DSP.dsp_print_some(node_num, node_num, nz_num, ia, ja, a, 1, 1, 10, 10, " Part of Finite Element matrix A:"); typeMethods.r8vec_print_some(node_num, f, 1, 10, " Part of right hand side vector F:"); break; } // // Adjust the linear system to account for Dirichlet boundary conditions. // switch (prefix) { case "baffle": DSP.dirichlet_apply_dsp(node_num, node_xy, node_condition, nz_num, ia, ja, ref a, ref f, baffle.dirichlet_condition); break; case "ell": DSP.dirichlet_apply_dsp(node_num, node_xy, node_condition, nz_num, ia, ja, ref a, ref f, ell.dirichlet_condition); break; case "lake": DSP.dirichlet_apply_dsp(node_num, node_xy, node_condition, nz_num, ia, ja, ref a, ref f, lake.dirichlet_condition); break; } switch (debug) { case true: DSP.dsp_print_some(node_num, node_num, nz_num, ia, ja, a, 1, 1, 10, 10, " Part of finite Element matrix A after boundary adjustments:"); typeMethods.r8vec_print_some(node_num, f, 1, 10, " Part of right hand side vector F:"); break; } // // Solve the linear system using an iterative solver. // UniformRNG.r8vec_uniform_01(node_num, ref seed, ref node_u); int itr_max = 20; int mr = 20; double tol_abs = 0.000001; double tol_rel = 0.000001; RestartedGeneralizedMinimumResidual.mgmres(a, ia, ja, ref node_u, f, node_num, nz_num, itr_max, mr, tol_abs, tol_rel); typeMethods.r8vec_print_some(node_num, node_u, 1, 10, " Part of the solution vector vector U:"); // // Write an ASCII file that can be read into MATLAB. // typeMethods.r8mat_write(solution_filename, 1, node_num, node_u); Console.WriteLine(""); Console.WriteLine("FEM2D_POISSON_SPARSE:"); Console.WriteLine(" Wrote an ASCII file"); Console.WriteLine(" \"" + solution_filename + "\"."); Console.WriteLine(" of the form"); Console.WriteLine(" U ( X(I), Y(I) )"); Console.WriteLine(" which can be used for plotting."); switch (debug) { case true: typeMethods.r8vec_print_some(node_num, node_u, 1, 10, " Part of the solution vector:"); break; } Console.WriteLine(""); Console.WriteLine("FEM2D_POISSON_SPARSE:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); } }
public static double[] uniform_in_simplex01_map(int dim_num, int n, ref int seed) //****************************************************************************80 // // Purpose: // // UNIFORM_IN_SIMPLEX01 maps uniform points into the unit simplex. // // Discussion: // // The interior of the unit DIM_NUM dimensional simplex is the set of points X(1:DIM_NUM) // such that each X(I) is nonnegative, and sum(X(1:DIM_NUM)) <= 1. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 18 August 2004 // // Author: // // John Burkardt // // Reference: // // Reuven Rubinstein, // Monte Carlo Optimization, Simulation, and Sensitivity // of Queueing Networks, // Krieger, 1992, // ISBN: 0894647644, // LC: QA298.R79. // // Parameters: // // Input, int DIM_NUM, the dimension of the space. // // Input, int N, the number of points. // // Input/output, int &SEED, a seed for the random number generator. // // Output, double UNIFORM_IN_SIMPLEX01_MAP[DIM_NUM*N], the points. // { int j; // // The construction begins by sampling DIM_NUM+1 points from the // exponential distribution with parameter 1. // double[] e = new double[dim_num + 1]; double[] x = new double[dim_num * n]; for (j = 0; j < n; j++) { UniformRNG.r8vec_uniform_01(dim_num + 1, ref seed, ref e); int i; for (i = 0; i <= dim_num; i++) { e[i] = -Math.Log(e[i]); } double total = 0.0; for (i = 0; i <= dim_num; i++) { total += e[i]; } for (i = 0; i < dim_num; i++) { x[i + dim_num * j] = e[i] / total; } } return(x); }
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 + ""); }
private static void hpp_test01() //****************************************************************************80 // // Purpose: // // HPP_TEST01 tests routines for the GRLEX ordering of compositions. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 11 September 2014 // // Author: // // John Burkardt // { int i; int k = 2; int rank; int rank1; int rank2; int seed; int test; int[] x; int x_sum; int x_sum_old; string cout = ""; x = new int[k]; Console.WriteLine(""); Console.WriteLine("HPP_TEST01:"); Console.WriteLine(" COMP_NEXT_GRLEX is given a composition, and computes the "); Console.WriteLine(" next composition in grlex order."); Console.WriteLine(""); Console.WriteLine(" Rank Sum Components"); for (i = 0; i < k; i++) { x[i] = 0; } x_sum_old = -1; rank = 1; for (;;) { x_sum = typeMethods.i4vec_sum(k, x); if (x_sum_old < x_sum) { x_sum_old = x_sum; Console.WriteLine(""); } cout = rank.ToString().PadLeft(6) + " " + x_sum.ToString().PadLeft(6); for (i = 0; i < k; i++) { cout += x[i].ToString().PadLeft(4); } Console.WriteLine(cout); if (20 <= rank) { break; } Comp.comp_next_grlex(k, ref x); rank += 1; } Console.WriteLine(""); Console.WriteLine(" COMP_UNRANK_GRLEX is given a rank and returns the"); Console.WriteLine(" corresponding set of multinomial exponents."); Console.WriteLine(""); Console.WriteLine(" Rank Sum Components"); Console.WriteLine(""); seed = 123456789; for (test = 1; test <= 5; test++) { rank = UniformRNG.i4_uniform_ab(1, 20, ref seed); x = Comp.comp_unrank_grlex(k, rank); x_sum = typeMethods.i4vec_sum(k, x); cout = rank.ToString().PadLeft(6) + " " + x_sum.ToString().PadLeft(6); for (i = 0; i < k; i++) { cout += x[i].ToString().PadLeft(4); } Console.WriteLine(cout); } Console.WriteLine(""); Console.WriteLine(" COMP_RANDOM_GRLEX randomly selects a composition"); Console.WriteLine(" between given lower and upper ranks."); Console.WriteLine(""); Console.WriteLine(" Rank Sum Components"); Console.WriteLine(""); seed = 123456789; rank1 = 5; rank2 = 20; for (test = 1; test <= 5; test++) { x = Comp.comp_random_grlex(k, rank1, rank2, ref seed, ref rank); x_sum = typeMethods.i4vec_sum(k, x); cout = rank.ToString().PadLeft(6) + " " + x_sum.ToString().PadLeft(6); for (i = 0; i < k; i++) { cout += x[i].ToString().PadLeft(4); } Console.WriteLine(cout); } Console.WriteLine(""); Console.WriteLine(" COMP_RANK_GRLEX returns the rank of a given composition."); Console.WriteLine(""); Console.WriteLine(" Rank Sum Components"); Console.WriteLine(""); x = new int[k]; x[0] = 4; x[1] = 0; rank = Comp.comp_rank_grlex(k, x); x_sum = typeMethods.i4vec_sum(k, x); cout = rank.ToString().PadLeft(6) + " " + x_sum.ToString().PadLeft(6); for (i = 0; i < k; i++) { cout += x[i].ToString().PadLeft(4); } Console.WriteLine(cout); ; x[0] = 11; x[1] = 5; rank = Comp.comp_rank_grlex(k, x); x_sum = typeMethods.i4vec_sum(k, x); cout = rank.ToString().PadLeft(6) + " " + x_sum.ToString().PadLeft(6); for (i = 0; i < k; i++) { cout += x[i].ToString().PadLeft(4); } Console.WriteLine(cout); }
private static void hpp_test03() //****************************************************************************80 // // Purpose: // // HPP_TEST03 tests HEPP_VALUE. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 22 October 2014 // // Author: // // John Burkardt // { double[] c; int[] e; int i; int[] l; int m = 3; int n = 1; int o = 0; int o_max; int rank; int seed; double[] v1; double[] v2; double[] x; double xhi; double xlo; string cout = ""; Console.WriteLine(""); Console.WriteLine("HPP_TEST03:"); Console.WriteLine(" HEPP_VALUE evaluates a Hermite product polynomial."); Console.WriteLine(" POLYNOMIAL_VALUE evaluates a polynomial."); xlo = -1.0; xhi = +1.0; seed = 123456789; x = UniformRNG.r8vec_uniform_ab_new(m, xlo, xhi, ref seed); Console.WriteLine(""); cout = " Evaluate at X = "; for (i = 0; i < m; i++) { cout += " " + x[i + 0 * m]; } Console.WriteLine(cout); Console.WriteLine(""); Console.WriteLine(" Rank I1 I2 I3: He(I1,X1)*He(I2,X2)*He(I3,X3) P(X1,X2,X3)"); Console.WriteLine(""); for (rank = 1; rank <= 20; rank++) { l = Comp.comp_unrank_grlex(m, rank); // // Evaluate the HePP directly. // v1 = Hermite.hepp_value(m, n, l, x); // // Convert the HePP to a polynomial. // o_max = 1; for (i = 0; i < m; i++) { o_max = o_max * (l[i] + 2) / 2; } c = new double[o_max]; e = new int[o_max]; Hermite.hepp_to_polynomial(m, l, o_max, o, ref c, ref e); // // Evaluate the polynomial. // v2 = Polynomial.polynomial_value(m, o, c, e, n, x); // // Compare results. // Console.WriteLine(rank.ToString().PadLeft(6) + " " + l[0].ToString().PadLeft(2) + " " + l[1].ToString().PadLeft(2) + " " + l[2].ToString().PadLeft(2) + " " + v1[0].ToString().PadLeft(14) + " " + v2[0].ToString().PadLeft(14) + ""); } }
public static double[] r8bto_random(int m, int l, ref int seed) //****************************************************************************80 // // Purpose: // // R8BTO_RANDOM randomizes an R8BTO matrix. // // Discussion: // // The R8BTO storage format is for a block Toeplitz matrix. The matrix // can be regarded as an L by L array of blocks, each of size M by M. // The full matrix has order N = M * L. The L by L matrix is Toeplitz, // that is, along its diagonal, the blocks repeat. // // Storage for the matrix consists of the L blocks of the first row, // followed by the L-1 blocks of the first column (skipping the first row). // These items are stored in the natural way in an (M,M,2*L-1) array. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 18 January 2004 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the order of the blocks of the matrix A. // // Input, int L, the number of blocks in a row or column of A. // // Input/output, int &SEED, a seed for the random number generator. // // Output, double R8BTO_RANDOM[M*M*(2*L-1)], the R8BTO matrix. // { int i; double[] a = r8vec_zeros_new(m * m * (2 * l - 1)); for (i = 0; i < m; i++) { int j; for (j = 0; j < m; j++) { int k; for (k = 0; k < 2 * l - 1; k++) { a[i + j * m + k * m * m] = UniformRNG.r8_uniform_01(ref seed); } } } return(a); }