89 changes: 89 additions & 0 deletions arb/add.c
@@ -0,0 +1,89 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_add(arb_t c, const arb_t a, const arb_t b)
{
fmpz e, f;

e = *arb_expref(a);
f = *arb_expref(b);

/* both exponents equal and small (e.g. small integer case) */
if (e == f)
{
/* add midpoints */
fmpz_add(arb_midref(c), arb_midref(a), arb_midref(b));

/* add errors */
if (fmpz_is_zero(arb_radref(a)) && fmpz_is_zero(arb_radref(b)))
fmpz_zero(arb_radref(c));
else
fmpz_add(arb_radref(c), arb_radref(a), arb_radref(b));

/* set exponent */
_fmpz_set_si_small(arb_expref(c), e);
}
/* both exponents are small */
else if (!COEFF_IS_MPZ(e) && !COEFF_IS_MPZ(f))
{
fmpz_t t;
fmpz_init(t);

/* TODO: be smart when one argument (or both) has rad = 0 */

if (e >= f)
{
fmpz_tdiv_q_2exp(t, arb_midref(b), e - f);
fmpz_add(arb_midref(c), arb_midref(a), t);

fmpz_cdiv_q_2exp(t, arb_radref(b), e - f);
fmpz_add(arb_radref(c), arb_radref(a), t);
fmpz_add_ui(arb_radref(c), arb_radref(c), 1UL);

_fmpz_set_si_small(arb_expref(c), e);
}
else
{
fmpz_tdiv_q_2exp(t, arb_midref(a), f - e);
fmpz_add(arb_midref(c), arb_midref(b), t);

fmpz_cdiv_q_2exp(t, arb_radref(a), f - e);
fmpz_add(arb_radref(c), arb_radref(b), t);
fmpz_add_ui(arb_radref(c), arb_radref(c), 1UL);

_fmpz_set_si_small(arb_expref(c), f);
}

fmpz_clear(t);
}
else
{
/* not implemented */
abort();
}
}
54 changes: 54 additions & 0 deletions arb/add_error_2exp.c
@@ -0,0 +1,54 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

/* todo: improve */
void
arb_add_error_2exp(arb_t x, long c)
{
long e;

if (COEFF_IS_MPZ(*arb_expref(x)))
{
printf("arb_add_error_2exp: large exponent");
abort();
}

e = fmpz_get_si(arb_expref(x));

if (c < e)
{
fmpz_add_ui(arb_radref(x), arb_radref(x), 1);
}
else
{
fmpz_t t;
fmpz_init_set_ui(t, 1);
fmpz_mul_2exp(t, t, c - e);
fmpz_add(arb_radref(x), arb_radref(x), t);
fmpz_clear(t);
}
}
86 changes: 86 additions & 0 deletions arb/addmul.c
@@ -0,0 +1,86 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_addmul(arb_t c, const arb_t a, const arb_t b)
{
if (fmpz_is_zero(arb_expref(c)) && fmpz_is_zero(arb_expref(a))
&& fmpz_is_zero(arb_expref(b)))
{
/* multiply errors */
if (fmpz_is_zero(arb_radref(a)))
{
if (!fmpz_is_zero(arb_radref(b)))
{
/* (c+e) + a * (b+r) = c + a*b + (e+a*r) */
_fmpz_addmul_abs(arb_radref(c), arb_midref(a), arb_radref(b));
}
}
else
{
if (fmpz_is_zero(arb_radref(b)))
{
/* (c+e) + (a+r) * b = c + a*b + (e+b*r) */
_fmpz_addmul_abs(arb_radref(c), arb_midref(b), arb_radref(a));
}
else
{
/* (a + r) * (b + s) = a*b + a*s + b*r + r*s */
if (c != a && c != b)
{
/* no aliasing */
_fmpz_addmul_abs(arb_radref(c), arb_radref(a), arb_radref(b));
_fmpz_addmul_abs(arb_radref(c), arb_midref(a), arb_radref(b));
_fmpz_addmul_abs(arb_radref(c), arb_midref(b), arb_radref(a));
}
else
{
fmpz_t t;
fmpz_init(t);
fmpz_mul(t, arb_radref(a), arb_radref(b));
_fmpz_addmul_abs(t, arb_midref(a), arb_radref(b));
_fmpz_addmul_abs(t, arb_midref(b), arb_radref(a));
fmpz_add(arb_radref(c), arb_radref(c), t);
fmpz_clear(t);
}
}
}

/* multiply midpoints */
fmpz_addmul(arb_midref(c), arb_midref(a), arb_midref(b));

_arb_normalise(c);
}
else
{
arb_t t;
arb_init(t, arb_prec(c));
arb_mul(t, a, b);
arb_add(c, c, t);
arb_clear(t);
}
}
34 changes: 34 additions & 0 deletions arb/clear.c
@@ -0,0 +1,34 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_clear(arb_t x)
{
fmpz_clear(&x->mid);
fmpz_clear(&x->exp);
fmpz_clear(&x->rad);
}
237 changes: 237 additions & 0 deletions arb/const_euler_brent_mcmillan.c
@@ -0,0 +1,237 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

typedef struct
{
arb_t P;
arb_t Q;
arb_t T;
arb_t C;
arb_t D;
arb_t V;
} euler_bsplit_struct;

typedef euler_bsplit_struct euler_bsplit_t[1];

static void euler_bsplit_init(euler_bsplit_t s, long wp)
{
arb_init(s->P, wp);
arb_init(s->Q, wp);
arb_init(s->T, wp);
arb_init(s->C, wp);
arb_init(s->D, wp);
arb_init(s->V, wp);
}

static void euler_bsplit_clear(euler_bsplit_t s)
{
arb_clear(s->P);
arb_clear(s->Q);
arb_clear(s->T);
arb_clear(s->C);
arb_clear(s->D);
arb_clear(s->V);
}

static void
euler_bsplit_1_merge(euler_bsplit_t s, euler_bsplit_t L, euler_bsplit_t R,
long wp, int cont)
{
arb_t t, u, v;

arb_init(t, wp);
arb_init(u, wp);
arb_init(v, wp);

if (cont)
arb_mul(s->P, L->P, R->P);

arb_mul(s->Q, L->Q, R->Q);
arb_mul(s->D, L->D, R->D);

/* T = LP RT + RQ LT*/
arb_mul(t, L->P, R->T);
arb_mul(v, R->Q, L->T);
arb_add(s->T, t, v);

/* C = LC RD + RC LD */
if (cont)
{
arb_mul(s->C, L->C, R->D);
arb_addmul(s->C, R->C, L->D);
}

/* V = RD (RQ LV + LC LP RT) + LD LP RV */
arb_mul(u, L->P, R->V);
arb_mul(u, u, L->D);
arb_mul(v, R->Q, L->V);
arb_addmul(v, t, L->C);
arb_mul(v, v, R->D);
arb_add(s->V, u, v);

arb_clear(t);
arb_clear(u);
arb_clear(v);
}

