Exemplo n.º 1
0
    private static void test005()

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    TEST005 tests BINOMIAL_TABLE.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    08 June 2007
    //
    //  Author:
    //
    //    John Burkardt
    //
    {
        int       i;
        int       j;
        const int m  = 10;
        const int n  = 7;
        const int qs = 7;

        Console.WriteLine("");
        Console.WriteLine("TEST005");
        Console.WriteLine("  BINOMIAL_TABLE computes a table of binomial.");
        Console.WriteLine("  coefficients mod QS.");
        Console.WriteLine("");
        Console.WriteLine("  Here, QS = " + qs + "");

        int[] coef = Coefficients.binomial_table(qs, m, n);

        Console.WriteLine("");
        string cout = "   I/J";

        for (j = 0; j <= n; j++)
        {
            cout += j.ToString(CultureInfo.InvariantCulture).PadLeft(8);
        }

        Console.WriteLine(cout);
        Console.WriteLine("");

        for (i = 0; i <= m; i++)
        {
            cout = "  " + i.ToString(CultureInfo.InvariantCulture).PadLeft(2) + "  ";
            for (j = 0; j <= n; j++)
            {
                cout += coef[i + j * (m + 1)].ToString(CultureInfo.InvariantCulture).PadLeft(8);
            }

            Console.WriteLine(cout);
        }
    }
Exemplo n.º 2
0
    public static void faure(ref FaureData data, int dim_num, ref int seed, ref double[] quasi, int quasiIndex = 0)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    FAURE generates a new quasirandom Faure vector with each call.
    //
    //  Discussion:
    //
    //    This routine implements the Faure method for computing
    //    quasirandom numbers.  It is a merging and adaptation of
    //    Bennett Fox's routines INFAUR and GOFAUR from ACM TOMS Algorithm 647.
    //
    //    Michael Baudin suggested a change so that whenever HISUM is altered,
    //    the binomial table is recomputed, which allows a user to go back or
    //    forth in the sequence.  08 December 2009.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    08 December 2009
    //
    //  Author:
    //
    //    John Burkardt
    //
    //  Reference:
    //
    //    Henri Faure,
    //    Discrepance de suites associees a un systeme de numeration
    //    (en dimension s),
    //    Acta Arithmetica,
    //    Volume 41, 1982, pages 337-351.
    //
    //    Bennett Fox,
    //    Algorithm 647:
    //    Implementation and Relative Efficiency of Quasirandom
    //    Sequence Generators,
    //    ACM Transactions on Mathematical Software,
    //    Volume 12, Number 4, December 1986, pages 362-376.
    //
    //  Parameters:
    //
    //    Input, int DIM_NUM, the spatial dimension, which should be
    //    at least 2.
    //
    //    Input/output, int *SEED, the seed, which can be used to index
    //    the values.  On first call, set the input value of SEED to be 0
    //    or negative.  The routine will automatically initialize data,
    //    and set SEED to a new value.  Thereafter, to compute successive
    //    entries of the sequence, simply call again without changing
    //    SEED.  On the first call, if SEED is negative, it will be set
    //    to a positive value that "skips over" an early part of the sequence
    //    (This is recommended for better results).
    //
    //    Output, double QUASI[DIM_NUM], the next quasirandom vector.
    //
    {
        int hisum;
        int i;
        int k;

        //
        //  Initialization required or requested?
        //
        if (data.qs <= 0 || seed <= 0)
        {
            data.qs = Prime.prime_ge(dim_num);

            switch (data.qs)
            {
            case < 1:
                Console.WriteLine("");
                Console.WriteLine("FAURE - Fatal error!");
                Console.WriteLine("  PRIME_GE failed.");
                return;

            default:
                data.hisum_save = -1;
                break;
            }
        }

        switch (seed)
        {
        //
        //  If SEED < 0, reset for recommended initial skip.
        //
        case < 0:
            hisum = 3;
            seed  = (int)Math.Pow(data.qs, hisum + 1) - 1;
            break;

        case 0:
            hisum = 0;
            break;

        default:
            hisum = (int)Math.Log(seed, data.qs);
            break;
        }

        //
        //  Is it necessary to recompute the coefficient table?
        //
        if (data.hisum_save != hisum)
        {
            data.hisum_save = hisum;

            data.coef = Coefficients.binomial_table(data.qs, hisum, hisum);

            data.ytemp = new int[hisum + 1];
        }

        //
        //  Find QUASI(1) using the method of Faure.
        //
        //  SEED has a representation in base QS of the form:
        //
        //    Sum ( 0 <= J <= HISUM ) YTEMP(J) * QS**J
        //
        //  We now compute the YTEMP(J)'s.
        //
        int ktemp = (int)Math.Pow(data.qs, hisum + 1);
        int ltemp = seed;

        for (i = hisum; 0 <= i; i--)
        {
            ktemp /= data.qs;
            int mtemp = ltemp % ktemp;
            data.ytemp[i] = (ltemp - mtemp) / ktemp;
            ltemp         = mtemp;
        }

        //
        //  QUASI(K) has the form
        //
        //    Sum ( 0 <= J <= HISUM ) YTEMP(J) / QS**(J+1)
        //
        //  Compute QUASI(1) using nested multiplication.
        //
        double r = data.ytemp[hisum];

        for (i = hisum - 1; 0 <= i; i--)
        {
            r = data.ytemp[i] + r / data.qs;
        }

        quasi[quasiIndex + 0] = r / data.qs;
        //
        //  Find components QUASI(2:DIM_NUM) using the Faure method.
        //
        for (k = 1; k < dim_num; k++)
        {
            quasi[quasiIndex + k] = 0.0;
            r = 1.0 / data.qs;

            int j;
            for (j = 0; j <= hisum; j++)
            {
                int ztemp = 0;
                for (i = j; i <= hisum; i++)
                {
                    ztemp += data.ytemp[i] * data.coef[i + j * (hisum + 1)];
                }

                //
                //  New YTEMP(J) is:
                //
                //    Sum ( J <= I <= HISUM ) ( old ytemp(i) * binom(i,j) ) mod QS.
                //
                data.ytemp[j]          = ztemp % data.qs;
                quasi[quasiIndex + k] += data.ytemp[j] * r;
                r /= data.qs;
            }
        }

        //
        //  Update SEED.
        //
        seed += 1;
    }