Example #1
0
    private static void gftab(ref Polynomial.PLY ply, ref List <string> output, int q_init)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    GFTAB computes and writes data for a particular field size Q_INIT.
    //
    //  Discussion:
    //
    //    A polynomial with coefficients A(*) in the field of order Q
    //    can also be stored in an integer I, with
    //
    //      I = AN*Q**N + ... + A0.
    //
    //    Polynomials stored as arrays have the
    //    coefficient of degree n in POLY(N), and the degree of the
    //    polynomial in POLY(-1).  The parameter DEG is just to remind
    //    us of this last fact.  A polynomial which is identically 0
    //    is given degree -1.
    //
    //    IRRPLY holds irreducible polynomials for constructing
    //    prime-power fields.  IRRPLY(-2,I) says which field this
    //    row is used for, and then the rest of the row is a
    //    polynomial (with the degree in IRRPLY(-1,I) as usual).
    //    The chosen irreducible poly is copied into MODPLY for use.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    06 September 2007
    //
    //  Author:
    //
    //    Paul Bratley, Bennet Fox, Harald Niederreiter.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Paul Bratley, Bennett Fox, Harald Niederreiter,
    //    Algorithm 738:
    //    Programs to Generate Niederreiter's Low-Discrepancy Sequences,
    //    ACM Transactions on Mathematical Software,
    //    Volume 20, Number 4, 1994, pages 494-495.
    //
    //  Parameters:
    //
    //    Input, ofstream &OUTPUT, a reference to the output stream.
    //
    //    Input, int Q_INIT, the order of the field for which the
    //    addition and multiplication tables are needed.
    //
    {
        int[,] gfadd  = new int [Polynomial.PLY.Q_MAX, Polynomial.PLY.Q_MAX];
        int[,] gfmul  = new int [Polynomial.PLY.Q_MAX, Polynomial.PLY.Q_MAX];
        int[,] irrply =
        {
            {  4, 2, 1, 1, 1, 0, 0, 0 },
            {  8, 3, 1, 1, 0, 1, 0, 0 },
            {  9, 2, 1, 0, 1, 0, 0, 0 },
            { 16, 4, 1, 1, 0, 0, 1, 0 },
            { 25, 2, 2, 0, 1, 0, 0, 0 },
            { 27, 3, 1, 2, 0, 1, 0, 0 },
            { 32, 5, 1, 0, 1, 0, 0, 1 },
            { 49, 2, 1, 0, 1, 0, 0, 0 }
        };
        int j;

        int[] modply = new int[Polynomial.PLY.DEG_MAX + 2];

        if (q_init is <= 1 or > Polynomial.PLY.Q_MAX)
        {
            Console.WriteLine("");
            Console.WriteLine("GFTAB - Fatal error!");
            Console.WriteLine("  Bad value of Q_INIT.");
            return;
        }

        ply.P = typeMethods.i4_characteristic(q_init);
        //
        //  If QIN is not a prime power, we are not interested.
        //
        if (ply.P == 0 || ply.P == q_init)
        {
            return;
        }

        Console.WriteLine("  GFTAB computing table for Q = " + q_init
                          + "  with characteristic P = " + ply.P + ".");
        //
        //  Otherwise, we set up the elements of the common /FIELD/
        //  ready to do arithmetic mod P, the characteristic of Q_INIT.
        //
        setfld(ref ply, q_init);
        //
        //  Next find a suitable irreducible polynomial and copy it to array MODPLY.
        //
        int i = 1;

        while (irrply[i - 1, -2 + 2] != q_init)
        {
            i += 1;
        }

        for (j = -1; j <= irrply[i - 1, -1 + 2]; j++)
        {
            modply[j + 1] = irrply[i - 1, j + 2];
        }

        for (j = irrply[i - 1, -1 + 2] + 1; j <= Polynomial.PLY.DEG_MAX; j++)
        {
            modply[j + 1] = 0;
        }

        //
        //  Deal with the trivial cases.
        //
        for (i = 0; i < q_init; i++)
        {
            gfadd[i, 0] = i;
            gfadd[0, i] = i;
            gfmul[i, 0] = 0;
            gfmul[0, i] = 0;
        }

        for (i = 1; i < q_init; i++)
        {
            gfmul[i, 1] = i;
            gfmul[1, i] = i;
        }

        //
        //  Now deal with the rest.  Each integer from 1 to Q-1
        //  is treated as a polynomial with coefficients handled mod P.
        //  Multiplication of polynomials is mod MODPLY.
        //
        int[] pl = new int[Polynomial.PLY.DEG_MAX + 2];

        for (i = 1; i < q_init; i++)
        {
            int[] pi = Polynomial.itop(i, ply.P);

            for (j = 1; j <= i; j++)
            {
                int[] pj = Polynomial.itop(j, ply.P);
                int[] pk = Polynomial.plyadd(ref ply, pi, pj);
                gfadd[i, j] = Polynomial.ptoi(pk, ply.P);
                gfadd[j, i] = gfadd[i, j];

                switch (i)
                {
                case > 1 when 1 < j:
                    pk = Polynomial.plymul(ref ply, pi, pj);
                    Polynomial.plydiv(ref ply, pk, modply, ref pj, ref pl);
                    gfmul[i, j] = Polynomial.ptoi(pl, ply.P);
                    gfmul[j, i] = gfmul[i, j];
                    break;
                }
            }
        }

        //
        //  Write out the tables.
        //
        output.Add(" " + q_init + "");

        for (i = 0; i < q_init; i++)
        {
            string cout = "";
            for (j = 0; j < q_init; j++)
            {
                cout += " " + gfadd[i, j];
            }

            output.Add(cout);
        }

        for (i = 0; i < q_init; i++)
        {
            string cout = "";
            for (j = 0; j < q_init; j++)
            {
                cout += " " + gfmul[i, j];
            }

            output.Add(cout);
        }
    }