void
euler_bsplit_1(euler_bsplit_t s, long n1, long n2, long N, long wp, int cont)
{
if (n2 - n1 == 1)
{
arb_set_si(s->P, N); /* p = N^2 todo: shift optimization */
arb_mul(s->P, s->P, s->P);
arb_set_si(s->Q, n1 + 1); /* q = (k + 1)^2 */
arb_mul(s->Q, s->Q, s->Q);
arb_set_si(s->C, 1);
arb_set_si(s->D, n1 + 1);
arb_set(s->T, s->P);
arb_set(s->V, s->P);
}
else
{
euler_bsplit_t L, R;
long m = (n1 + n2) / 2;

euler_bsplit_init(L, wp);
euler_bsplit_init(R, wp);
euler_bsplit_1(L, n1, m, N, wp, 1);
euler_bsplit_1(R, m, n2, N, wp, 1);
euler_bsplit_1_merge(s, L, R, wp, cont);
euler_bsplit_clear(L);
euler_bsplit_clear(R);
}
}

void
euler_bsplit_2(arb_t P, arb_t Q, arb_t T, long n1, long n2,
long N, long wp, int cont)
{
if (n2 - n1 == 1)
{
if (n1 == 0)
{
arb_set_si(P, 1);
arb_set_si(Q, 4 * N);
arb_set_si(T, 1);
}
else
{
arb_zero(P);
fmpz_set_si(arb_midref(P), 1 - 2*n1);
fmpz_pow_ui(arb_midref(P), arb_midref(P), 3);
fmpz_neg(arb_midref(P), arb_midref(P));
arb_zero(Q);
fmpz_set_si(arb_midref(Q), 32 * n1);
fmpz_mul_ui(arb_midref(Q), arb_midref(Q), N);
fmpz_mul_ui(arb_midref(Q), arb_midref(Q), N);
}

arb_set(T, P);
}
else
{
arb_t P2, Q2, T2;
long m = (n1 + n2) / 2;

arb_init(P2, wp);
arb_init(Q2, wp);
arb_init(T2, wp);

euler_bsplit_2(P, Q, T, n1, m, N, wp, 1);
euler_bsplit_2(P2, Q2, T2, m, n2, N, wp, 1);

arb_mul(T, T, Q2);
arb_mul(T2, T2, P);
arb_add(T, T, T2);

if (cont)
arb_mul(P, P, P2);

arb_mul(Q, Q, Q2);

arb_clear(P2);
arb_clear(Q2);
arb_clear(T2);
}
}

void
arb_const_euler_brent_mcmillan(arb_t res)
{
euler_bsplit_t sum;
arb_t t, u, v, P2, T2, Q2;
long bits, wp, n, nterms1, nterms2;

bits = arb_prec(res) + 20;
n = 0.08665 * bits + 1;

nterms1 = 4.9706258 * n + 1;
nterms2 = 2 * n + 1;
wp = bits + FLINT_BIT_COUNT(n);

euler_bsplit_init(sum, wp);
arb_init(P2, wp);
arb_init(T2, wp);
arb_init(Q2, wp);
arb_init(t, wp);
arb_init(u, wp);
arb_init(v, wp);

/* Compute S0 = V / (Q * D), I0 = 1 + T / Q */
euler_bsplit_1(sum, 0, nterms1, n, wp, 0);

/* Compute K0 = T2 / Q2 */
euler_bsplit_2(P2, Q2, T2, 0, nterms2, n, wp, 0);

/* Compute (S0/I0 + K0/I0^2) = (Q2*(Q+T)*V - D*Q^2*T2)/(D*Q2*(Q+T)^2) */
arb_add(v, sum->Q, sum->T);
arb_mul(t, v, Q2);
arb_mul(u, sum->Q, sum->Q);
arb_mul(u, u, T2);
arb_mul(u, u, sum->D);
arb_mul(sum->V, t, sum->V);
arb_sub(sum->V, sum->V, u);
arb_mul(u, sum->D, t);
arb_mul(u, u, v);
arb_div(t, sum->V, u);

/* subtract log(n) */
arb_log_ui(u, n);
arb_sub(res, t, u);

/* TODO: add error term */

arb_clear(P2);
arb_clear(T2);
arb_clear(Q2);
arb_clear(t);
arb_clear(u);
arb_clear(v);

euler_bsplit_clear(sum);
}
114 changes: 114 additions & 0 deletions arb/const_pi_chudnovsky.c
@@ -0,0 +1,114 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

#define CONST_A 13591409UL
#define CONST_B 545140134UL
#define CONST_C 640320UL
#define CONST_D 12UL
#define BITS_PER_TERM 47.1104131382158 /* log2(640320^3 / (2^6 * 3^3)) */

void
chudnovsky_bsplit(arb_t G, arb_t P, arb_t Q, long a, long b, long wp, int cont)
{
if (b - a == 1)
{
/* g = (6*b-5)*(2*b-1)*(6*b-1) */
arb_set_si(G, 6*b - 5);
fmpz_mul_si(arb_midref(G), arb_midref(G), 2*b-1);
fmpz_mul_si(arb_midref(G), arb_midref(G), 6*b-1);

/* p = C^3 * b^3 / 24 */
arb_set_si(P, CONST_C * CONST_C * CONST_C / 24); /* xxx: fix for 32-bit */
fmpz_mul_ui(arb_midref(P), arb_midref(P), b);
fmpz_mul2_uiui(arb_midref(P), arb_midref(P), b, b);

/* (-1)^b * g * (A + B*b) */
arb_set_si(Q, CONST_A);
fmpz_addmul_ui(arb_midref(Q), (fmpz *) &b, CONST_B);
arb_mul(Q, Q, G);
if (b % 2)
fmpz_neg(arb_midref(Q), arb_midref(Q));
}
else
{
long m;
arb_t G2, P2, Q2;

m = (a + b) / 2;

arb_init(G2, wp);
arb_init(P2, wp);
arb_init(Q2, wp);

chudnovsky_bsplit(G, P, Q, a, m, wp, 1);
chudnovsky_bsplit(G2, P2, Q2, m, b, wp, 1);

arb_mul(Q, Q, P2);
arb_addmul(Q, Q2, G);

arb_mul(P, P, P2);

if (cont)
arb_mul(G, G, G2);

arb_clear(G2);
arb_clear(P2);
arb_clear(Q2);
}
}

