/*
Copyright (C) 2018 Daniel Schultz
This file is part of FLINT.
FLINT is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See .
*/
#include
#include
#include
#include "flint.h"
#include "fmpz.h"
#include "mpoly.h"
#include "fmpz_mpoly.h"
#include "profiler.h"
#include "ulong_extras.h"
int
main(void)
{
int i, j, k;
FLINT_TEST_INIT(state);
flint_printf("search_monomial....");
fflush(stdout);
/* get two random polys and test output of search */
for (k = 0; k < 1000*flint_test_multiplier(); k++)
{
fmpz_mpoly_ctx_t ctx;
fmpz_mpoly_t f, g;
slong len1, len2;
slong coeff_bits, exp_bits1, exp_bits2, fg_bits;
ulong * e, * fexp, * gexp, * temp;
slong e_score, * e_ind, *t1, *t2, *t3, score, x;
slong lower, upper, N;
ulong * cmpmask;
fmpz_mpoly_ctx_init_rand(ctx, state, 10);
fmpz_mpoly_init(f, ctx);
fmpz_mpoly_init(g, ctx);
len1 = n_randint(state, 100) + 1;
len2 = n_randint(state, 100) + 1;
exp_bits1 = n_randint(state, 200) + 1;
exp_bits2 = n_randint(state, 200) + 1;
coeff_bits = n_randint(state, 100) + 1;
do {
fmpz_mpoly_randtest_bits(f, state, len1, coeff_bits, exp_bits1, ctx);
fmpz_mpoly_assert_canonical(f, ctx);
} while (f->length == 0);
do {
fmpz_mpoly_randtest_bits(g, state, len2, coeff_bits, exp_bits2, ctx);
fmpz_mpoly_assert_canonical(g, ctx);
} while (g->length == 0);
fg_bits = FLINT_MAX(f->bits, g->bits);
N = mpoly_words_per_exp(fg_bits, ctx->minfo);
cmpmask = (ulong*) flint_malloc(N*sizeof(ulong));
mpoly_get_cmpmask(cmpmask, N, fg_bits, ctx->minfo);
fexp = (ulong *) flint_malloc(f->length*N*sizeof(ulong));
gexp = (ulong *) flint_malloc(g->length*N*sizeof(ulong));
e = (ulong *) flint_malloc(N*sizeof(ulong));
temp = (ulong *) flint_malloc(N*sizeof(ulong));
t1 = (slong *) flint_malloc(f->length*N*sizeof(slong));
t2 = (slong *) flint_malloc(f->length*N*sizeof(slong));
t3 = (slong *) flint_malloc(f->length*N*sizeof(slong));
mpoly_repack_monomials(fexp, fg_bits, f->exps, f->bits, f->length, ctx->minfo);
mpoly_repack_monomials(gexp, fg_bits, g->exps, g->bits, g->length, ctx->minfo);
lower = n_randint(state, f->length*g->length);
upper = n_randint(state, f->length*g->length);
if (upper < lower)
{
x = lower;
lower = upper;
upper = x;
}
mpoly_search_monomials(&e_ind, e, &e_score, t1, t2, t3, lower, upper,
fexp, f->length, gexp, g->length, N, cmpmask);
/* make sure that e_ind is correct for e */
score = 0;
for (i = 0; i < f->length; i++)
{
x = 0;
for (j = 0; j < g->length; j++)
{
mpoly_monomial_add_mp(temp, fexp + i*N, gexp + j*N, N);
if (mpoly_monomial_lt(e, temp, N, cmpmask))
{
x = j + 1;
}
}
if (x != e_ind[i])
{
flint_printf("e_ind is not right x=%wd, e_ind[%wd]=%wd\n",x,i,e_ind[i]);
flint_printf("lower = %wd upper = %wd\n",lower,upper);
fmpz_mpoly_print_pretty(f,NULL,ctx);printf("\n\n");
fmpz_mpoly_print_pretty(g,NULL,ctx);printf("\n\n");
flint_abort();
}
score += g->length - x;
}
/* make sure that e_score is correct for e */
if (score != e_score)
{
printf("e_score is not right\n");
flint_abort();
}
/* if e_score is outside of [lower,upper] check that nothing closer works */
if (e_score < lower || e_score > upper)
{
slong returned_error, new_error, i1, j1;
ulong * temp1;
temp1 = (ulong *) flint_malloc(N*sizeof(ulong));
returned_error = e_score < lower ? lower - e_score : e_score - upper;
for (i1 = 0; i1 < f->length; i1++)
{
for (j1 = 0; j1 < g->length; j1++)
{
mpoly_monomial_add_mp(temp1, fexp + i1*N, gexp + j1*N, N);
score = 0;
for (i = 0; i < f->length; i++)
{
x = 0;
for (j = 0; j < g->length; j++)
{
mpoly_monomial_add_mp(temp, fexp + i*N, gexp + j*N, N);
if (mpoly_monomial_lt(temp1, temp, N, cmpmask))
{
x = j + 1;
}
}
score += g->length - x;
}
if (!(score < lower || score > upper))
{
printf("returned score is outside, but score inside exists\n");
flint_abort();
}
new_error = score < lower ? lower - score : score - upper;
if (new_error < returned_error)
{
printf("returned score is not closest possible\n");
flint_abort();
}
}
}
flint_free(temp1);
}
flint_free(cmpmask);
flint_free(fexp);
flint_free(gexp);
flint_free(temp);
flint_free(t3);
flint_free(t2);
flint_free(t1);
flint_free(e);
fmpz_mpoly_clear(f, ctx);
fmpz_mpoly_clear(g, ctx);
}
flint_printf("PASS\n");
FLINT_TEST_CLEANUP(state);
return 0;
}