document and add tests for some more mag functions

This commit is contained in:
Fredrik Johansson 2014-05-19 14:11:05 +02:00
parent c939538a0a
commit 5b99998396
6 changed files with 382 additions and 20 deletions

View file

@ -51,6 +51,10 @@ Special values
Sets *x* to zero.
.. function:: void mag_one(mag_t x)
Sets *x* to one.
.. function:: void mag_inf(mag_t x)
Sets *x* to positive infinity.
@ -67,9 +71,37 @@ Special values
Returns nonzero iff *x* is positive infinity.
.. function:: int mag_is_finite(const mag_t x)
Returns nonzero iff *x* is not positive infinity (since there is no
NaN value, this function is exactly the negation of :func:`mag_is_inf`).
Comparisons
-------------------------------------------------------------------------------
.. function:: int mag_equal(const mag_t x, const mag_t y)
Returns nonzero iff *x* and *y* have the same value.
.. function:: int mag_cmp(const mag_t x, const mag_t y)
Returns negative, zero, or positive, depending on whether *x*
is smaller, equal, or larger than *y*.
.. function:: int mag_cmp_2exp_si(const mag_t x, long y)
Returns negative, zero, or positive, depending on whether *x*
is smaller, equal, or larger than `2^y`.
Arithmetic
-------------------------------------------------------------------------------
.. function:: void mag_mul_2exp_si(mag_t z, const mag_t x, long y)
.. function:: void mag_mul_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t y)
Sets `z` to `x \times 2^y`. This operation is exact.
.. function:: void mag_mul(mag_t z, const mag_t x, const mag_t y)
Sets `z` to an upper bound for `xy`.
@ -130,14 +162,21 @@ Random generation
.. function:: void mag_randtest(mag_t x, flint_rand_t state, long expbits)
Sets *x* to a random value, with an exponent up to *expbits* bits large.
The special values zero and infinity are occasionally generated.
Sets *x* to a random finite value, with an exponent up to *expbits* bits large.
.. function:: void mag_randtest_special(mag_t x, flint_rand_t state, long expbits)
Like :func:`mag_randtest`, but also sometimes sets *x* to
infinity.
Conversions
-------------------------------------------------------------------------------
These functions are intended for debugging purposes: see the :doc:`arf <arf>`
module for other conversion functions.
.. function:: void mag_set_d_2exp_fmpz(mag_t z, double x, const fmpz_t y)
.. function:: void mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t x, const fmpz_t y)
Sets *z* to an upper bound for `x \times 2^y`.
.. function:: void mag_set_fmpr(mag_t y, const fmpr_t x)
@ -145,5 +184,9 @@ module for other conversion functions.
.. function:: void mag_get_fmpr(fmpr_t y, const mag_t x)
Sets *y* to exactly *x*.
Sets *y* exactly to *x*.
.. function:: void mag_get_fmpq(fmpq_t y, const mag_t x)
Sets *y* exactly to *x*. Assumes that no overflow occurs.

20
mag.h
View file