void
arb_const_pi_chudnovsky(arb_t x)
{
long prec, wp, N;
arb_t G, P, Q;

prec = arb_prec(x);
wp = prec + 32;

N = wp / BITS_PER_TERM + 1;

arb_init(G, wp);
arb_init(P, wp);
arb_init(Q, wp);

chudnovsky_bsplit(G, P, Q, 0, N, wp, 0);

arb_sqrt_ui(G, CONST_C);
arb_mul_si(G, G, CONST_C);
arb_mul(G, G, P);
arb_mul_si(P, P, CONST_A);
arb_add(Q, Q, P);
arb_mul_si(Q, Q, CONST_D);
arb_div(x, G, Q);

/* TODO: add error term */

arb_clear(G);
arb_clear(P);
arb_clear(Q);
}
93 changes: 93 additions & 0 deletions arb/const_zeta3_bplit.c
@@ -0,0 +1,93 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

static void
zeta3_bsplit(arb_t P, arb_t Q, arb_t T, long a, long b, long wp, int cont)
{
if (b - a == 1)
{
arb_set_si(P, a ? a : 1);
fmpz_pow_ui(arb_midref(P), arb_midref(P), 5);

arb_set_si(Q, 2*a + 1);
fmpz_pow_ui(arb_midref(Q), arb_midref(Q), 5);
fmpz_mul_ui(arb_midref(Q), arb_midref(Q), a ? 32 : 64);

arb_set_si(T, 205*a*a + 250*a + 77); /* xxx: overflow */
if (a % 2)
fmpz_neg(arb_midref(T), arb_midref(T));
arb_mul(T, T, P);
}
else
{
long m;
arb_t P2, Q2, T2;

m = (a + b) / 2;

arb_init(P2, wp);
arb_init(Q2, wp);
arb_init(T2, wp);

zeta3_bsplit(P, Q, T, a, m, wp, 1);
zeta3_bsplit(P2, Q2, T2, m, b, wp, 1);

arb_mul(T, T, Q2);
arb_addmul(T, P, T2);
arb_mul(Q, Q, Q2);
if (cont)
arb_mul(P, P, P2);

arb_clear(P2);
arb_clear(Q2);
arb_clear(T2);
}
}

void
arb_const_zeta3_bsplit(arb_t x)
{
long prec, wp, N;
arb_t P, Q, T;

prec = arb_prec(x);
wp = prec + 10 + FLINT_BIT_COUNT(prec);
N = prec / 10 + 2;

arb_init(P, wp);
arb_init(Q, wp);
arb_init(T, wp);

zeta3_bsplit(P, Q, T, 0, N, wp, 0);
arb_div(x, T, Q);

arb_add_error_2exp(x, -10 * (N - 1));

arb_clear(P);
arb_clear(Q);
arb_clear(T);
}
72 changes: 72 additions & 0 deletions arb/contains_fmpq.c
@@ -0,0 +1,72 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int
arb_contains_fmpq(const arb_t x, const fmpq_t q)
{
fmpz_t a, b;
long exp = *arb_expref(x);
int result;

/* fixme */
if (COEFF_IS_MPZ(exp))
{
printf("error: arb_contains_fmpq: too large exponent\n");
abort();
}

fmpz_init(a);
fmpz_init(b);

/* compare with left endpoint */
fmpz_sub(a, arb_midref(x), arb_radref(x));
fmpz_mul(a, a, fmpq_denref(q));
if (exp >= 0)
{
fmpz_mul_2exp(a, a, exp);
fmpz_set(b, fmpq_numref(q));
}
else
fmpz_mul_2exp(b, fmpq_numref(q), -exp);

result = (fmpz_cmp(a, b) <= 0);

/* compare with right endpoint */
if (result != 0)
{
fmpz_add(a, arb_midref(x), arb_radref(x));
fmpz_mul(a, a, fmpq_denref(q));
if (exp >= 0)
fmpz_mul_2exp(a, a, exp);
result = (fmpz_cmp(a, b) >= 0);
}

fmpz_clear(a);
fmpz_clear(b);

return result;
}
70 changes: 70 additions & 0 deletions arb/contains_fmpz.c
@@ -0,0 +1,70 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int
arb_contains_fmpz(const arb_t x, const fmpz_t z)
{
fmpz_t a, b;
long exp = *arb_expref(x);
int result;

/* fixme */
if (COEFF_IS_MPZ(exp))
{
printf("error: arb_contains_fmpz: too large exponent\n");
abort();
}

fmpz_init(a);
fmpz_init(b);

/* compare with left endpoint */
fmpz_sub(a, arb_midref(x), arb_radref(x));
if (exp >= 0)
{
fmpz_mul_2exp(a, a, exp);
fmpz_set(b, z);
}
else
fmpz_mul_2exp(b, z, -exp);

result = (fmpz_cmp(a, b) <= 0);

/* compare with right endpoint */
if (result != 0)
{
fmpz_add(a, arb_midref(x), arb_radref(x));
if (exp >= 0)
fmpz_mul_2exp(a, a, exp);
result = (fmpz_cmp(a, b) >= 0);
}

fmpz_clear(a);
fmpz_clear(b);

return result;
}
65 changes: 65 additions & 0 deletions arb/contains_mpfr.c
@@ -0,0 +1,65 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int
arb_contains_mpfr(const arb_t x, const mpfr_t z)
{
fmpz_t a;
mpfr_t t;
long exp = *arb_expref(x);
int result;

/* fixme */
if (COEFF_IS_MPZ(exp))
{
printf("error: arb_contains_mpfr: too large exponent\n");
abort();
}

fmpz_init(a);

/* compare with left endpoint */
fmpz_sub(a, arb_midref(x), arb_radref(x));

mpfr_init2(t, 2 + fmpz_bits(a));
_arb_get_mpfr(t, a, arb_expref(x), MPFR_RNDN); /* exact */

result = (mpfr_cmp(t, z) <= 0);

/* compare with right endpoint */
if (result != 0)
{
fmpz_add(a, arb_midref(x), arb_radref(x));
mpfr_set_prec(t, 2 + fmpz_bits(a));
_arb_get_mpfr(t, a, arb_expref(x), MPFR_RNDN); /* exact */
result = (mpfr_cmp(t, z) >= 0);
}

fmpz_clear(a);
mpfr_clear(t);
return result;
}
38 changes: 38 additions & 0 deletions arb/contains_ui.c
@@ -0,0 +1,38 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int
arb_contains_ui(const arb_t x, ulong z)
{
fmpz_t t;
int result;

fmpz_init_set_ui(t, z);
result = arb_contains_fmpz(x, t);
fmpz_clear(t);
return result;
}
32 changes: 32 additions & 0 deletions arb/contains_zero.c
@@ -0,0 +1,32 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int
arb_contains_zero(const arb_t x)
{
return fmpz_cmpabs(arb_radref(x), arb_midref(x)) >= 0;
}
40 changes: 40 additions & 0 deletions arb/debug.c
@@ -0,0 +1,40 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_debug(const arb_t x)
{
printf("arb(mid=");
fmpz_print(arb_midref(x));
printf(", rad=");
fmpz_print(arb_radref(x));
printf(", exp=");
fmpz_print(arb_expref(x));
printf(", prec=");
printf("%ld", arb_prec(x));
printf(")");
}
105 changes: 105 additions & 0 deletions arb/div.c
@@ -0,0 +1,105 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_div(arb_t c, const arb_t a, const arb_t b)
{
fmpz_t t, u, v;
long abits, bbits, sshift, shift;

if (arb_contains_zero(b))
{
printf("arb_div: division by zero\n");
abort();
}

if (fmpz_is_zero(arb_radref(b)))
{
if (fmpz_is_zero(arb_radref(a)))
{
fmpz_init(t);
fmpz_sub(t, arb_expref(a), arb_expref(b));
_arb_set_fmpq(c, arb_midref(a), arb_midref(b));
fmpz_add(arb_expref(c), arb_expref(c), t);
fmpz_clear(t);
return;
}

/* TODO: (a + r) / b = a / b + r / b */
}

fmpz_init(t);
fmpz_init(u);
fmpz_init(v);

abits = fmpz_bits(arb_midref(a));
bbits = fmpz_bits(arb_midref(b));
sshift = arb_prec(c) - (abits - bbits);
shift = FLINT_MAX(0, sshift);

/* a/b - (a+r)/(b-s) = r/(s-b) + a*s/(b*(s-b)) */

/* t = minimize |s-b| */
if (fmpz_sgn(arb_midref(b)) >= 0)
{
fmpz_sub(t, arb_midref(b), arb_radref(b));
}
else
{
fmpz_add(t, arb_midref(b), arb_radref(b));
fmpz_neg(t, t);
}

/* first terror term: r/|s-b| */
fmpz_mul_2exp(u, arb_radref(a), shift);
fmpz_cdiv_q(u, u, t);

/* second error term (likely small): a*s/(b*(s-b)) */
fmpz_mul_2exp(v, arb_midref(a), shift);
fmpz_mul(v, v, arb_radref(b));
fmpz_abs(v, v);
fmpz_cdiv_q_2exp(v, v, bbits - 1); /* fast approximate division */
fmpz_cdiv_q_2exp(v, v, fmpz_bits(t) - 1); /* fast approximate division */

/* add error terms */
fmpz_add(arb_radref(c), u, v);

/* compute quotient; TODO: normalise afterwards if sshift < 0 */
fmpz_mul_2exp(v, arb_midref(a), shift);
fmpz_tdiv_q(arb_midref(c), v, arb_midref(b));

/* error from main division */
fmpz_add_ui(arb_radref(c), arb_radref(c), 1UL);

/* subtract exponents */
fmpz_sub(arb_expref(c), arb_expref(a), arb_expref(b));
fmpz_sub_ui(arb_expref(c), arb_expref(c), shift);

fmpz_clear(t);
fmpz_clear(u);
fmpz_clear(v);
}
97 changes: 97 additions & 0 deletions arb/fmpz_extras.c
@@ -0,0 +1,97 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
_fmpz_addmul_abs_ui(fmpz_t f, const fmpz_t g, ulong x)
{
fmpz c1 = *g;

/* c1 is small */
if (!COEFF_IS_MPZ(c1))
{
mp_limb_t prod[2];
ulong uc1 = FLINT_ABS(c1);

/* compute product */
umul_ppmm(prod[1], prod[0], uc1, x);

/* product fits in one limb */
if (prod[1] == 0)
{
fmpz_add_ui(f, f, prod[0]);
}
else
{
__mpz_struct * mpz_ptr = _fmpz_promote_val(f);
mpz_t temp; /* set up a temporary, cheap mpz_t to contain prod */
temp->_mp_d = prod;
temp->_mp_size = 2;
mpz_add(mpz_ptr, mpz_ptr, temp);
}
}
else /* c1 is large */
{
__mpz_struct * cptr = COEFF_TO_PTR(c1);
__mpz_struct * mpz_ptr = _fmpz_promote_val(f);
if (mpz_sgn(cptr) == -1)
mpz_submul_ui(mpz_ptr, cptr, x);
else
mpz_addmul_ui(mpz_ptr, cptr, x);
}
}

