#include <string.h>
#include <math.h>
#include "gmpcompat.h"
#include "fmpz.h"
#include "fmpq_poly.h"
char * fmpq_poly_get_str(const fmpq_poly_t poly)
{
slong i;
size_t j;
size_t len;
size_t denlen;
mpz_t z;
mpq_t q;
char * str;
if (poly->length == 0)
{
str = (char *) flint_malloc(2 * sizeof(char));
str[0] = '0';
str[1] = '\0';
return str;
}
mpz_init(z);
if (*poly->den == WORD(1))
{
denlen = 0;
}
else
{
fmpz_get_mpz(z, poly->den);
denlen = mpz_sizeinbase(z, 10);
}
len = (size_t) ceil(log10((double) (poly->length + 1))) + (size_t) 2;
for (i = 0; i < poly->length; i++)
{
fmpz_get_mpz(z, poly->coeffs + i);
len += mpz_sizeinbase(z, 10) + (size_t) 1;
if (mpz_sgn(z))
len += denlen + (size_t) 2;
}
mpq_init(q);
str = (char *) flint_malloc(len * sizeof(char));
j = flint_sprintf(str, "%wd", poly->length);
str[j++] = ' ';
for (i = 0; i < poly->length; i++)
{
str[j++] = ' ';
fmpz_get_mpz(mpq_numref(q), poly->coeffs + i);
fmpz_get_mpz(mpq_denref(q), poly->den);
mpq_canonicalize(q);
mpq_get_str(str + j, 10, q);
j += strlen(str + j);
}
mpq_clear(q);
mpz_clear(z);
return str;
}
char * _fmpq_poly_get_str_pretty(const fmpz *poly, const fmpz_t den, slong len,
const char *var)
{
slong i;
size_t j;
size_t size;
size_t densize;
size_t varsize;
mpz_t z;
mpq_t q;
char *str;
if (len == 0)
{
str = flint_malloc(2);
str[0] = '0';
str[1] = '\0';
return str;
}
if (len == 1)
{
mpq_init(q);
fmpz_get_mpz(mpq_numref(q), poly);
fmpz_get_mpz(mpq_denref(q), den);
mpq_canonicalize(q);
str = flint_malloc(mpz_sizeinbase (mpq_numref(q), 10) +
mpz_sizeinbase (mpq_denref(q), 10) + 3);
str = mpq_get_str(str, 10, q);
mpq_clear(q);
return str;
}
if (len == 2)
{
mpq_t a0, a1;
size_t size0, size1;
mpq_init(a0);
mpq_init(a1);
fmpz_get_mpz(mpq_numref(a0), poly);
fmpz_get_mpz(mpq_denref(a0), den);
mpq_canonicalize(a0);
fmpz_get_mpz(mpq_numref(a1), poly + 1);
fmpz_get_mpz(mpq_denref(a1), den);
mpq_canonicalize(a1);
size0 = mpz_sizeinbase(mpq_numref(a0), 10)
+ mpz_sizeinbase(mpq_denref(a0), 10) + 2;
size1 = mpz_sizeinbase(mpq_numref(a1), 10)
+ mpz_sizeinbase(mpq_denref(a1), 10) + 2;
size = size0 + 1 + strlen(var) + 1 + size1 + 1;
str = flint_malloc(size);
if (flint_mpq_cmp_si(a1, 1, 1) == 0)
{
if (mpq_sgn(a0) == 0)
gmp_sprintf(str, "%s", var);
else if (mpq_sgn(a0) > 0)
gmp_sprintf(str, "%s+%Qd", var, a0);
else
gmp_sprintf(str, "%s%Qd", var, a0);
}
else if (flint_mpq_cmp_si(a1, -1, 1) == 0)
{
if (mpq_sgn(a0) == 0)
gmp_sprintf(str, "-%s", var);
else if (mpq_sgn(a0) > 0)
gmp_sprintf(str, "-%s+%Qd", var, a0);
else
gmp_sprintf(str, "-%s%Qd", var, a0);
}
else
{
if (mpq_sgn(a0) == 0)
gmp_sprintf(str, "%Qd*%s", a1, var);
else if (mpq_sgn(a0) > 0)
gmp_sprintf(str, "%Qd*%s+%Qd", a1, var, a0);
else
gmp_sprintf(str, "%Qd*%s%Qd", a1, var, a0);
}
mpq_clear(a0);
mpq_clear(a1);
return str;
}
varsize = strlen(var);
mpz_init(z);
if (*den == WORD(1))
{
densize = 0;
}
else
{
fmpz_get_mpz(z, den);
densize = mpz_sizeinbase(z, 10);
}
size = 0;
for (i = 0; i < len; i++)
{
fmpz_get_mpz(z, poly + i);
size += mpz_sizeinbase(z, 10) + 1;
if (mpz_sgn(z) != 0) size += 1 + densize;
size += 3;
size += 1 + varsize + 1;
size += (size_t) ceil(log10((double) (i + 1)));
}
mpq_init(q);
str = flint_malloc(size);
j = 0;
fmpz_get_mpz(mpq_numref(q), poly + (len - 1));
fmpz_get_mpz(mpq_denref(q), den);
mpq_canonicalize(q);
if (flint_mpq_cmp_si(q, 1, 1) != 0)
{
if (flint_mpq_cmp_si(q, -1, 1) == 0)
str[j++] = '-';
else
{
mpq_get_str(str, 10, q);
j += strlen(str + j);
str[j++] = '*';
}
}
j += flint_sprintf(str + j, "%s", var);
str[j++] = '^';
j += flint_sprintf(str + j, "%wd", len - 1);
i = len - 1;
while (i)
{
i--;
if (fmpz_is_zero(poly + i))
continue;
fmpz_get_mpz(mpq_numref(q), poly + i);
fmpz_get_mpz(mpq_denref(q), den);
mpq_canonicalize(q);
str[j++] = ' ';
if (mpq_sgn(q) < 0)
{
mpq_abs(q, q);
str[j++] = '-';
}
else
str[j++] = '+';
str[j++] = ' ';
mpq_get_str(str + j, 10, q);
j += strlen(str + j);
if (i > 0)
{
str[j++] = '*';
j += flint_sprintf(str + j, "%s", var);
if (i > 1)
{
str[j++] = '^';
j += flint_sprintf(str + j, "%wd", i);
}
}
}
mpq_clear(q);
mpz_clear(z);
return str;
}
char * fmpq_poly_get_str_pretty(const fmpq_poly_t poly, const char * var)
{
return _fmpq_poly_get_str_pretty(poly->coeffs, poly->den, poly->length,
var);
}