public static void tuple_next_test() //****************************************************************************80 // // Purpose: // // TUPLE_NEXT_TEST tests TUPLE_NEXT. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 11 October 2006 // // Author: // // John Burkardt // { const int N = 2; const int m1 = 2; const int m2 = 4; int[] x = new int[N]; Console.WriteLine(""); Console.WriteLine("TUPLE_NEXT_TEST"); Console.WriteLine(" TUPLE_NEXT returns the next \"tuple\", that is,"); Console.WriteLine(" a vector of N integers, each between M1 and M2."); Console.WriteLine(""); Console.WriteLine(" M1 = " + m1 + ""); Console.WriteLine(" M2 = " + m2 + ""); Console.WriteLine(" N = " + N + ""); Console.WriteLine(""); int rank = 0; for (;;) { BTuple.tuple_next(m1, m2, N, ref rank, ref x); if (rank == 0) { break; } string cout = rank.ToString().PadLeft(4); int i; for (i = 0; i < N; i++) { cout += x[i].ToString().PadLeft(4) + " "; } Console.WriteLine(cout); } }
public static void tuple_next_ge_test() //****************************************************************************80 // // Purpose: // // TUPLE_NEXT_GE_TEST tests TUPLE_NEXT_GE. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 11 October 2006 // // Author: // // John Burkardt // { const int N = 3; const int m = 3; int[] x = new int[N]; Console.WriteLine(""); Console.WriteLine("TUPLE_NEXT_GE_TEST"); Console.WriteLine(" TUPLE_NEXT_GE returns the next nondecreasting \"tuple\","); Console.WriteLine(" that is, a vector of N integers, each between 1 and M,"); Console.WriteLine(" with the additional property that the digits never decrease"); Console.WriteLine(" reading from left to right."); Console.WriteLine(""); Console.WriteLine(" M = " + m + ""); Console.WriteLine(" N = " + N + ""); Console.WriteLine(""); int rank = 0; for (;;) { BTuple.tuple_next_ge(m, N, ref rank, ref x); if (rank == 0) { break; } string cout = rank.ToString().PadLeft(4); int i; for (i = 0; i < N; i++) { cout += x[i].ToString().PadLeft(4) + " "; } Console.WriteLine(cout); } }
public static void tuple_next_fast_test() //****************************************************************************80 // // Purpose: // // TUPLE_NEXT_FAST_TEST tests TUPLE_NEXT_FAST. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 04 June 2015 // // Author: // // John Burkardt // { int[] base_ = new int[2]; const int m = 3; const int n = 2; int[] x = new int[2]; Console.WriteLine(""); Console.WriteLine("TUPLE_NEXT_FAST_TEST"); Console.WriteLine(" TUPLE_NEXT_FAST returns the next \"tuple\", that is,"); Console.WriteLine(" a vector of N integers, each between 1 and M."); Console.WriteLine(""); Console.WriteLine(" M = " + m + ""); Console.WriteLine(" N = " + n + ""); Console.WriteLine(""); // // Initialize. // int rank = -1; BTuple.tuple_next_fast(m, n, rank, ref base_, ref x); int rank_hi = (int)Math.Pow(m, n); for (rank = 0; rank < rank_hi; rank++) { BTuple.tuple_next_fast(m, n, rank, ref base_, ref x); string cout = rank.ToString().PadLeft(4); int i; for (i = 0; i < n; i++) { cout += x[i].ToString().PadLeft(4) + " "; } Console.WriteLine(cout); } }
public static double[] grid_in_cube01(int dim_num, int n, int center, ref int seed) //****************************************************************************80 // // Purpose: // // GRID_IN_CUBE01 generates a grid dataset in the unit hypercube. // // Discussion: // // N points are needed in a DIM_NUM dimensional space. // // The points are to lie on a uniform grid of side N_SIDE. // // Unless the N = N_SIDE^DIM_NUM for some N_SIDE, we can't use all the // points on a grid. What we do is find the smallest N_SIDE // that's big enough, and randomly omit some points. // // If N_SIDE is 4, then the choices in 1D are: // // A: 0, 1/3, 2/3, 1 // B: 1/5, 2/5, 3/5, 4/5 // C: 0, 1/4, 2/4, 3/4 // D: 1/4, 2/4, 3/4, 1 // E: 1/8, 3/8, 5/8, 7/8 // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 17 August 2004 // // Author: // // John Burkardt // // Parameters: // // Input, int DIM_NUM, the spatial dimension. // // Input, int N, the number of points. // // Input, int CENTER, specifies the 1D grid centering: // 1: first point is 0.0, last point is 1.0; // 2: first point is 1/(N+1), last point is N/(N+1); // 3: first point is 0, last point is (N-1)/N; // 4: first point is 1/N, last point is 1; // 5: first point is 1/(2*N), last point is (2*N-1)/(2*N); // // Input/output, int &SEED, a seed for the random number generator. // // Output, double GRID_IN_CUBE01[DIM_NUM*N], the points. // { int j; // // Find the dimension of the smallest grid with N points. // int n_side = grid_side(dim_num, n); // // We need to select N points out of N_SIDE^DIM_NUM set. // int n_grid = (int)Math.Pow(n_side, dim_num); // // Generate a random subset of N items from a set of size N_GRID. // int[] rank_list = new int[n]; Ksub.ksub_random2(n_grid, n, ref seed, ref rank_list); // // Must make one dummy call to TUPLE_NEXT_FAST with RANK = -1. // int rank = -1; int[] tuple = new int[dim_num]; BTupleData data = new() { base_ = new int[dim_num] }; BTuple.tuple_next_fast(ref data, n_side, dim_num, rank, ref tuple); // // Now generate the appropriate indices, and "center" them. // double[] r = new double[dim_num * n]; for (j = 0; j < n; j++) { rank = rank_list[j] - 1; BTuple.tuple_next_fast(ref data, n_side, dim_num, rank, ref tuple); int i; switch (center) { case 1: { for (i = 0; i < dim_num; i++) { r[i + j * dim_num] = (tuple[i] - 1) / (double)(n_side - 1); } break; } case 2: { for (i = 0; i < dim_num; i++) { r[i + j * dim_num] = tuple[i] / (double)(n_side + 1); } break; } case 3: { for (i = 0; i < dim_num; i++) { r[i + j * dim_num] = (tuple[i] - 1) / (double)n_side; } break; } case 4: { for (i = 0; i < dim_num; i++) { r[i + j * dim_num] = tuple[i] / (double)n_side; } break; } case 5: { for (i = 0; i < dim_num; i++) { r[i + j * dim_num] = (2 * tuple[i] - 1) / (double)(2 * n_side); } break; } } } return(r); }
private static void test02() //****************************************************************************80 // // Purpose: // // TEST02 tests CVT. R8MAT_LATINIZE. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 09 September 2006 // // Author: // // John Burkardt // { const int M = 2; const int N = 25; LCVData ldata = new(M); double[] generator = new double[M * N]; int i; const int latin_steps = 3; int rank; const int sample_function_cvt = 0; const int sample_function_init = 3; const int sample_num_cvt = 100000; const int sample_num_steps = 50; int[] tuple = new int[M]; Console.WriteLine(""); Console.WriteLine("TEST02"); Console.WriteLine(" CVT computes a Centroidal Voronoi Tessellation."); Console.WriteLine(" R8MAT_LATINIZE makes it a Latin Hypersquare."); Console.WriteLine(""); Console.WriteLine(" In this test, we initialize the generators to"); Console.WriteLine(" grid points; this is an unstable CVT solution."); // // GET_SEED can be used to produce a different seed on each run. // But using a fixed seed is useful for debugging. // int seed = entropyRNG.RNG.nextint(); seed = 123456789; Console.WriteLine(""); Console.WriteLine(" Spatial dimension M = " + M + ""); Console.WriteLine(" Number of generators = " + N + ""); Console.WriteLine(" Initial random number seed = " + seed + ""); ; Console.WriteLine(""); switch (sample_function_init) { case -1: Console.WriteLine(" Initialize using RANDOM_NUMBER (C++ STDLIB intrinsic)."); break; case 0: Console.WriteLine(" Initialize using UNIFORM."); break; case 1: Console.WriteLine(" Initialize using HALTON."); break; case 2: Console.WriteLine(" Initialize using GRID."); break; case 3: Console.WriteLine(" USER will initialize data."); break; } switch (sample_function_cvt) { case -1: Console.WriteLine(" Sample using RANDOM_NUMBER (C++ STDLIB intrinsic)."); break; case 0: Console.WriteLine(" Sample using UNIFORM."); break; case 1: Console.WriteLine(" Sample using HALTON."); break; case 2: Console.WriteLine(" Sample using GRID."); break; } Console.WriteLine(" Number of sample points = " + sample_num_cvt + ""); Console.WriteLine(" Number of sample steps = " + sample_num_steps + ""); int ngrid = 5; for (rank = 0; rank <= N - 1; rank++) { BTuple.tuple_next_fast(ref ldata.data.tdata, ngrid, M, rank, ref tuple); for (i = 0; i < M; i++) { generator[i + rank * M] = (2 * tuple[i] - 1) / (double)(2 * ngrid); } } typeMethods.r8mat_transpose_print(M, N, generator, " Initial generators (rows):"); for (i = 1; i <= latin_steps; i++) { LatinCentroidalVoronoi.cvt(ref ldata, M, N, sample_function_init, sample_function_cvt, sample_num_cvt, sample_num_steps, ref seed, ref generator); typeMethods.r8mat_transpose_print(M, N, generator, " After CVT steps:"); typeMethods.r8mat_latinize(M, N, ref generator); typeMethods.r8mat_transpose_print(M, N, generator, " After Latin step:"); } }
private static void test11() //****************************************************************************80 // // Purpose: // // TEST11 tests CVT. // // Discussion: // // In this test, we initialize the generators to grid points; this is // an unstable CVT solution. The data would "prefer" to be in a // different form. However, even if we take 2000 steps of CVT iteration, // the data is still only slowly progressing towards that other // configuration. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 17 February 2007 // // Author: // // John Burkardt // { const int N = 16; const int DIM_NUM = 2; double energy = 0; double it_diff = 0; int it_num = 0; int j; double[] r = new double[DIM_NUM * N]; int[] tuple = new int[DIM_NUM]; Console.WriteLine(""); Console.WriteLine("TEST11"); Console.WriteLine(" CVT computes a Centroidal Voronoi Tessellation."); Console.WriteLine(""); Console.WriteLine(" In this test, we initialize the generators to"); Console.WriteLine(" grid points; this is an unstable CVT solution."); const int batch = 1000; const int init = 4; const string init_string = "user initialization"; const int it_max = 40; const int it_fixed = 1; const int sample = 0; const int sample_num = 1000; const string sample_string = "uniform"; int seed = 123456789; int seed_init = seed; // // Initialize the tuple generator. // int rank = -1; const int ngrid = 4; CVTHaltonData data = new(DIM_NUM); BTuple.tuple_next_fast(ref data.tupledata, ngrid, DIM_NUM, rank, ref tuple); // // Pick points on a grid. // for (j = 0; j < N; j++) { rank = j; BTuple.tuple_next_fast(ref data.tupledata, ngrid, DIM_NUM, rank, ref tuple); int i; for (i = 0; i < DIM_NUM; i++) { r[i + j * DIM_NUM] = (2 * tuple[i] - 1) / (double)(2 * ngrid); } } typeMethods.r8mat_transpose_print(DIM_NUM, N, r, " Initial generators (rows):"); CentroidalVoronoi.cvt(ref data, DIM_NUM, N, batch, init, sample, sample_num, it_max, it_fixed, ref seed, ref r, ref it_num, ref it_diff, ref energy); Console.WriteLine(""); Console.WriteLine(" Dimension DIM_NUM = " + DIM_NUM + ""); Console.WriteLine(" Number of points N = " + N + ""); Console.WriteLine(" Initial SEED = " + seed_init + ""); Console.WriteLine(" Current SEED = " + seed + ""); Console.WriteLine(" INIT = \"" + init_string + "\"."); Console.WriteLine(" Max iterations IT_MAX = " + it_max + ""); Console.WriteLine(" IT_FIXED (fixed samples) = " + it_fixed + ""); Console.WriteLine(" Iterations IT_NUM = " + it_num + ""); Console.WriteLine(" Difference IT_DIFF = " + it_diff + ""); Console.WriteLine(" CVT ENERGY = " + energy + ""); Console.WriteLine(" SAMPLE = \"" + sample_string + "\"."); Console.WriteLine(" Samples SAMPLE_NUM = " + sample_num + ""); Console.WriteLine(" Sampling BATCH size = " + batch + ""); Console.WriteLine(" EPSILON (unit roundoff) = " + typeMethods.r8_epsilon() + ""); typeMethods.r8mat_transpose_print(DIM_NUM, N, r, " Generators (rows):"); }
public static double fibonacci_lattice_t(int k, Func <int, double[], double> f) //****************************************************************************80 // // Purpose: // // FIBONACCI_LATTICE_T applies a symmetric Fibonacci lattice integration rule in 2D. // // Discussion: // // This routine may be applied to integrands which are not periodic. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 21 November 2008 // // Author: // // John Burkardt // // Reference: // // Ian Sloan, Stephen Joe, // Lattice Methods for Multiple Integration, // Oxford, 1994, // ISBN: 0198534728, // LC: QA311.S56 // // Parameters: // // Input, int K, the index of the Fibonacci number to be used. // K must be at least 3. // // Input, double F ( int DIM_NUM, double X[] ), the name of the // user-supplied routine which evaluates the function. // // Output, double FIBONACCI_LATTICE_T, the estimated integral. // { const int dim_num = 2; int i; int j; double[] x = new double[dim_num]; int[] z = new int[dim_num]; double quad = 0.0; int m = Helpers.fibonacci(k); // // Get all the corner values. // int rank = 0; double quad1 = 0.0; double w = 1.0 / (int)Math.Pow(2, dim_num); for (;;) { BTuple.tuple_next(0, 1, dim_num, ref rank, ref z); if (rank == 0) { break; } for (i = 0; i < dim_num; i++) { x[i] = z[i]; } quad1 += w * f(dim_num, x); } // // Get the interior values. // z[0] = 1; z[1] = Helpers.fibonacci(k - 1); double quad2 = 0.0; for (j = 1; j <= m - 1; j++) { for (i = 0; i < dim_num; i++) { x[i] = j * z[i] / (double)m % 1.0; } quad2 += f(dim_num, x); } quad = (quad1 + quad2) / m; return(quad); }
public static double fibonacci_lattice_b(int k, Func <int, double[], double> f) //****************************************************************************80 // // Purpose: // // FIBONACCI_LATTICE_B applies an optimal Fibonacci lattice integration rule in 2D. // // Discussion: // // This routine may be applied to integrands which are not periodic. // // When K is odd, this is the same as the symmetric Fibonacci lattice // integration rule. But when K is even, a correction is made to the // corner weights which is expected to improve the results. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 19 November 2008 // // Author: // // John Burkardt // // Reference: // // Ian Sloan, Stephen Joe, // Lattice Methods for Multiple Integration, // Oxford, 1994, // ISBN: 0198534728, // LC: QA311.S56 // // Parameters: // // Input, int K, the index of the Fibonacci number to be used. // K must be at least 3. // // Input, double F ( int DIM_NUM, double X[] ), the name of the // user-supplied routine which evaluates the function. // // Output, double FIBONACCI_LATTICE_B, the estimated integral. // { int dim; const int dim_num = 2; int j; double[] w = new double[2 * 2]; double[] x = new double[dim_num]; int[] z = new int[dim_num]; int m = Helpers.fibonacci(k); int n = Helpers.fibonacci(k - 1); switch (k % 2) { // // Get the corner weights. // case 1: w[0 + 0 * 2] = 1.0 / (4 * m); w[1 + 0 * 2] = 1.0 / (4 * m); w[0 + 1 * 2] = 1.0 / (4 * m); w[1 + 1 * 2] = 1.0 / (4 * m); break; default: { double delta = 0.0; for (j = 1; j <= m - 1; j++) { delta += j * (j * n % m) / (double)(m * m); } w[0 + 0 * 2] = 0.25 - delta / m; delta = 0.0; for (j = 1; j <= m - 1; j++) { delta += j * (m - j * n % m) / (double)(m * m); } w[0 + 1 * 2] = 0.25 - delta / m; w[1 + 0 * 2] = w[0 + 1 * 2]; w[1 + 1 * 2] = w[0 + 0 * 2]; break; } } // // Get all the corner values. // int rank = 0; double quad1 = 0.0; for (;;) { BTuple.tuple_next(0, 1, dim_num, ref rank, ref z); if (rank == 0) { break; } for (dim = 0; dim < dim_num; dim++) { x[dim] = z[dim]; } quad1 += w[z[0] + z[1] * 2] * f(dim_num, x); } // // Get the interior values. // z[0] = 1; z[1] = Helpers.fibonacci(k - 1); double quad2 = 0.0; for (j = 1; j <= m - 1; j++) { for (dim = 0; dim < dim_num; dim++) { x[dim] = j * z[dim] / (double)m % 1.0; } quad2 += f(dim_num, x); } double quad = quad1 + quad2 / m; return(quad); }
public static double box_nd(Func <int, double[], double> func, int dim_num, int order, double[] xtab, double[] weight, ref int eval_num) //****************************************************************************80 // // Purpose: // // BOX_ND estimates a multidimensional integral using a product rule. // // Discussion: // // The routine creates a DIM_NUM-dimensional product rule from a 1D rule // supplied by the user. The routine is fairly inflexible. If // you supply a rule for integration from -1 to 1, then your product // box must be a product of DIM_NUM copies of the interval [-1,1]. // // 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, int ORDER, the number of points used in the 1D rule. // // Input, double XTAB[ORDER], the abscissas of the 1D rule. // // Input, double WEIGHT[ORDER], the weights of the 1D rule. // // Output, int *EVAL_NUM, the number of function evaluations. // // Output, double BOX_ND, the approximate value of the integral. // { eval_num = 0; switch (dim_num) { case < 1: Console.WriteLine(""); Console.WriteLine("BOX_ND - Fatal error!"); Console.WriteLine(" DIM_NUM < 1."); Console.WriteLine(" DIM_NUM = " + dim_num + ""); return(1); } switch (order) { case < 1: Console.WriteLine(""); Console.WriteLine("BOX_ND - Fatal error!"); Console.WriteLine(" ORDER < 1."); Console.WriteLine(" ORDER = " + order + ""); return(1); } int k = 0; double result = 0.0; int[] indx = new int[dim_num]; double[] x = new double[dim_num]; for (;;) { BTuple.tuple_next(1, order, dim_num, ref k, ref indx); if (k == 0) { break; } double w = 1.0; int dim; for (dim = 0; dim < dim_num; dim++) { w *= weight[indx[dim] - 1]; } for (dim = 0; dim < dim_num; dim++) { x[dim] = xtab[indx[dim] - 1]; } result += w * func(dim_num, x); eval_num += 1; } return(result); }
public static void cvt_sample(ref CVTHaltonData data, int dim_num, int n, int n_now, int sample, bool initialize, ref int seed, ref double[] r) //****************************************************************************80 // // Purpose: // // CVT_SAMPLE returns sample points. // // Discussion: // // N sample points are to be taken from the unit box of dimension DIM_NUM. // // These sample points are usually created by a pseudorandom process // for which the points are essentially indexed by a quantity called // SEED. To get N sample points, we generate values with indices // SEED through SEED+N-1. // // It may not be practical to generate all the sample points in a // single call. For that reason, the routine allows the user to // request a total of N points, but to require that only N_NOW be // generated now (on this call). // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 23 June 2005 // // Author: // // John Burkardt // // Parameters: // // Input, int DIM_NUM, the spatial dimension. // // Input, int N, the number of Voronoi cells. // // Input, int N_NOW, the number of sample points to be generated // on this call. N_NOW must be at least 1. // // Input, int SAMPLE, specifies how the sampling is done. // -1, 'RANDOM', using C++ RANDOM function; // 0, 'UNIFORM', using a simple uniform RNG; // 1, 'HALTON', from a Halton sequence; // 2, 'GRID', points from a grid; // 3, 'USER', call "user" routine. // // Input, bool INITIALIZE, is TRUE if the pseudorandom process should be // reinitialized. // // Input/output, int *SEED, the random number seed. // // Output, double R[DIM_NUM*N_NOW], the sample points. // { switch (n_now) { case < 1: Console.WriteLine(""); Console.WriteLine("CVT_SAMPLE - Fatal error!"); Console.WriteLine(" N_NOW < 1."); return; default: int i; int j; switch (sample) { case -1: { /* * if (initialize) * { * random_initialize(ref seed); * } */ for (j = 0; j < n_now; j++) { for (i = 0; i < dim_num; i++) { r[i + j * dim_num] = RNG.nextdouble(); //(double) random() / (double) RAND_MAX; } } seed += n_now * dim_num; break; } case 0: r = UniformRNG.r8mat_uniform_01(dim_num, n_now, ref seed); break; case 1: { data.halton_seed = new int[dim_num]; data.halton_leap = new int[dim_num]; data.halton_base = new int[dim_num]; int halton_step = seed; for (i = 0; i < dim_num; i++) { data.halton_seed[i] = 0; } for (i = 0; i < dim_num; i++) { data.halton_leap[i] = 1; } for (i = 0; i < dim_num; i++) { data.halton_base[i] = Prime.prime(i + 1); } Halton.i4_to_halton_sequence(dim_num, n_now, halton_step, data.halton_seed, data.halton_leap, data.halton_base, ref r); seed += n_now; break; } case 2: { double exponent = 1.0 / dim_num; data.ngrid = (int)Math.Pow(n, exponent); int rank_max = (int)Math.Pow(data.ngrid, dim_num); data.tuple = new int[dim_num]; if (rank_max < n) { data.ngrid += 1; rank_max = (int)Math.Pow(data.ngrid, dim_num); } switch (initialize) { case true: data.rank = -1; BTuple.tuple_next_fast(ref data.tupledata, data.ngrid, dim_num, data.rank, ref data.tuple); break; } data.rank = seed % rank_max; for (j = 0; j < n_now; j++) { BTuple.tuple_next_fast(ref data.tupledata, data.ngrid, dim_num, data.rank, ref data.tuple); data.rank += 1; data.rank %= rank_max; for (i = 0; i < dim_num; i++) { r[i + j * dim_num] = (2.0 * data.tuple[i] - 1) / (2.0 * data.ngrid); } } seed += n_now; break; } case 3: user(dim_num, n_now, ref seed, ref r); break; default: Console.WriteLine(""); Console.WriteLine("CVT_SAMPLE - Fatal error!"); Console.WriteLine(" The value of SAMPLE = " + sample + " is illegal."); break; } break; } }
public static void power_rule_set(int point_num_1d, double[] x_1d, double[] w_1d, double[] r_1d, int dim_num, int point_num, ref double[] x, ref double[] w, ref double[] r) //****************************************************************************80 // // Purpose: // // POWER_RULE_SET sets up a power rule. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 08 May 2007 // // Author: // // John Burkardt // // Parameters: // // Input, int POINT_NUM_1D, the order of the 1D rule. // // Input, double X_1D[POINT_NUM_1D], the points of the 1D rule. // // Input, double W_1D[POINT_NUM_1D], the weights of the // 1D rule. // // Input, double R_1D[2], the extreme points that define // the range of the 1D region. // // Input, int DIM_NUM, the spatial dimension. // // Input, int POINT_NUM, the number of points in the rule. // // Output, double X[DIM_NUM*POINT_NUM], the points of the rule. // // Output, double W[POINT_NUM], the weights of the rule. // // Output, double R[DIM_NUM*2], the extreme points // that define the range of the product rule region. // { int dim; int[] indx = new int[dim_num]; int k = 0; for (;;) { BTuple.tuple_next(0, point_num_1d - 1, dim_num, ref k, ref indx); if (k == 0) { break; } w[k - 1] = 1.0; for (dim = 0; dim < dim_num; dim++) { w[k - 1] *= w_1d[indx[dim]]; } for (dim = 0; dim < dim_num; dim++) { x[dim + (k - 1) * dim_num] = x_1d[indx[dim]]; } } for (dim = 0; dim < dim_num; dim++) { r[dim + 0 * dim_num] = r_1d[0]; r[dim + 1 * dim_num] = r_1d[1]; } }
public static void region_sampler(ref RegionData data, int m, int n, int n_total, ref double[] x, int sample_function, bool reset, ref int seed) //****************************************************************************80 // // Purpose: // // REGION_SAMPLER returns a sample point in the physical region. // // Discussion: // // This routine original interfaced with a lower routine called // TEST_REGION, which tested whether the points generated in the // bounding box were actually inside a possibly smaller physical // region of interest. It's been a long time since that option // was actually used, so it's been dropped. // // A point is chosen in the bounding box, either by a uniform random // number generator, or from a vector Halton sequence. // // The entries of the local vector HALTON_BASE should be distinct primes. // Right now, we're assuming M is no greater than 3. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 04 March 2004 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the spatial dimension. // // Input, int N, the number of points to generate now. // // Input, int N_TOTAL, the total number of points to generate. // // Output, double X[M*N], the sample points. // // Input, int SAMPLE_FUNCTION, region sampling function: // -1, sampling function is RANDOM (C++ STDLIB library function); // 0, sampling function is UNIFORM; // 1, sampling function is HALTON; // 2, sampling function is GRID; // 3, sample points are generated elsewhere, and this routine is skipped. // // Input, bool RESET, if true, then this is the first call for a particular // calculation, and initialization should be taken care of. // // Input/output, int *SEED, the random number seed. // { int i; int j; int k; switch (sample_function) { // case -1: { for (k = 0; k < m * n; k++) { x[k] = entropyRNG.RNG.nextdouble(); } break; } case 0: { for (k = 0; k < m * n; k++) { x[k] = UniformRNG.r8_uniform_01(ref seed); } break; } case 1: { switch (reset) { case true: { data.halton_seed = 1; data.halton_base = new int[m]; for (i = 0; i < m; i++) { data.halton_base[i] = Prime.prime(i + 1); } break; } } // // The unusual syntax X+J*M essentially means pass the address of the beginning // of the J-th vector of length M in X. // for (j = 0; j < n; j++) { Halton.i4_to_halton(data.halton_seed, data.halton_base, m, ref x, rIndex: +j * m); data.halton_seed += 1; } break; } case 2: { switch (reset) { case true: { data.rank = 0; double exponent = 1.0 / m; data.ngrid = (int)Math.Pow(n_total, exponent); if (Math.Pow(data.ngrid, m) < n_total) { data.ngrid += 1; } data.tuple = new int[m]; break; } } for (j = 0; j < n; j++) { BTuple.tuple_next_fast(ref data.tdata, data.ngrid, m, data.rank, ref data.tuple); data.rank += 1; for (i = 0; i < m; i++) { x[j * m + i] = (2 * data.tuple[i] - 1) / (double)(2 * data.ngrid); } } break; } case 3: break; default: Console.WriteLine(""); Console.WriteLine("REGION_SAMPLER - Fatal error!"); Console.WriteLine(" Illegal SAMPLE_FUNCTION = " + sample_function + ""); break; } }
public static void tuple_next2_test() //****************************************************************************80 // // Purpose: // // TUPLE_NEXT2_TEST tests TUPLE_NEXT2. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 11 October 2006 // // Author: // // John Burkardt // { const int N = 3; int[] x = new int[N]; int[] xmin = { 2, 3, 8 }; int[] xmax = { 4, 3, 5 }; Console.WriteLine(""); Console.WriteLine("TUPLE_NEXT2_TEST"); Console.WriteLine(" TUPLE_NEXT2 returns the next \"tuple\","); Console.WriteLine(" that is, a vector of N integers."); Console.WriteLine(" Each position in the vector has a separate min and max."); Console.WriteLine(" reading from left to right."); Console.WriteLine(""); Console.WriteLine(" N = " + N + ""); Console.WriteLine(""); typeMethods.i4vec1_print(N, xmin, " The minimum values:"); typeMethods.i4vec1_print(N, xmax, " The maximum values:"); Console.WriteLine(""); Console.WriteLine(""); int rank = 0; for (;;) { BTuple.tuple_next2(N, xmin, xmax, ref x, ref rank); if (rank == 0) { break; } string cout = rank.ToString().PadLeft(4); int i; for (i = 0; i < N; i++) { cout += x[i].ToString().PadLeft(4) + " "; } Console.WriteLine(cout); } }