void
_fmpz_addmul_abs(fmpz_t f, const fmpz_t g, const fmpz_t h)
{
fmpz c1, c2;
__mpz_struct * mpz_ptr, *p1, *p2;

c1 = *g;
if (!COEFF_IS_MPZ(c1)) /* g is small */
{
_fmpz_addmul_abs_ui(f, h, FLINT_ABS(c1));
return;
}

c2 = *h;
if (!COEFF_IS_MPZ(c2)) /* h is small */
{
_fmpz_addmul_abs_ui(f, g, FLINT_ABS(c2));
return;
}

/* both g and h are large */
mpz_ptr = _fmpz_promote_val(f);

p1 = COEFF_TO_PTR(c1);
p2 = COEFF_TO_PTR(c2);

if (mpz_sgn(p1) != mpz_sgn(p2))
mpz_submul(mpz_ptr, p1, p2);
else
mpz_addmul(mpz_ptr, p1, p2);
}
62 changes: 62 additions & 0 deletions arb/get_mpfr.c
@@ -0,0 +1,62 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

static __inline__ void
mpfr_set_fmpz(mpfr_t c, const fmpz_t b, mpfr_rnd_t rnd)
{
if (COEFF_IS_MPZ(*b))
mpfr_set_z(c, COEFF_TO_PTR(*b), rnd);
else
mpfr_set_si(c, *b, rnd);
}

void
_arb_get_mpfr(mpfr_t f, const fmpz_t mid, const fmpz_t exp, mpfr_rnd_t rnd)
{
long e;

if (COEFF_IS_MPZ(*exp))
{
printf("arb_get_mpfr: large exponent\n");
abort();
}

e = fmpz_get_si(exp);

mpfr_set_fmpz(f, mid, rnd);

if (e >= 0)
mpfr_mul_2exp(f, f, e, rnd);
else
mpfr_div_2exp(f, f, -e, rnd);
}

