Esempio n. 1
0
        /*  find  value = poly(arg) where poly is a polynomial of degree d  
            and all the arithmetic takes place in the given Galois field.*/
        int polyeval(GF & gf, int d, std::vector<int> & poly, int arg, int* value)
        {
            int ans = 0;
            /* note: cannot decrement with a size type because it is always > 0.  this needs to go < 1 to stop */
            //for (size_t i = static_cast<size_t>(d); i >= 0; --i) /* Horner's rule */
            for (int i = d; i >= 0; i--) /* Horner's rule */
            {
                size_t ui = static_cast<size_t>(i);
                size_t uans = static_cast<size_t>(ans);
                size_t uarg = static_cast<size_t>(arg);
    #ifdef RANGE_DEBUG
                size_t plusRow = static_cast<size_t>(gf.times.at(uans,uarg));
                size_t plusCol = static_cast<size_t>(poly.at(ui));
                ans = gf.plus.at(plusRow, plusCol);
    #else
                //ans = gf.plus(gf.times(ans,arg),poly[i]);
                size_t plusRow = static_cast<size_t>(gf.times(uans,uarg));
                size_t plusCol = static_cast<size_t>(poly[ui]);
                ans = gf.plus(plusRow, plusCol);
    #endif
            }

            *value = ans;
            return UNCHECKED_RETURN;
        }
Esempio n. 2
0
        int bose(GF & gf, bclib::matrix<int> & A, int ncol)
        {
            size_t icol, irow;
            size_t q = static_cast<size_t>(gf.q);

            // bosecheck throws if it fails
            bosecheck(static_cast<int>(q), ncol);

            irow = 0;
            for (size_t i = 0; i < q; i++)
            {
                for (size_t j = 0; j < q; j++)
                {
                    icol = 0;
                    A(irow, icol++) = static_cast<int>(i);
                    if (ncol > 1)
                    {
                        A(irow, icol++) = static_cast<int>(j);
                    }
                    for (icol = 2; icol < static_cast<size_t>(ncol); icol++)
                    {
                        A(irow, icol) = gf.plus(j, gf.times(i, icol - 1));
                    }
                    irow++;
                }
            }

            return SUCCESS_CHECK;
        }
Esempio n. 3
0
        int bosebushl(GF & gf, int lam, bclib::matrix<int> & B, int ncol)
        /* Implement Bose and Bush's 1952 A.M.S. method with given lambda */
        {
            int p, irow;
            int mul;

            p = gf.p; /* GF(q) used to generate design with q/lam levels */
            size_t q = static_cast<size_t>(gf.q);
            size_t s = q / lam; /* number of levels in design */
            bclib::matrix<int> A(s,q);

            // bosebushlcheck throws if it fails
            bosebushlcheck(static_cast<int>(s), p, lam, ncol);

            irow = 0;
            for (size_t i = 0; i < q; i++)
            {
                for (size_t j = 0; j < q; j++)
                {
                    mul = gf.times(i,j);
                    mul = mul % s;
                    for (size_t k = 0; k < s; k++)
                    {
                        A(k,j) = gf.plus(mul,k);
                    }
                }
                for (size_t k = 0; k < s; k++)
                {
                    for (size_t j = 0; j < static_cast<size_t>(ncol) && j < lam * s + 1; j++)
                    {
                        B(irow,j) = A(k,j);
                    }
                    if (ncol == lam * static_cast<int>(s) + 1)
                    {
                        B(irow, static_cast<size_t>(ncol) - 1) = static_cast<int>(i % s);
                    }
                    irow++;
                }
            }
            return SUCCESS_CHECK;
        }
Esempio n. 4
0
        int bosebush(GF & gf, bclib::matrix<int> & B, int ncol)
        {
            int p;
            int mul;
			size_t irow;

            p = gf.p; /* GF(q) used to generate design with q/2 levels */
            size_t q = static_cast<size_t>(gf.q);
            size_t s = q / 2; /* number of levels in design */
            bclib::matrix<int> A(s, q);

            // bosebushcheck throws if it fails
            bosebushcheck(static_cast<int>(s), p, ncol);

            irow = 0;
            for (size_t i = 0; i < q; i++)
            {
                for (size_t j = 0; j < q; j++)
                {
                    mul = gf.times(i,j);
                    mul = mul % s;
                    for (size_t k = 0; k < s; k++)
                    {
                        A(k,j) = gf.plus(mul,k);
                    }
                }
                for (size_t k = 0; k < s; k++)
                {
                    for (size_t j = 0; j < static_cast<size_t>(ncol) && j < 2 * s + 1; j++)
                    {
                        B(irow,j) = A(k,j);
                    }
                    if (static_cast<size_t>(ncol) == 2 * s + 1)
                    {
                        B(irow, static_cast<size_t>(ncol) - 1) = static_cast<int>(i % s);
                    }
                    irow++;
                }
            }
            return SUCCESS_CHECK;
        }