Example #2
0
    private static void setfld(ref Polynomial.PLY ply, int q_init)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    SETFLD sets up the arithmetic tables for a finite field.
    //
    //  Discussion:
    //
    //    This subroutine sets up addition, multiplication, and
    //    subtraction tables for the finite field of order QIN.
    //
    //    A polynomial with coefficients A(*) in the field of order Q
    //    can also be stored in an integer I, with
    //
    //      I = AN*Q**N + ... + A0.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    06 September 2007
    //
    //  Author:
    //
    //    Paul Bratley, Bennet Fox, Harald Niederreiter.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Paul Bratley, Bennett Fox, Harald Niederreiter,
    //    Algorithm 738:
    //    Programs to Generate Niederreiter's Low-Discrepancy Sequences,
    //    ACM Transactions on Mathematical Software,
    //    Volume 20, Number 4, 1994, pages 494-495.
    //
    //  Parameters:
    //
    //    Input, int Q_INIT, the order of the field.
    //
    {
        int i;
        int j;

        if (q_init is <= 1 or > Polynomial.PLY.Q_MAX)
        {
            Console.WriteLine("");
            Console.WriteLine("SETFLD - Fatal error!");
            Console.WriteLine("  Bad value of Q = " + q_init + "");
            return;
        }

        ply.Q = q_init;
        ply.P = typeMethods.i4_characteristic(ply.Q);

        switch (ply.P)
        {
        case 0:
            Console.WriteLine("");
            Console.WriteLine("SETFLD - Fatal error!");
            Console.WriteLine("  There is no field of order Q = " + ply.Q + "");
            return;
        }

        //
        //  Set up to handle a field of prime or prime-power order.
        //  Calculate the addition and multiplication tables.
        //
        for (i = 0; i < ply.P; i++)
        {
            for (j = 0; j < ply.P; j++)
            {
                ply.add[i, j] = (i + j) % ply.P;
            }
        }

        for (i = 0; i < ply.P; i++)
        {
            for (j = 0; j < ply.P; j++)
            {
                ply.mul[i, j] = i * j % ply.P;
            }
        }

        //
        //  Use the addition table to set the subtraction table.
        //
        for (i = 0; i < ply.P; i++)
        {
            for (j = 0; j < ply.P; j++)
            {
                ply.sub[ply.add[i, j], i] = j;
            }
        }
    }