void
arb_get_mpfr(mpfr_t f, const arb_t x, mpfr_rnd_t rnd)
{
_arb_get_mpfr(f, arb_midref(x), arb_expref(x), rnd);
}
86 changes: 86 additions & 0 deletions arb/get_rand_fmpq.c
@@ -0,0 +1,86 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_get_rand_fmpq(fmpq_t q, flint_rand_t state, const arb_t x)
{
fmpz_t a, b;
long exp = *arb_expref(x);

if (COEFF_IS_MPZ(exp))
{
printf("error: arb_get_rand_fmpq: too large exponent\n");
abort();
}

/* there is only one rational */
if (fmpz_is_zero(arb_radref(x)))
{
fmpz_set(fmpq_numref(q), arb_midref(x));
fmpz_set_ui(fmpq_denref(q), 1UL);
if (exp >= 0)
fmpz_mul_2exp(fmpq_numref(q), fmpq_numref(q), exp);
else
fmpz_mul_2exp(fmpq_denref(q), fmpq_denref(q), -exp);
fmpq_canonicalise(q);
return;
}

fmpz_init(a);
fmpz_init(b);

fmpz_sub(a, arb_midref(x), arb_radref(x));
fmpz_add(b, arb_midref(x), arb_radref(x));

/* pick a denominator */
fmpz_randbits(fmpq_denref(q), state, 1 + n_randint(state, arb_prec(x)));
fmpz_abs(fmpq_denref(q), fmpq_denref(q));
if (fmpz_is_zero(fmpq_denref(q)))
fmpz_set_ui(fmpq_denref(q), 1UL);

if (exp >= 0)
{
fmpz_mul_2exp(a, a, exp);
fmpz_mul_2exp(b, b, exp);
}

/* generate random integer in [a*den, b*den] */
fmpz_mul(a, a, fmpq_denref(q));
fmpz_mul(b, b, fmpq_denref(q));
fmpz_add_ui(b, b, 1UL);
fmpz_sub(b, b, a);
fmpz_randtest_mod(fmpq_numref(q), state, b);
fmpz_add(fmpq_numref(q), fmpq_numref(q), a);

if (exp < 0)
fmpz_mul_2exp(fmpq_denref(q), fmpq_denref(q), -exp);

fmpq_canonicalise(q);

fmpz_clear(a);
fmpz_clear(b);
}
35 changes: 35 additions & 0 deletions arb/init.c
@@ -0,0 +1,35 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_init(arb_t x, long prec)
{
fmpz_init(&x->mid);
fmpz_init(&x->exp);
x->rad = 0;
x->prec = prec;
}
75 changes: 75 additions & 0 deletions arb/log_ui.c
@@ -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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_log_ui(arb_t x, ulong n)
{
mpfr_t y;
mpz_t z;
long exp;

if (n == 0)
{
printf("arb_log_ui: log(0)\n");
abort();
}

if (n == 1)
{
arb_zero(x);
return;
}

/* power of two */
if (n > 2 && (n & (n-1UL)) == 0UL)
{
arb_log_ui(x, 2);
arb_mul_si(x, x, FLINT_BIT_COUNT(n) - 1);
return;
}

mpfr_init2(y, FLINT_MAX(arb_prec(x), FLINT_BITS));

if (n == 2)
{
mpfr_const_log2(y, MPFR_RNDN);
fmpz_set_ui(arb_radref(x), 1UL);
}
else
{
mpfr_set_ui(y, n, MPFR_RNDN); /* exact */
mpfr_log(y, y, MPFR_RNDN);
fmpz_set_ui(arb_radref(x), 1UL);
}

mpz_init(z);
exp = mpfr_get_z_2exp(z, y);
fmpz_set_mpz(arb_midref(x), z);
fmpz_set_si(arb_expref(x), exp);
mpz_clear(z);
mpfr_clear(y);
}
84 changes: 84 additions & 0 deletions arb/mul.c
@@ -0,0 +1,84 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_mul(arb_t c, const arb_t a, const arb_t b)
{
/* multiply errors */
if (fmpz_is_zero(arb_radref(a)))
{
if (fmpz_is_zero(arb_radref(b)))
{
fmpz_zero(arb_radref(c));
}
else
{
/* a * (b + r) = a*b + a*r */
_fmpz_mul_abs(arb_radref(c), arb_midref(a), arb_radref(b));
}
}
else
{
if (fmpz_is_zero(arb_radref(b)))
{
/* (a + r) * b = a*b + b*r */
_fmpz_mul_abs(arb_radref(c), arb_midref(b), arb_radref(a));
}
else
{
/* (a + r) * (b + s) = a*b + a*s + b*r + r*s */
if (c != a && c != b)
{
/* no aliasing */
fmpz_mul(arb_radref(c), arb_radref(a), arb_radref(b));
_fmpz_addmul_abs(arb_radref(c), arb_midref(a), arb_radref(b));
_fmpz_addmul_abs(arb_radref(c), arb_midref(b), arb_radref(a));
}
else
{
/* aliasing */
fmpz_t t;
fmpz_init(t);
fmpz_mul(t, arb_radref(a), arb_radref(b));
_fmpz_addmul_abs(t, arb_midref(a), arb_radref(b));
_fmpz_addmul_abs(t, arb_midref(b), arb_radref(a));
fmpz_swap(arb_radref(c), t);
fmpz_clear(t);
}
}
}

fmpz_mul(arb_midref(c), arb_midref(a), arb_midref(b));

/* common case (both integers) */
if (fmpz_is_zero(arb_expref(a)) && fmpz_is_zero(arb_expref(b)))
fmpz_zero(arb_expref(c));
else
fmpz_add(arb_expref(c), arb_expref(a), arb_expref(b));

_arb_normalise(c);
}
35 changes: 35 additions & 0 deletions arb/mul_si.c
@@ -0,0 +1,35 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

/* todo: reduce? */
void
arb_mul_si(arb_t y, const arb_t x, long c)
{
fmpz_mul_si(arb_midref(y), arb_midref(x), c);
fmpz_mul_si(arb_radref(y), arb_radref(x), c);
fmpz_set(arb_expref(y), arb_expref(x));
}
45 changes: 45 additions & 0 deletions arb/randtest.c
@@ -0,0 +1,45 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_randtest(arb_t x, flint_rand_t state, long exp_bits)
{
fmpz_randtest(arb_midref(x), state, arb_prec(x));

if (n_randint(state, 4) == 0)
fmpz_zero(arb_radref(x));
else
{
fmpz_randtest(arb_radref(x), state, arb_prec(x));
fmpz_abs(arb_radref(x), arb_radref(x));
}

if (n_randint(state, 4) == 0)
fmpz_zero(arb_expref(x));
else
fmpz_randtest(arb_expref(x), state, exp_bits);
}
35 changes: 35 additions & 0 deletions arb/set.c
@@ -0,0 +1,35 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