Esempio n. 5
0
        void GF_print(GF & gf)
        {
            int n, p, q;

            n = gf.n;
            p = gf.p;
            q = gf.q;

            if (q > 999)
            {
                PRINT_OUTPUT("Warning q=%d will overflow print field.\n", q);
            }

            PRINT_OUTPUT("\nFor GF(%d) p=%d n=%d\n", q, p, n);
            PRINT_OUTPUT("x**n = (");
            for (int i = 0; i < n - 1; i++)
            {
                PRINT_OUTPUT("%d,", gf.xton[i]);
            }
            PRINT_OUTPUT("%d)\n", gf.xton[n - 1]);
            PRINT_OUTPUT("\n\nGF(%d) Polynomial coefficients:\n", q);
            for (int i = 0; i < q; i++)
            {
                PRINT_OUTPUT("  %3d  ", i);
                for (int j = 0; j < n; j++)
                {
                    PRINT_OUTPUT("%3d ", gf.poly(i,j));
                }
                PRINT_OUTPUT("\n");
            }
            PRINT_OUTPUT("\n\nGF(%d) Addition Table\n", q);
            for (int i = 0; i < q; i++)
            {
                PRINT_OUTPUT("  ");
                for (int j = 0; j < q; j++)
                {
                    PRINT_OUTPUT(" %3d", gf.plus(i,j));
                }
                PRINT_OUTPUT("\n");
            }
            PRINT_OUTPUT("\n\nGF(%d) Multiplication table\n", q);
            for (int i = 0; i < q; i++)
            {
                PRINT_OUTPUT("  ");
                for (int j = 0; j < q; j++)
                {
                    PRINT_OUTPUT(" %3d", gf.times(i,j));
                }
                PRINT_OUTPUT("\n");
            }
            PRINT_OUTPUT("\n\nGF(%d) Reciprocals\n", q);
            for (int i = 1; i < q; i++)
            {
                PRINT_OUTPUT(" %3d %3d\n", i, gf.inv[i]);
            }

            PRINT_OUTPUT("\n\nGF(%d) Negatives\n", q);
            for (int i = 0; i < q; i++)
            {
                PRINT_OUTPUT(" %3d %3d\n", i, gf.neg[i]);
            }

            PRINT_OUTPUT("\n\nGF(%d) Square roots\n", q);
            for (int i = 0; i < q; i++)
            {
                PRINT_OUTPUT(" %3d %3d\n", i, gf.root[i]);
            }
        }
Esempio n. 6
0
        /* 
           Make ready the Galois Field
         */
        int GF_ready(GF & gf, int p, int n, std::vector<int> & xton)
        {
            size_t q;
            std::ostringstream msg;

            std::vector<int> poly(n);

            gf.n = n;
            gf.p = p;
            q = 1;
            for (int i = 0; i < n; i++)
            {
                q *= p;
            }
            gf.q = q;
            gf.xton = std::vector<int>(n);
            for (size_t i = 0; i < static_cast<size_t>(n); i++)
            {
                gf.xton[i] = xton[i];
            }
            gf.plus = bclib::matrix<int>(q,q);
            gf.times = bclib::matrix<int>(q,q);
            gf.inv = std::vector<int>(q);
            gf.neg = std::vector<int>(q);
            gf.root = std::vector<int>(q);
            gf.poly = bclib::matrix<int>(q, n);

            for (size_t i = 0; i < static_cast<size_t>(n); i++)
            {
                gf.poly(0,i) = 0;
            }

            for (size_t i = 1; i < q; i++)
            {
                size_t click;
                for (click = 0; gf.poly(i - 1,click) == (p - 1); click++)
                {
                    gf.poly(i,click) = 0;
                }
                gf.poly(i,click) = gf.poly(i - 1,click) + 1;
                for (size_t j = click + 1; j < static_cast<size_t>(n); j++)
                {
                    gf.poly(i,j) = gf.poly(i - 1,j);
                }
            }

            for (size_t i = 0; i < q; i++)
            {
                for (size_t j = 0; j < q; j++)
                {
                    //GF_poly_sum(p, n, gf.poly[i], gf.poly[j], poly);
                    GF_poly_sum(p, n, gf.poly.getrow(i), gf.poly.getrow(j), poly);
                    gf.plus(i,j) = GF_poly2int(p, n, poly);
                    GF_poly_prod(p, n, xton, gf.poly.getrow(i), gf.poly.getrow(j), poly);
                    gf.times(i,j) = GF_poly2int(p, n, poly);
                }
            }

            for (size_t i = 0; i < q; i++)
            {
                gf.inv[i] = -1;
                for (size_t j = 0; j < q; j++)
                {
                    if (gf.times(i,j) == 1)
                    {
                        gf.inv[i] = j;
                    }
                }
                if (i > 0 && gf.inv[i] <= 0)
                {
                    msg << "There is something wrong with the Galois field\n";
                    msg << "used for q=" << q << ".  Element " << i << "has no reciprocal.\n";
                    throw std::runtime_error(msg.str().c_str());
                }
            }

            for (size_t i = 0; i < q; i++)
            {
                gf.neg[i] = -1;
                for (size_t j = 0; j < q; j++)
                    if (gf.plus(i,j) == 0)
                        gf.neg[i] = j;
                if (i > 0 && gf.neg[i] <= 0)
                {
                    msg << "There is something wrong with the Galois field\n";
                    msg << "used for q=" << q << ".  Element " << i << " has no negative.\n";
                    throw std::runtime_error(msg.str().c_str());
                }
            }

            for (size_t i = 0; i < q; i++)
            {
                gf.root[i] = -1;
                for (size_t j = 0; j < q; j++)
                {
                    if (gf.times(j,j) == static_cast<int>(i))
                    {
                        gf.root[i] = j;
                    }
                }
            }
            return 1;
        }