Example #3
0
    private static void irred(ref Polynomial.PLY ply, ref List <string> output, int q_init)

    //****************************************************************************80
    //
    //  Purpose:
    //
    //    IRRED computes and writes out a set of irreducible polynomials.
    //
    //  Discussion:
    //
    //    We find the irreducible polynomials using a sieve.
    //
    //    Polynomials stored as arrays have the coefficient of degree n in
    //    POLY(N), and the degree of the polynomial in POLY(-1).  The parameter
    //    DEG is just to remind us of this last fact.  A polynomial which is
    //    identically 0 is given degree -1.
    //
    //    Note that the value of NPOL controls the number of polynomials
    //    computed, and hence the maximum spatial dimension for the
    //    subsequence Niederreiter sequences, JVB, 07 June 2010.
    //
    //  Licensing:
    //
    //    This code is distributed under the GNU LGPL license.
    //
    //  Modified:
    //
    //    07 June 2010
    //
    //  Author:
    //
    //    Original FORTRAN77 version by Paul Bratley, Bennett Fox,
    //    Harald Niederreiter.
    //    C++ version by John Burkardt.
    //
    //  Reference:
    //
    //    Paul Bratley, Bennett Fox, Harald Niederreiter,
    //    Algorithm 738:
    //    Programs to Generate Niederreiter's Low-Discrepancy Sequences,
    //    ACM Transactions on Mathematical Software,
    //    Volume 20, Number 4, 1994, pages 494-495.
    //
    //  Parameters:
    //
    //    Input, ofstream &OUTPUT, a reference to the output stream.
    //
    //    Input, int Q_INIT, the order of the field.
    //
    //  Local Parameters:
    //
    //    Local, int SIEVE_MAX, the size of the sieve.
    //
    //    Array MONPOL holds monic polynomials.
    //
    //    Array SIEVE says whether the polynomial is still OK.
    //
    //    Local, int NPOLS, the number of irreducible polynomials to
    //    be calculated for a given field.
    //
    {
        const int SIEVE_MAX = 400;

        int[]     monpol = new int[SIEVE_MAX];
        int       n;
        const int npols = 50;

        bool[] sieve = new bool[SIEVE_MAX];

        if (q_init is <= 1 or > Polynomial.PLY.Q_MAX)
        {
            Console.WriteLine("");
            Console.WriteLine("IRRED - Fatal error!");
            Console.WriteLine("  Bad value of Q = " + q_init + "");
            return;
        }

        ply.P = typeMethods.i4_characteristic(q_init);
        switch (ply.P)
        {
        //
        //  If no field of order Q_INIT exists, there is nothing to do.
        //
        case <= 0:
            return;
        }

        Console.WriteLine("  IRRED setting up case for Q = " + q_init + "");
        //
        //  Set up the field arithmetic tables.
        //  (Note that SETFLD sets Q = q_init!)
        //
        setfld(ref ply, q_init);
        //
        //  Set up the sieve containing only monic polynomials.
        //
        int i = 0;
        int j = 1;
        int k = ply.Q;

        for (n = 1; n <= SIEVE_MAX; n++)
        {
            i += 1;

            if (i == j)
            {
                i = k;
                j = 2 * k;
                k = ply.Q * k;
            }

            monpol[n - 1] = i;
            sieve[n - 1]  = true;
        }

        //
        //  Write out the irreducible polynomials as they are found.
        //
        n = 0;
        output.Add(ply.Q.ToString(CultureInfo.InvariantCulture).PadLeft(3) + "");

        for (i = 1; i <= SIEVE_MAX; i++)
        {
            switch (sieve[i - 1])
            {
            case true:
            {
                int[] pi = Polynomial.itop(ref ply, monpol[i - 1]);
                k = pi[0];
                string cout = k.ToString(CultureInfo.InvariantCulture).PadLeft(3);
                int    l;
                for (l = 0; l <= k; l++)
                {
                    cout += pi[l + 1].ToString(CultureInfo.InvariantCulture).PadLeft(3);
                }

                output.Add(cout);
                n += 1;

                if (n == npols)
                {
                    return;
                }

                for (j = i; j <= SIEVE_MAX; j++)
                {
                    int[] pj = Polynomial.itop(ref ply, monpol[j - 1]);
                    int[] pk = Polynomial.plymul(ref ply, pi, pj);

                    k = find(Polynomial.ptoi(ref ply, pk), monpol, j, SIEVE_MAX);

                    if (k != -1)
                    {
                        sieve[k - 1] = false;
                    }
                }

                break;
            }
            }
        }

        Console.WriteLine("");
        Console.WriteLine("IRRED - Warning!");
        Console.WriteLine("  The sieve size SIEVE_MAX is too small.");
        Console.WriteLine("  Number of irreducible polynomials found: " + n + "");
        Console.WriteLine("  Number needed: " + npols + "");
    }