/* todo: reduce */
void
arb_set(arb_t dst, const arb_t src)
{
fmpz_set(arb_midref(dst), arb_midref(src));
fmpz_set(arb_radref(dst), arb_radref(src));
fmpz_set(arb_expref(dst), arb_expref(src));
}
66 changes: 66 additions & 0 deletions arb/set_fmpq.c
@@ -0,0 +1,66 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
_arb_set_fmpq(arb_t x, const fmpz_t p, const fmpz_t q)
{
long pbits, qbits, shift;

if (fmpz_is_one(q))
{
arb_set_fmpz(x, p);
return;
}

pbits = fmpz_bits(p);
qbits = fmpz_bits(q);
shift = arb_prec(x) - (pbits - qbits);

if (shift > 0)
{
fmpz_t t;
fmpz_init(t);
fmpz_mul_2exp(t, p, shift);
fmpz_tdiv_q(arb_midref(x), t, q);
fmpz_clear(t);
fmpz_one(arb_radref(x));
fmpz_set_si(arb_expref(x), -shift);
}
else
{
fmpz_tdiv_q(arb_midref(x), p, q);
fmpz_zero(arb_expref(x));
fmpz_one(arb_radref(x));
_arb_normalise(x);
}
}

void
arb_set_fmpq(arb_t x, const fmpq_t c)
{
_arb_set_fmpq(x, fmpq_numref(c), fmpq_denref(c));
}
35 changes: 35 additions & 0 deletions arb/set_fmpz.c
@@ -0,0 +1,35 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_set_fmpz(arb_t x, const fmpz_t c)
{
/* todo: reduce */
fmpz_set(arb_midref(x), c);
fmpz_zero(arb_expref(x));
fmpz_zero(arb_radref(x));
}
34 changes: 34 additions & 0 deletions arb/set_si.c
@@ -0,0 +1,34 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_set_si(arb_t x, long c)
{
fmpz_set_si(arb_midref(x), c);
fmpz_zero(arb_expref(x));
fmpz_zero(arb_radref(x));
}
34 changes: 34 additions & 0 deletions arb/set_ui.c
@@ -0,0 +1,34 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_set_ui(arb_t x, ulong c)
{
fmpz_set_ui(arb_midref(x), c);
fmpz_zero(arb_expref(x));
fmpz_zero(arb_radref(x));
}
67 changes: 67 additions & 0 deletions arb/sqrt_fmpz.c
@@ -0,0 +1,67 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_sqrt_fmpz(arb_t x, const fmpz_t n)
{
long size, prec;

if (fmpz_sgn(n) < 0)
{
printf("arb_sqrt_fmpz: negative input\n");
abort();
}

if (fmpz_is_zero(n) || fmpz_is_one(n))
{
arb_set_fmpz(x, n);
return;
}

prec = arb_prec(x);
size = fmpz_bits(n);

/* todo: shift down */
if (size >= 2 * prec)
{
fmpz_sqrt(arb_midref(x), n);
fmpz_zero(arb_expref(x));
}
else
{
long shift;

shift = 2 * prec - size;
shift += (shift & 1);

fmpz_mul_2exp(arb_midref(x), n, shift);
fmpz_sqrt(arb_midref(x), arb_midref(x));
fmpz_set_si(arb_expref(x), -shift / 2);
}

fmpz_one(arb_radref(x));
}
35 changes: 35 additions & 0 deletions arb/sqrt_ui.c
@@ -0,0 +1,35 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_sqrt_ui(arb_t x, ulong n)
{
fmpz_t t;
fmpz_init_set_ui(t, n);
arb_sqrt_fmpz(x, t);
fmpz_clear(t);
}
89 changes: 89 additions & 0 deletions arb/sub.c
@@ -0,0 +1,89 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_sub(arb_t c, const arb_t a, const arb_t b)
{
fmpz e, f;

e = *arb_expref(a);
f = *arb_expref(b);

/* both exponents equal and small (e.g. small integer case) */
if (e == f)
{
/* subtract midpoints */
fmpz_sub(arb_midref(c), arb_midref(a), arb_midref(b));

/* add errors */
if (fmpz_is_zero(arb_radref(a)) && fmpz_is_zero(arb_radref(b)))
fmpz_zero(arb_radref(c));
else
fmpz_add(arb_radref(c), arb_radref(a), arb_radref(b));

/* set exponent */
_fmpz_set_si_small(arb_expref(c), e);
}
/* both exponents are small */
else if (!COEFF_IS_MPZ(e) && !COEFF_IS_MPZ(f))
{
fmpz_t t;
fmpz_init(t);

/* TODO: be smart when one argument (or both) has rad = 0 */

if (e >= f)
{
fmpz_tdiv_q_2exp(t, arb_midref(b), e - f);
fmpz_sub(arb_midref(c), arb_midref(a), t);

fmpz_cdiv_q_2exp(t, arb_radref(b), e - f);
fmpz_add(arb_radref(c), arb_radref(a), t);
fmpz_add_ui(arb_radref(c), arb_radref(c), 1UL);

_fmpz_set_si_small(arb_expref(c), e);
}
else
{
fmpz_tdiv_q_2exp(t, arb_midref(a), f - e);
fmpz_sub(arb_midref(c), t, arb_midref(b));

fmpz_cdiv_q_2exp(t, arb_radref(a), f - e);
fmpz_add(arb_radref(c), arb_radref(b), t);
fmpz_add_ui(arb_radref(c), arb_radref(c), 1UL);

_fmpz_set_si_small(arb_expref(c), f);
}

fmpz_clear(t);
}
else
{
/* not implemented */
abort();
}
}
86 changes: 86 additions & 0 deletions arb/submul.c
@@ -0,0 +1,86 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

