Esempio n. 1
0
void inv(ZZ& d_out, mat_ZZ& x_out, const mat_ZZ& A, long deterministic)
{
    long n = A.NumRows();

    if (A.NumCols() != n)
        Error("solve: nonsquare matrix");

    if (n == 0) {
        set(d_out);
        x_out.SetDims(0, 0);
        return;
    }

    zz_pBak zbak;
    zbak.save();

    ZZ_pBak Zbak;
    Zbak.save();

    mat_ZZ x(INIT_SIZE, n, n);
    ZZ d, d1;

    ZZ d_prod, x_prod;
    set(d_prod);
    set(x_prod);

    long d_instable = 1;
    long x_instable = 1;

    long gp_cnt = 0;

    long check = 0;


    mat_ZZ y;

    long i;
    long bound = 2+DetBound(A);

    for (i = 0; ; i++) {
        if ((check || IsZero(d)) && !d_instable) {
            if (NumBits(d_prod) > bound) {
                break;
            }
            else if (!deterministic &&
                     bound > 1000 && NumBits(d_prod) < 0.25*bound) {

                ZZ P;

                long plen = 90 + NumBits(max(bound, NumBits(d)));
                GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++));

                ZZ_p::init(P);

                mat_ZZ_p AA;
                conv(AA, A);

                ZZ_p dd;
                determinant(dd, AA);

                if (CRT(d, d_prod, rep(dd), P))
                    d_instable = 1;
                else
                    break;
            }
        }


        zz_p::FFTInit(i);
        long p = zz_p::modulus();

        mat_zz_p AA;
        conv(AA, A);

        if (!check) {
            mat_zz_p xx;

            zz_p dd;

            inv(dd, xx, AA);

            d_instable = CRT(d, d_prod, rep(dd), p);
            if (!IsZero(dd)) {
                mul(xx, xx, dd);
                x_instable = CRT(x, x_prod, xx);
            }
            else
                x_instable = 1;

            if (!d_instable && !x_instable) {
                mul(y, x, A);
                if (IsDiag(y, n, d)) {
                    d1 = d;
                    check = 1;
                }
            }
        }
        else {
            zz_p dd;
            determinant(dd, AA);
            d_instable = CRT(d, d_prod, rep(dd), p);
        }
    }

    if (check && d1 != d) {
        mul(x, x, d);
        ExactDiv(x, d1);
    }

    d_out = d;
    if (check) x_out = x;

    zbak.restore();
    Zbak.restore();
}
Esempio n. 2
0
void determinant(ZZ& rres, const mat_ZZ& a, long deterministic)
{
    long n = a.NumRows();
    if (a.NumCols() != n)
        Error("determinant: nonsquare matrix");

    if (n == 0) {
        set(rres);
        return;
    }

    zz_pBak zbak;
    zbak.save();

    ZZ_pBak Zbak;
    Zbak.save();

    long instable = 1;

    long gp_cnt = 0;

    long bound = 2+DetBound(a);

    ZZ res, prod;

    clear(res);
    set(prod);


    long i;
    for (i = 0; ; i++) {
        if (NumBits(prod) > bound)
            break;

        if (!deterministic &&
                !instable && bound > 1000 && NumBits(prod) < 0.25*bound) {
            ZZ P;


            long plen = 90 + NumBits(max(bound, NumBits(res)));
            GenPrime(P, plen, 90 + 2*NumBits(gp_cnt++));

            ZZ_p::init(P);

            mat_ZZ_p A;
            conv(A, a);

            ZZ_p t;
            determinant(t, A);

            if (CRT(res, prod, rep(t), P))
                instable = 1;
            else
                break;
        }


        zz_p::FFTInit(i);
        long p = zz_p::modulus();

        mat_zz_p A;
        conv(A, a);

        zz_p t;
        determinant(t, A);

        instable = CRT(res, prod, rep(t), p);
    }

    rres = res;

    zbak.restore();
    Zbak.restore();
}