@ -236,7 +236,6 @@ mag_zero(mag_t x)
MAG_MAN(x) = 0;
}
/* TODO: document */
static __inline__ void
mag_one(mag_t x)
{
@ -270,14 +269,12 @@ mag_is_inf(const mag_t x)
return (MAG_MAN(x) == 0) && (MAG_EXP(x) != 0);
}
/* TODO: document */
static __inline__ int
mag_is_finite(const mag_t x)
{
return !mag_is_inf(x);
}
/* TODO: document */
static __inline__ int
mag_equal(const mag_t x, const mag_t y)
{
@ -297,8 +294,6 @@ void mag_add(mag_t z, const mag_t x, const mag_t y);
void mag_div(mag_t z, const mag_t x, const mag_t y);
/* TODO: document */
/* TODO: avoid fmpz_add_si_inline */
static __inline__ void
mag_mul_2exp_si(mag_t z, const mag_t x, long y)
{
@ -308,13 +303,14 @@ mag_mul_2exp_si(mag_t z, const mag_t x, long y)
}
else
{
fmpz_add_si_inline(MAG_EXPREF(z), MAG_EXPREF(x), y);
if (y >= ADD2_FAST_MIN && y <= ADD2_FAST_MAX)
_fmpz_add_fast(MAG_EXPREF(z), MAG_EXPREF(x), y);
else
fmpz_add_si(MAG_EXPREF(z), MAG_EXPREF(x), y);
MAG_MAN(z) = MAG_MAN(x);
}
}
/* TODO: document */
/* TODO: avoid fmpz_add_inline */
static __inline__ void
mag_mul_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t y)
{
@ -324,7 +320,7 @@ mag_mul_2exp_fmpz(mag_t z, const mag_t x, const fmpz_t y)
}
else
{
fmpz_add_inline(MAG_EXPREF(z), MAG_EXPREF(x), y);
_fmpz_add2_fast(MAG_EXPREF(z), MAG_EXPREF(x), y, 0);
MAG_MAN(z) = MAG_MAN(x);
}
}
@ -449,7 +445,6 @@ mag_fast_add_2exp_si(mag_t z, const mag_t x, long e)
}
}
/* TODO: document */
void mag_set_d_2exp_fmpz(mag_t z, double c, const fmpz_t exp);
void mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t man, const fmpz_t exp);
@ -475,7 +470,6 @@ mag_get_fmpr(fmpr_t x, const mag_t r)
}
}
/* TODO: document */
static __inline__ void
mag_randtest_special(mag_t x, flint_rand_t state, long expbits)
{
@ -502,7 +496,6 @@ mag_randtest_special(mag_t x, flint_rand_t state, long expbits)
}
}
/* TODO: update documentation */
static __inline__ void
mag_randtest(mag_t x, flint_rand_t state, long expbits)
{
@ -537,7 +530,6 @@ mag_printd(const mag_t x, long d)
fmpr_clear(t);
}
/* TODO: document */
static __inline__ void
mag_get_fmpq(fmpq_t y, const mag_t x)
{
@ -548,7 +540,6 @@ mag_get_fmpq(fmpq_t y, const mag_t x)
fmpr_clear(t);
}
/* TODO: document/test */
static __inline__ int
mag_cmp(const mag_t x, const mag_t y)
{
@ -573,7 +564,6 @@ mag_cmp(const mag_t x, const mag_t y)
return (c < 0) ? -1 : 1;
}
/* TODO: document/test */
static __inline__ int
mag_cmp_2exp_si(const mag_t x, long e)
{

81
mag/test/t-cmp.c Normal file
View file

@ -0,0 +1,81 @@
/*=============================================================================
This file is part of ARB.
ARB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ARB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ARB; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2014 Fredrik Johansson
******************************************************************************/
#include "mag.h"
int main()
{
long iter;
flint_rand_t state;
printf("cmp....");
fflush(stdout);
flint_randinit(state);
for (iter = 0; iter < 100000; iter++)
{
fmpr_t x, y;
mag_t xb, yb;
int c1, c2;
fmpr_init(x);
fmpr_init(y);
mag_init(xb);
mag_init(yb);
mag_randtest_special(xb, state, 100);
mag_randtest_special(yb, state, 100);
mag_get_fmpr(x, xb);
mag_get_fmpr(y, yb);
c1 = fmpr_cmp(x, y);
c2 = mag_cmp(xb, yb);
if (c1 != c2)
{
printf("FAIL\n\n");
printf("x = "); fmpr_print(x); printf("\n\n");
printf("y = "); fmpr_print(y); printf("\n\n");
printf("xb = "); mag_print(xb); printf("\n\n");
printf("yb = "); mag_print(yb); printf("\n\n");
abort();
}
fmpr_clear(x);
fmpr_clear(y);
mag_clear(xb);
mag_clear(yb);
}
flint_randclear(state);
flint_cleanup();
printf("PASS\n");
return EXIT_SUCCESS;
}

75
mag/test/t-cmp_2exp_si.c Normal file
View file

@ -0,0 +1,75 @@
/*=============================================================================
This file is part of ARB.
ARB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ARB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ARB; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2014 Fredrik Johansson
******************************************************************************/
#include "mag.h"
#include "long_extras.h"
int main()
{
long iter;
flint_rand_t state;
printf("cmp....");
fflush(stdout);
flint_randinit(state);
for (iter = 0; iter < 100000; iter++)
{
fmpr_t x;
mag_t xb;
long y;
int c1, c2;
fmpr_init(x);
mag_init(xb);
mag_randtest_special(xb, state, 100);
y = z_randtest(state);
mag_get_fmpr(x, xb);
c1 = fmpr_cmp_2exp_si(x, y);
c2 = mag_cmp_2exp_si(xb, y);
if (c1 != c2)
{
printf("FAIL\n\n");
printf("x = "); fmpr_print(x); printf("\n\n");
printf("y = %ld", y); printf("\n\n");
printf("xb = "); mag_print(xb); printf("\n\n");
abort();
}
fmpr_clear(x);
mag_clear(xb);
}
flint_randclear(state);
flint_cleanup();
printf("PASS\n");
return EXIT_SUCCESS;
}

View file

@ -0,0 +1,88 @@
/*=============================================================================
This file is part of ARB.
ARB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ARB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ARB; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2014 Fredrik Johansson
******************************************************************************/
#include "mag.h"
int main()
{
long iter;
flint_rand_t state;
printf("mul_2exp_fmpz....");
fflush(stdout);
flint_randinit(state);
for (iter = 0; iter < 100000; iter++)
{
fmpr_t x, y, z;
mag_t xb, yb;
fmpz_t e;
fmpr_init(x);
fmpr_init(y);
fmpr_init(z);
fmpz_init(e);
mag_init(xb);
mag_init(yb);
mag_randtest_special(xb, state, 100);
fmpz_randtest(e, state, 100);
mag_get_fmpr(x, xb);
mag_mul_2exp_fmpz(yb, xb, e);
fmpr_mul_2exp_fmpz(y, x, e);
mag_get_fmpr(z, yb);
MAG_CHECK_BITS(yb)
if (!fmpr_equal(z, y))
{
printf("FAIL\n\n");
printf("x = "); fmpr_printd(x, 15); printf("\n\n");
printf("y = "); fmpr_printd(y, 15); printf("\n\n");
printf("z = "); fmpr_printd(z, 15); printf("\n\n");
abort();
}
fmpr_clear(x);
fmpr_clear(y);
fmpr_clear(z);
mag_clear(xb);
mag_clear(yb);
fmpz_clear(e);
}
flint_randclear(state);
flint_cleanup();
printf("PASS\n");
return EXIT_SUCCESS;
}

85
mag/test/t-mul_2exp_si.c Normal file
View file

@ -0,0 +1,85 @@
/*=============================================================================
This file is part of ARB.
ARB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ARB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ARB; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2014 Fredrik Johansson
******************************************************************************/
#include "mag.h"
#include "long_extras.h"
int main()
{
long iter;
flint_rand_t state;
printf("mul_2exp_si....");
fflush(stdout);
flint_randinit(state);
for (iter = 0; iter < 100000; iter++)
{
fmpr_t x, y, z;
mag_t xb, yb;
long e;
fmpr_init(x);
fmpr_init(y);
fmpr_init(z);
mag_init(xb);
mag_init(yb);
mag_randtest_special(xb, state, 100);
e = z_randtest(state);
mag_get_fmpr(x, xb);
mag_mul_2exp_si(yb, xb, e);
fmpr_mul_2exp_si(y, x, e);
mag_get_fmpr(z, yb);
MAG_CHECK_BITS(yb)
if (!fmpr_equal(z, y))
{
printf("FAIL\n\n");
printf("x = "); fmpr_printd(x, 15); printf("\n\n");
printf("y = "); fmpr_printd(y, 15); printf("\n\n");
printf("z = "); fmpr_printd(z, 15); printf("\n\n");
abort();
}
fmpr_clear(x);
fmpr_clear(y);
fmpr_clear(z);
mag_clear(xb);
mag_clear(yb);
}
flint_randclear(state);
flint_cleanup();
printf("PASS\n");
return EXIT_SUCCESS;
}