예제 #1
0
    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);
        }
    }
예제 #2
0
    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);
        }
    }
예제 #3
0
    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);
        }
    }
예제 #4
0
    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);
    }
예제 #5
0
    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:");
        }
    }
예제 #6
0
    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):");
    }
예제 #7
0
    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);
    }
예제 #8
0
    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);
    }
예제 #9
0
    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);
    }
예제 #10
0
    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;
        }
    }
예제 #11
0
    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];
        }
    }
예제 #12
0
    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;
        }
    }
예제 #13
0
    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);
        }
    }