コード例 #1
0
void
_elem_frac_poly_divrem(elem_ptr Q, elem_ptr Qden,
    elem_ptr R, elem_ptr Rden,
    elem_srcptr A, elem_srcptr Aden, long lenA,
    elem_srcptr B, elem_srcptr Bden, long lenB, const ring_t ring)
{
    long lenQ = lenA - lenB + 1;
    long lenR = lenB - 1;
    long size = ring->size;
    elem_ptr den;
    elem_srcptr leadB = SRC_INDEX(B, lenB - 1, size);
    ulong d;

    /* TODO: lenB == 1 case efficiently */
    _elem_poly_pseudo_divrem(Q, R, &d, A, lenA, B, lenB, ring);

    for ( ; lenR != 0 &&
        elem_is_zero(SRC_INDEX(R, lenR - 1, size), ring); lenR--);

    /* TODO: lead^d = +/- 1 and other cases more efficiently */
    /* see also fmpq_poly_divrem, which avoids the post-canonicalisation */

    ELEM_TMP_INIT(den, ring);

    elem_pow_ui(den, leadB, d, ring);
    elem_mul(den, den, Aden, ring);
    elem_set(Rden, den, ring);

    elem_set(Qden, den, ring);

    _elem_vec_scalar_mul(Q, Q, lenQ, Bden, ring);

    ELEM_TMP_CLEAR(den, ring);
}
コード例 #2
0
ファイル: mat_solve.c プロジェクト: fredrik-johansson/bland
void
elem_mat_set_perm(elem_mat_t X, const long * perm, const elem_mat_t B, const ring_t ring)
{
    long c, i, j, m, n;
    const ring_struct * ering = RING_PARENT(ring);

    m = elem_mat_nrows(B, ring);
    n = elem_mat_ncols(B, ring);

    if (X == B)
    {
        elem_ptr tmp = _elem_vec_init(n, ering);

        for (c = 0; c < m; c++)
        {
            for (i = 0; i < n; i++)
                elem_set(INDEX(tmp, i, ering->size), elem_mat_entry(B, perm[i], c, ring), ering);
            for (i = 0; i < n; i++)
                elem_set(elem_mat_entry(X, i, c, ring), INDEX(tmp, i, ering->size), ering);
        }

        _elem_vec_clear(tmp, n, ering);
    }
    else
    {
        for (i = 0; i < m; i++)
            for (j = 0; j < n; j++)
                elem_set(elem_mat_entry(X, i, j, ring), elem_mat_entry(B, perm[i], j, ring), ering);
    }
}
コード例 #3
0
ファイル: poly_sub.c プロジェクト: fredrik-johansson/bland
void
_elem_poly_sub(elem_ptr res, elem_srcptr poly1, long len1,
    elem_srcptr poly2, long len2, const ring_t ring)
{
    long i, min;
    long size = ring->size;

    if (ring->type == TYPE_FMPZ && 0)
    {
        _fmpz_poly_sub(res, poly1, len1, poly2, len2);
        return;
    }

    min = FLINT_MIN(len1, len2);

    for (i = 0; i < min; i++)
        elem_sub(INDEX(res, i, size), SRC_INDEX(poly1, i, size), SRC_INDEX(poly2, i, size), ring);

    if (poly1 != res)
        for (i = min; i < len1; i++)
            elem_set(INDEX(res, i, size), SRC_INDEX(poly1, i, size), ring);

    for (i = min; i < len2; i++)
        elem_neg(INDEX(res, i, size), SRC_INDEX(poly2, i, size), ring);
}
コード例 #4
0
ファイル: set.c プロジェクト: fredrik-johansson/bland
void
elem_set(elem_ptr res, elem_srcptr src, const ring_t ring)
{
    if (res != src)
    {
        switch (ring->type)
        {
            case TYPE_FMPZ:
                fmpz_set(res, src);
                break;

            case TYPE_LIMB:
                *((mp_ptr) res) = *((mp_srcptr) src);
                break;

            case TYPE_MOD:
                elem_set(res, src, ring->parent);
                break;

            case TYPE_POLY:
                elem_poly_set(res, src, ring);
                break;

            case TYPE_FRAC:
                elem_set(NUMER(res, ring), NUMER(src, ring), RING_NUMER(ring));
                elem_set(DENOM(res, ring), DENOM(src, ring), RING_DENOM(ring));
                break;

            case TYPE_COMPLEX:
                elem_set(REALPART(res, ring), REALPART(src, ring), RING_PARENT(ring));
                elem_set(IMAGPART(res, ring), IMAGPART(src, ring), RING_PARENT(ring));
                break;

            default:
                NOT_IMPLEMENTED("set", ring);
        }
    }
}
コード例 #5
0
void
elem_frac_poly_divrem(elem_ptr Q, elem_ptr R, elem_srcptr A, elem_srcptr B, const ring_t ring)
{
    if (elem_is_zero(B, ring))
    {
        printf("Exception: division by zero in elem_frac_poly_divrem\n");
        abort();
    }
    else if (Q == R)
    {
        printf("Exception: output arguments Q and R may not be aliased\n");
        abort();
    }
    else if (((const elem_poly_struct *) A)->length < ((const elem_poly_struct *) B)->length)
    {
        elem_set(R, A, ring);
        elem_zero(Q, ring);
    }
    else if (Q == A || Q == B)
    {
        elem_ptr tmp;
        ELEM_TMP_INIT(tmp, ring);
        elem_frac_poly_divrem(tmp, R, A, B, ring);
        elem_swap(Q, tmp, ring);
        ELEM_TMP_CLEAR(tmp, ring);
    }
    else if (R == B)
    {
        elem_ptr tmp;
        ELEM_TMP_INIT(tmp, ring);
        elem_frac_poly_divrem(Q, tmp, A, B, ring);
        elem_swap(R, tmp, ring);
        ELEM_TMP_CLEAR(tmp, ring);
    }
    else
    {
        /* if the denominators are the same as coefficients, we can do pseudo division */
        if (RING_DENOM(ring) == RING_PARENT(RING_NUMER(ring)))
        {
            _elem_frac_poly_divrem_wrap(NUMER(Q, ring), DENOM(Q, ring),
                NUMER(R, ring), DENOM(R, ring),
                NUMER(A, ring), DENOM(A, ring),
                NUMER(B, ring), DENOM(B, ring), RING_NUMER(ring), RING_DENOM(ring));
        }
        else
        {
            NOT_IMPLEMENTED("polynomial divrem with different denominator type", ring);
        }
    }
}
コード例 #6
0
ファイル: poly_gcd.c プロジェクト: fredrik-johansson/bland
void
_elem_vec_gcd(elem_ptr res, elem_srcptr vec, long len, elem_srcptr input, const ring_t ring)
{
    long i, size = ring->size;

    if (len == 0)
    {
        elem_set(res, input, ring);
    }
    else
    {
        elem_gcd(res, vec, input, ring);

        for (i = 1; i < len && !elem_is_one(res, ring); i++)
            elem_gcd(res, res, INDEX(vec, i, size), ring);
    }
}
コード例 #7
0
static void layer_index_set(layer_index_t *layer_index, int base_value, int multiple)
{
	layer_index_t *p_layer_index=layer_index;
	elem_t *p_elem=NULL;
	int elem_value=0;
	int which_layer=0;
	if(NULL==p_layer_index){
		return;
	}

	while(NULL!=p_layer_index){
		++which_layer;
		elem_value=calc_elem_value(which_layer,base_value,multiple);
		p_elem=p_layer_index->elem;
		while(NULL!=p_elem){
			elem_set(p_elem,&elem_value,int_elem_set);
			p_elem=p_elem->next_elem;
		}
		p_layer_index=p_layer_index->next_layer;
	}
	
	return;
}
コード例 #8
0
ファイル: poly_gcd.c プロジェクト: fredrik-johansson/bland
void
_elem_poly_gcd_subresultant(elem_ptr res, elem_srcptr poly1, long len1, elem_srcptr poly2, long len2, const ring_t ring)
{
    if (len2 == 1)
    {
        _elem_vec_gcd(res, poly1, len1, poly2, ring);
    }
    else
    {
        elem_ptr a, b, d, g, h;
        elem_ptr A, B, W;
        long alloc, lenA, lenB, size = ring->size;

        alloc = len1 + len2 + 5;
        W = _elem_vec_init(alloc, ring);
        A = INDEX(W, 0, size);
        B = INDEX(A, len1, size);
        a = INDEX(B, len2, size);
        b = INDEX(a, 1, size);
        d = INDEX(b, 1, size);
        g = INDEX(d, 1, size);
        h = INDEX(g, 1, size);

        lenA = len1;
        lenB = len2;
        _elem_vec_gcd(a, poly1, lenA, a, ring);
        _elem_vec_gcd(b, poly2, lenB, b, ring);
        _elem_vec_scalar_divexact(A, poly1, lenA, a, ring);
        _elem_vec_scalar_divexact(B, poly2, lenB, b, ring);

        elem_gcd(d, a, b, ring);
        elem_one(g, ring);
        elem_one(h, ring);

        while (1)
        {
            const long delta = lenA - lenB;

            _elem_poly_pseudo_rem_cohen(A, A, lenA, B, lenB, ring);

            ELEM_VEC_NORM(A, lenA, ring);

            if (lenA <= 1)
                break;

            { /* Swap A and B */
                elem_ptr T;
                long len;
                T = A, A = B, B = T, len = lenA, lenA = lenB, lenB = len;
            }

            if (delta == 1)
            {
                elem_mul(b, g, h, ring);
                _elem_vec_scalar_divexact(B, B, lenB, b, ring);
                elem_set(g, SRC_INDEX(A, lenA - 1, size), ring);
                elem_set(h, g, ring);
            }
            else
            {
                elem_pow_ui(a, h, delta, ring);
                elem_mul(b, g, a, ring);
                _elem_vec_scalar_divexact(B, B, lenB, b, ring);
                elem_pow_ui(b, SRC_INDEX(A, lenA - 1, size), delta, ring);
                elem_mul(g, h, b, ring);
                elem_divexact(h, g, a, ring);
                elem_set(g, SRC_INDEX(A, lenA - 1, size), ring);
            }
        }

        if (lenA == 1)
        {
            elem_set(res, d, ring);
            _elem_vec_zero(INDEX(res, 1, size), len2 - 1, ring);
        }
        else
        {
            elem_zero(b, ring);
            _elem_vec_gcd(b, B, lenB, b, ring);
            _elem_vec_scalar_divexact(B, B, lenB, b, ring);

            if (elem_leading_sign(INDEX(B, lenB - 1, size), ring) < 0)
                elem_neg(d, d, ring);

            _elem_vec_scalar_mul(res, B, lenB, d, ring);

            if (len2 >= lenB)
                _elem_vec_zero(INDEX(res, lenB, size), len2 - lenB, ring);
        }

        _elem_vec_clear(W, alloc, ring);
    }
}
コード例 #9
0
ファイル: t-divexact.c プロジェクト: fredrik-johansson/bland
void
test_divexact(flint_rand_t state, const ring_t ring, const long * size, long iters)
{
    long iter;

    for (iter = 0; iter < iters; iter++)
    {
        elem_ptr A, B, C, Q;

        A = elem_new(ring);
        B = elem_new(ring);
        C = elem_new(ring);
        Q = elem_new(ring);

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_mul(C, A, B, ring);
        elem_divexact(Q, C, B, ring);
        if (!elem_equal(Q, A, ring))
        {
            printf("FAIL: (A * B) / B = A\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_randtest_not_zero(A, state, size, ring);
        elem_set(B, A, ring);
        elem_divexact(C, A, A, ring);
        elem_divexact(Q, A, B, ring);
        if (!elem_equal(C, Q, ring) || !elem_is_one(Q, ring))
        {
            printf("FAIL: aliasing A, B\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_mul(A, A, B, ring);
        elem_divexact(Q, A, B, ring);
        elem_divexact(A, A, B, ring);
        if (!elem_equal(A, Q, ring))
        {
            printf("FAIL: aliasing Q, A\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_randtest(A, state, size, ring);
        elem_randtest_not_zero(B, state, size, ring);
        elem_mul(A, A, B, ring);
        elem_divexact(Q, A, B, ring);
        elem_divexact(B, A, B, ring);
        if (!elem_equal(B, Q, ring))
        {
            printf("FAIL: aliasing Q, A\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_randtest_not_zero(B, state, size, ring);
        elem_divexact(Q, B, B, ring);
        elem_divexact(B, B, B, ring);
        if (!elem_equal(B, Q, ring))
        {
            printf("FAIL: aliasing Q, A, B\n");
            ring_print(ring); printf("\n\n");
            elem_print(A, ring); printf("\n\n");
            elem_print(B, ring); printf("\n\n");
            elem_print(C, ring); printf("\n\n");
            elem_print(Q, ring); printf("\n\n");
            abort();
        }

        elem_del(A, ring);
        elem_del(B, ring);
        elem_del(C, ring);
        elem_del(Q, ring);
    }
}