Esempio n. 7
0
        int addelkemp(GF & gf, bclib::matrix<int> & A, int ncol)
        {
            int kay; /* A&K notation */
            int square, ksquare, temp;
			size_t row, col;

            int p = gf.p;
            size_t q = gf.q;

            std::vector<int> b(q);
            std::vector<int> c(q);
            std::vector<int> k(q);

            // addelkempcheck throws if it fails
            addelkempcheck(static_cast<int>(q), p, ncol);

            for (size_t i = 0; i < q; i++)
            { /* First q*q rows */
                square = gf.times(i,i);
                for (size_t j = 0; j < q; j++)
                {
                    row = i * q + j;
                    col = 0;
                    if (col < static_cast<size_t>(ncol))
                    {
                        A(row, col++) = static_cast<int>(j);
                    }
                    for (size_t m = 1; m < q && col < static_cast<size_t>(ncol); m++)
                    {
                        A(row,col++) = gf.plus(i,gf.times(m,j));
                    }
                    for (size_t m = 0; m < q && col < static_cast<size_t>(ncol); m++)
                    {
                        temp = gf.plus(j,gf.times(m,i));
                        A(row,col++) = gf.plus(temp,square); /* Rgt cols */
                    }
                    if (col < static_cast<size_t>(ncol))
                    {
                        A(row, col++) = static_cast<int>(i);
                    }
                }
            }

            if (p != 2) /* Constants kay,b,c,k for odd p */
            {
                oaaddelkemp::akodd(gf, &kay, b, c, k);
            }
            else /* Constants kay,b,c,k for even p */
            {
                oaaddelkemp::akeven(gf, &kay, b, c, k);
            }

            for (size_t i = 0; i < q; i++)
            { /* Second q*q rows */
                square = gf.times(i,i);
                ksquare = gf.times(kay,square);
                for (size_t j = 0; j < q; j++)
                {
                    row = q * q + i * q + j;
                    col = 0;
                    if (col < static_cast<size_t>(ncol))
                    {
                        A(row, col++) = static_cast<int>(j);
                    }
                    for (size_t m = 1; m < q && col < static_cast<size_t>(ncol); m++, col++)
                    {
                        A(row,col) = gf.plus(A(row - q * q,col),b[m]);
                    }
                    if (col < static_cast<size_t>(ncol))
                    {
                        A(row,col++) = gf.plus(ksquare,j); /* q+1 */
                    }
                    for (size_t m = 1; m < q && col < static_cast<size_t>(ncol); m++)
                    {
                        temp = gf.times(i,k[m]);
                        temp = gf.plus(ksquare,temp);
                        temp = gf.plus(j,temp);
                        A(row,col++) = gf.plus(temp,c[m]);
                    }
                    if (col < static_cast<size_t>(ncol))
                    {
                        A(row, col++) = static_cast<int>(i);
                    }
                }
            }

            return SUCCESS_CHECK;
        }