#include <math.h>
#include <float.h>
#include "fmpz.h"
#include "fmpz_poly.h"
#include "fmpz_mod.h"
#include "fmpz_mod_poly.h"
#include "ulong_extras.h"
#include "profiler.h"
#define lenlo 1
#define lenhi 2000
#define lenr 1.2
#define bitslo 16
#define bitshi 640
#define bitsr 1.2
#define cols (slong) (ceil(log((double)(lenhi/lenlo))/log((double)lenr)))
#define rows (slong) (ceil(log((double)(bitshi/bitslo))/log((double)bitsr)))
#define cpumin 10
#define ncases 1
#define nalgs 2
#define img 1
#define imgname "out.ppm"
int write_rgb_ppm(const char* file_name, unsigned char* pixels,
unsigned int width, unsigned int height)
{
FILE* file = fopen(file_name, "wb");
if (file == NULL)
return -1;
flint_fprintf(file, "P6\n%d %d\n255\n", width, height);
fwrite(pixels, sizeof(unsigned char), width * height * 3, file);
fclose(file);
return 0;
}
int
main(void)
{
int i, j, len, bits, maxcols, maxrows;
int X[rows][cols];
double T[rows][cols][nalgs];
fmpz_mod_poly_t f, g, h;
fmpz_t p;
fmpz_mod_ctx_t ctx;
FLINT_TEST_INIT(state);
fmpz_init(p);
fmpz_mod_ctx_init_ui(ctx, 2);
for (len = lenlo, j = 0; len <= lenhi; len = ceil((double)len*lenr), j++)
{
slong s[nalgs];
for (bits = bitslo, i = 0; bits <= bitshi; bits = ceil((double)bits*bitsr), i++)
{
int c, n, reps = 0;
for (c = 0; c < nalgs; c++)
s[c] = WORD(0);
do {
fmpz_randbits(p, state, bits);
} while (!fmpz_is_probabprime(p));
fmpz_mod_ctx_set_modulus(ctx, p);
fmpz_mod_poly_init2(f, len, ctx);
fmpz_mod_poly_init2(g, len, ctx);
fmpz_mod_poly_init2(h, len, ctx);
for (n = 0; n < ncases; n++)
{
timeit_t t[nalgs];
int l, loops = 1;
{
slong k;
for (k = 0; k < len; k++)
{
fmpz_randm(f->coeffs + k, state, p);
fmpz_randm(g->coeffs + k, state, p);
}
while ((f->coeffs)[len-1] == WORD(0))
fmpz_randm(f->coeffs + (len - 1), state, p);
while ((g->coeffs)[len-1] == WORD(0))
fmpz_randm(g->coeffs + (len - 1), state, p);
f->length = len;
g->length = len;
}
loop:
timeit_start(t[0]);
for (l = 0; l < loops; l++)
fmpz_mod_poly_gcd(h, f, g, ctx);
timeit_stop(t[0]);
timeit_start(t[1]);
for (l = 0; l < loops; l++)
fmpz_mod_poly_gcd(h, f, g, ctx);
timeit_stop(t[1]);
for (c = 0; c < nalgs; c++)
if (t[c]->cpu <= cpumin)
{
loops *= 2;
goto loop;
}
for (c = 0; c < nalgs; c++)
s[c] += t[c]->cpu;
reps += loops;
}
for (c = 0; c < nalgs; c++)
T[i][j][c] = s[c] / (double) reps;
if (s[0] <= s[1])
X[i][j] = 0;
else
X[i][j] = 1;
fmpz_mod_poly_clear(f, ctx);
fmpz_mod_poly_clear(g, ctx);
fmpz_mod_poly_clear(h, ctx);
}
{
slong sum = 0, c;
for (c = 0; c < nalgs; c++)
sum += s[c];
flint_printf("len = %d, time = %wdms\n", len, sum), fflush(stdout);
}
}
fmpz_clear(p);
fmpz_mod_ctx_clear(ctx);
maxcols = j;
maxrows = i;
for (i = 0; i < maxrows; i++)
{
for (j = 0; j < maxcols; j++)
flint_printf("%d", X[i][j]);
flint_printf("\n");
}
if (img)
{
unsigned char * PIXELS;
int k;
PIXELS = (unsigned char *) flint_malloc(3 * maxrows * maxcols * sizeof(unsigned char));
k = 0;
for (i = 0; i < maxrows; i++)
{
for (j = 0; j < maxcols; j++)
{
double max = DBL_MIN, v[nalgs];
int m;
for (m = 0; m < nalgs; m++)
{
v[m] = T[i][j][m] - T[i][j][X[i][j]];
if (v[m] > max)
max = v[m];
}
for (m = 0; m < nalgs; m++)
{
v[m] = (max - v[m]) / max;
PIXELS[k++] = (unsigned char) (v[m] * 255);
}
for (; m < 3; m++)
PIXELS[k++] = (unsigned char) 0;
}
}
k = write_rgb_ppm(imgname, PIXELS, maxcols, maxrows);
flint_free(PIXELS);
if (k)
{
flint_printf("Exception: writing ppm image failed\n");
}
}
FLINT_TEST_CLEAR(state);
return 0;
}