void
arb_submul(arb_t c, const arb_t a, const arb_t b)
{
if (fmpz_is_zero(arb_expref(c)) && fmpz_is_zero(arb_expref(a))
&& fmpz_is_zero(arb_expref(b)))
{
/* multiply errors */
if (fmpz_is_zero(arb_radref(a)))
{
if (!fmpz_is_zero(arb_radref(b)))
{
/* (c+e) + a * (b+r) = c + a*b + (e+a*r) */
_fmpz_addmul_abs(arb_radref(c), arb_midref(a), arb_radref(b));
}
}
else
{
if (fmpz_is_zero(arb_radref(b)))
{
/* (c+e) + (a+r) * b = c + a*b + (e+b*r) */
_fmpz_addmul_abs(arb_radref(c), arb_midref(b), arb_radref(a));
}
else
{
/* (a + r) * (b + s) = a*b + a*s + b*r + r*s */
if (c != a && c != b)
{
/* no aliasing */
_fmpz_addmul_abs(arb_radref(c), arb_radref(a), arb_radref(b));
_fmpz_addmul_abs(arb_radref(c), arb_midref(a), arb_radref(b));
_fmpz_addmul_abs(arb_radref(c), arb_midref(b), arb_radref(a));
}
else
{
fmpz_t t;
fmpz_init(t);
fmpz_mul(t, arb_radref(a), arb_radref(b));
_fmpz_addmul_abs(t, arb_midref(a), arb_radref(b));
_fmpz_addmul_abs(t, arb_midref(b), arb_radref(a));
fmpz_add(arb_radref(c), arb_radref(c), t);
fmpz_clear(t);
}
}
}

/* multiply midpoints */
fmpz_submul(arb_midref(c), arb_midref(a), arb_midref(b));

_arb_normalise(c);
}
else
{
arb_t t;
arb_init(t, arb_prec(c));
arb_mul(t, a, b);
arb_sub(c, c, t);
arb_clear(t);
}
}
168 changes: 168 additions & 0 deletions arb/test/t-add.c
@@ -0,0 +1,168 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int main()
{
long iter;
flint_rand_t state;

printf("add....");
fflush(stdout);

flint_randinit(state);

for (iter = 0; iter < 10000; iter++)
{
arb_t a, b, c;
fmpq_t x, y, z;

arb_init(a, n_randint(state, 200));
arb_init(b, n_randint(state, 200));
arb_init(c, n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);
fmpq_init(z);

arb_randtest(a, state, 10);
arb_randtest(b, state, 10);
arb_randtest(c, state, 10);

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);

arb_add(c, a, b);
fmpq_add(z, x, y);

if (!arb_contains_fmpq(c, z))
{
printf("FAIL: containment\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
printf("c = "); arb_debug(c); printf("\n\n");
printf("z = "); fmpq_print(z); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);
arb_clear(c);

fmpq_clear(x);
fmpq_clear(y);
fmpq_clear(z);
}

/* aliasing of c and a */
for (iter = 0; iter < 10000; iter++)
{
arb_t a, b;
fmpq_t x, y, z;

arb_init(a, n_randint(state, 200));
arb_init(b, n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);
fmpq_init(z);

arb_randtest(a, state, 10);
arb_randtest(b, state, 10);

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);

arb_add(a, a, b);
fmpq_add(z, x, y);

if (!arb_contains_fmpq(a, z))
{
printf("FAIL: aliasing (c, a)\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
printf("z = "); fmpq_print(z); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);

fmpq_clear(x);
fmpq_clear(y);
fmpq_clear(z);
}

/* aliasing of c and b */
for (iter = 0; iter < 10000; iter++)
{
arb_t a, b;
fmpq_t x, y, z;

arb_init(a, n_randint(state, 200));
arb_init(b, n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);
fmpq_init(z);

arb_randtest(a, state, 10);
arb_randtest(b, state, 10);

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);

arb_add(b, a, b);
fmpq_add(z, x, y);

if (!arb_contains_fmpq(b, z))
{
printf("FAIL: aliasing (c, b)\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
printf("z = "); fmpq_print(z); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);

fmpq_clear(x);
fmpq_clear(y);
fmpq_clear(z);
}

flint_randclear(state);
_fmpz_cleanup();
printf("PASS\n");
return EXIT_SUCCESS;
}
163 changes: 163 additions & 0 deletions arb/test/t-addmul.c
@@ -0,0 +1,163 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int main()
{
long iter;
flint_rand_t state;

printf("addmul....");
fflush(stdout);

flint_randinit(state);

for (iter = 0; iter < 10000; iter++)
{
arb_t a, b, c;
fmpq_t x, y, z;

arb_init(a, n_randint(state, 200));
arb_init(b, n_randint(state, 200));
arb_init(c, n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);
fmpq_init(z);

arb_randtest(a, state, 10);
arb_randtest(b, state, 10);
arb_randtest(c, state, 10);

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);
arb_get_rand_fmpq(z, state, c);

arb_addmul(c, a, b);
fmpq_addmul(z, x, y);

if (!arb_contains_fmpq(c, z))
{
printf("FAIL: containment\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
printf("c = "); arb_debug(c); printf("\n\n");
printf("z = "); fmpq_print(z); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);
arb_clear(c);

fmpq_clear(x);
fmpq_clear(y);
fmpq_clear(z);
}

/* aliasing of c and a */
for (iter = 0; iter < 10000; iter++)
{
arb_t a, b;
fmpq_t x, y;

arb_init(a, n_randint(state, 200));
arb_init(b, n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);

arb_randtest(a, state, 10);
arb_randtest(b, state, 10);

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);

arb_addmul(a, a, b);
fmpq_addmul(x, x, y);

if (!arb_contains_fmpq(a, x))
{
printf("FAIL: aliasing (c, a)\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);

fmpq_clear(x);
fmpq_clear(y);
}

/* aliasing of c and b */
for (iter = 0; iter < 10000; iter++)
{
arb_t a, b;
fmpq_t x, y;

arb_init(a, n_randint(state, 200));
arb_init(b, n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);

arb_randtest(a, state, 10);
arb_randtest(b, state, 10);

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);

arb_addmul(b, a, b);
fmpq_addmul(y, x, y);

if (!arb_contains_fmpq(b, y))
{
printf("FAIL: aliasing (c, b)\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);

fmpq_clear(x);
fmpq_clear(y);
}

flint_randclear(state);
_fmpz_cleanup();
printf("PASS\n");
return EXIT_SUCCESS;
}
76 changes: 76 additions & 0 deletions arb/test/t-const_euler_brent_mcmillan.c
@@ -0,0 +1,76 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int main()
{
long iter;
flint_rand_t state;

printf("const_euler_brent_mcmillan....");
fflush(stdout);

flint_randinit(state);

for (iter = 0; iter < 250; iter++)
{
arb_t r;
mpfr_t s;
long effective_prec;

arb_init(r, 1 + n_randint(state, 1 << n_randint(state, 16)));
mpfr_init2(s, arb_prec(r) + 1000);
arb_randtest(r, state, 10);

arb_const_euler_brent_mcmillan(r);
mpfr_const_euler(s, MPFR_RNDN);

if (!arb_contains_mpfr(r, s))
{
printf("FAIL: containment\n\n");
printf("r = "); arb_debug(r); printf("\n\n");
abort();
}

effective_prec = fmpz_bits(arb_midref(r)) - fmpz_bits(arb_radref(r));

if (effective_prec < arb_prec(r) - 4)
{
printf("FAIL: poor accuracy\n\n");
printf("r = "); arb_debug(r); printf("\n\n");
abort();
}

arb_clear(r);
mpfr_clear(s);
}

flint_randclear(state);
_fmpz_cleanup();
mpfr_free_cache();
printf("PASS\n");
return EXIT_SUCCESS;
}
76 changes: 76 additions & 0 deletions arb/test/t-const_pi_chudnovsky.c
@@ -0,0 +1,76 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int main()
{
long iter;
flint_rand_t state;

printf("const_pi_chudnovsky....");
fflush(stdout);

flint_randinit(state);

for (iter = 0; iter < 250; iter++)
{
arb_t r;
mpfr_t s;
long effective_prec;

arb_init(r, 1 + n_randint(state, 1 << n_randint(state, 18)));
mpfr_init2(s, arb_prec(r) + 1000);
arb_randtest(r, state, 10);

arb_const_pi_chudnovsky(r);
mpfr_const_pi(s, MPFR_RNDN);

if (!arb_contains_mpfr(r, s))
{
printf("FAIL: containment\n\n");
printf("r = "); arb_debug(r); printf("\n\n");
abort();
}

effective_prec = fmpz_bits(arb_midref(r)) - fmpz_bits(arb_radref(r));

if (effective_prec < arb_prec(r) - 4)
{
printf("FAIL: poor accuracy\n\n");
printf("r = "); arb_debug(r); printf("\n\n");
abort();
}

arb_clear(r);
mpfr_clear(s);
}

flint_randclear(state);
_fmpz_cleanup();
mpfr_free_cache();
printf("PASS\n");
return EXIT_SUCCESS;
}
76 changes: 76 additions & 0 deletions arb/test/t-const_zeta3_bsplit.c
@@ -0,0 +1,76 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int main()
{
long iter;
flint_rand_t state;

printf("const_zeta3_bsplit....");
fflush(stdout);

flint_randinit(state);

for (iter = 0; iter < 250; iter++)
{
arb_t r;
mpfr_t s;
long effective_prec;

arb_init(r, 1 + n_randint(state, 1 << n_randint(state, 17)));
mpfr_init2(s, arb_prec(r) + 1000);
arb_randtest(r, state, 10);

arb_const_zeta3_bsplit(r);
mpfr_zeta_ui(s, 3, MPFR_RNDN);

if (!arb_contains_mpfr(r, s))
{
printf("FAIL: containment\n\n");
printf("r = "); arb_debug(r); printf("\n\n");
abort();
}

effective_prec = fmpz_bits(arb_midref(r)) - fmpz_bits(arb_radref(r));

if (effective_prec < arb_prec(r) - 4)
{
printf("FAIL: poor accuracy\n\n");
printf("r = "); arb_debug(r); printf("\n\n");
abort();
}

arb_clear(r);
mpfr_clear(s);
}

flint_randclear(state);
_fmpz_cleanup();
mpfr_free_cache();
printf("PASS\n");
return EXIT_SUCCESS;
}
168 changes: 168 additions & 0 deletions arb/test/t-div.c
@@ -0,0 +1,168 @@
/*=============================================================================
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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int main()
{
long iter;
flint_rand_t state;

printf("div....");
fflush(stdout);

flint_randinit(state);

for (iter = 0; iter < 10000; iter++)
{
arb_t a, b, c;
fmpq_t x, y, z;

arb_init(a, 1 + n_randint(state, 200));
arb_init(b, 1 + n_randint(state, 200));
arb_init(c, 1 + n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);
fmpq_init(z);

arb_randtest(a, state, 10);
do { arb_randtest(b, state, 10); } while (arb_contains_zero(b));
arb_randtest(c, state, 10);

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);

arb_div(c, a, b);
fmpq_div(z, x, y);

if (!arb_contains_fmpq(c, z))
{
printf("FAIL: containment\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
printf("c = "); arb_debug(c); printf("\n\n");
printf("z = "); fmpq_print(z); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);
arb_clear(c);

fmpq_clear(x);
fmpq_clear(y);
fmpq_clear(z);
}

/* aliasing of c and a */
for (iter = 0; iter < 10000; iter++)
{
arb_t a, b;
fmpq_t x, y, z;

arb_init(a, 1 + n_randint(state, 200));
arb_init(b, 1 + n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);
fmpq_init(z);

arb_randtest(a, state, 10);
do { arb_randtest(b, state, 10); } while (arb_contains_zero(b));

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);

arb_div(a, a, b);
fmpq_div(z, x, y);

if (!arb_contains_fmpq(a, z))
{
printf("FAIL: aliasing (c, a)\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
printf("z = "); fmpq_print(z); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);

fmpq_clear(x);
fmpq_clear(y);
fmpq_clear(z);
}

/* aliasing of c and b */
for (iter = 0; iter < 10000; iter++)
{
arb_t a, b;
fmpq_t x, y, z;

arb_init(a, 1 + n_randint(state, 200));
arb_init(b, 1 + n_randint(state, 200));

fmpq_init(x);
fmpq_init(y);
fmpq_init(z);

arb_randtest(a, state, 10);
do { arb_randtest(b, state, 10); } while (arb_contains_zero(b));

arb_get_rand_fmpq(x, state, a);
arb_get_rand_fmpq(y, state, b);

arb_div(b, a, b);
fmpq_div(z, x, y);

if (!arb_contains_fmpq(b, z))
{
printf("FAIL: aliasing (c, b)\n\n");
printf("a = "); arb_debug(a); printf("\n\n");
printf("x = "); fmpq_print(x); printf("\n\n");
printf("b = "); arb_debug(b); printf("\n\n");
printf("y = "); fmpq_print(y); printf("\n\n");
printf("z = "); fmpq_print(z); printf("\n\n");
abort();
}

arb_clear(a);
arb_clear(b);

fmpq_clear(x);
fmpq_clear(y);
fmpq_clear(z);
}

flint_randclear(state);
_fmpz_cleanup();
printf("PASS\n");
return EXIT_SUCCESS;
}
81 changes: 81 additions & 0 deletions arb/test/t-log_ui.c
@@ -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) 2012 Fredrik Johansson
******************************************************************************/

#include "arb.h"

int main()
{
long iter;
flint_rand_t state;

printf("log_ui....");
fflush(stdout);

flint_randinit(state);

for (iter = 0; iter < 1000; iter++)
{
arb_t r;
ulong n;
mpfr_t s;
long effective_prec;

arb_init(r, 1 + n_randint(state, 1 << n_randint(state, 12)));
mpfr_init2(s, arb_prec(r) + 1000);
arb_randtest(r, state, 10);

n = n_randtest_not_zero(state);

arb_log_ui(r, n);
mpfr_set_ui(s, n, MPFR_RNDN);
mpfr_log(s, s, MPFR_RNDN);

if (!arb_contains_mpfr(r, s))
{
printf("FAIL: containment\n\n");
printf("n = %lu\n\n", n);
printf("r = "); arb_debug(r); printf("\n\n");
abort();
}

effective_prec = fmpz_bits(arb_midref(r)) - fmpz_bits(arb_radref(r));

if (!fmpz_is_zero(arb_radref(r)) && effective_prec < arb_prec(r) - 4)
{
printf("FAIL: poor accuracy\n\n");
printf("r = "); arb_debug(r); printf("\n\n");
abort();
}

arb_clear(r);
mpfr_clear(s);
}

flint_randclear(state);
_fmpz_cleanup();
mpfr_free_cache();
printf("PASS\n");
return EXIT_SUCCESS;
}