Skip to content

Commit 80e9b24

Browse files
Merge pull request #2004 from flintlib/nfloat9
Complex nfloats
2 parents 3d6eaab + a6f6fb8 commit 80e9b24

15 files changed

+2473
-18
lines changed

doc/source/nfloat.rst

+72-3
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ Types, macros and constants
6262
NFLOAT_MAX_LIMBS
6363
6464
The number of limbs `n` permitted as precision. The current
65-
limits are are `1 \le n \le 33` on a 64-bit machine and
66-
`1 \le n \le 66` on a 32-bit machine, permitting precision
67-
up to 2112 bits. The upper limit exists so that elements and
65+
limits are are `1 \le n \le 66` on a 64-bit machine and
66+
`1 \le n \le 132` on a 32-bit machine, permitting precision
67+
up to 4224 bits. The upper limit exists so that elements and
6868
temporary buffers are safe to allocate on the stack and so that
6969
simple operations like swapping are not too expensive.
7070
@@ -84,6 +84,7 @@ Types, macros and constants
8484
nfloat512_struct
8585
nfloat1024_struct
8686
nfloat2048_struct
87+
nfloat4096_struct
8788
nfloat64_t
8889
nfloat128_t
8990
nfloat192_t
@@ -92,6 +93,7 @@ Types, macros and constants
9293
nfloat512_t
9394
nfloat1024_t
9495
nfloat2048_t
96+
nfloat4096_t
9597

9698
For convenience we define types of the correct structure size for
9799
some common levels of bit precision. An ``nfloatX_t`` is defined as
@@ -254,6 +256,7 @@ These methods are interchangeable with their ``gr`` counterparts.
254256
int nfloat_mul(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)
255257
int nfloat_submul(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)
256258
int nfloat_addmul(nfloat_ptr res, nfloat_srcptr x, nfloat_srcptr y, gr_ctx_t ctx)
259+
int nfloat_sqr(nfloat_ptr res, nfloat_srcptr x, gr_ctx_t ctx)
257260

258261
.. function:: int nfloat_mul_2exp_si(nfloat_ptr res, nfloat_srcptr x, slong y, gr_ctx_t ctx)
259262

@@ -329,3 +332,69 @@ Internal functions
329332
int _nfloat_sub_4(nfloat_ptr res, nn_srcptr x, slong xexp, int xsgnbit, nn_srcptr y, slong delta, gr_ctx_t ctx)
330333
int _nfloat_add_n(nfloat_ptr res, nn_srcptr xd, slong xexp, int xsgnbit, nn_srcptr yd, slong delta, slong nlimbs, gr_ctx_t ctx)
331334
int _nfloat_sub_n(nfloat_ptr res, nn_srcptr xd, slong xexp, int xsgnbit, nn_srcptr yd, slong delta, slong nlimbs, gr_ctx_t ctx)
335+
336+
Complex numbers
337+
-------------------------------------------------------------------------------
338+
339+
Complex floating-point numbers have the obvious representation as
340+
real pairs.
341+
342+
.. type:: nfloat_complex_ptr
343+
nfloat_complex_srcptr
344+
345+
.. function:: int nfloat_complex_ctx_init(gr_ctx_t ctx, slong prec, int flags)
346+
347+
.. macro:: NFLOAT_COMPLEX_CTX_DATA_NLIMBS(ctx)
348+
NFLOAT_COMPLEX_RE(ptr, ctx)
349+
NFLOAT_COMPLEX_IM(ptr, ctx)
350+
NFLOAT_COMPLEX_IS_SPECIAL(x, ctx)
351+
NFLOAT_COMPLEX_IS_ZERO(x, ctx)
352+
353+
.. function:: void nfloat_complex_init(nfloat_complex_ptr res, gr_ctx_t ctx)
354+
void nfloat_complex_clear(nfloat_complex_ptr res, gr_ctx_t ctx)
355+
int nfloat_complex_zero(nfloat_complex_ptr res, gr_ctx_t ctx)
356+
int nfloat_complex_get_acf(acf_t res, nfloat_complex_srcptr x, gr_ctx_t ctx)
357+
int nfloat_complex_set_acf(nfloat_complex_ptr res, const acf_t x, gr_ctx_t ctx)
358+
int nfloat_complex_get_acb(acb_t res, nfloat_complex_srcptr x, gr_ctx_t ctx)
359+
int nfloat_complex_set_acb(nfloat_complex_ptr res, const acb_t x, gr_ctx_t ctx)
360+
int nfloat_complex_write(gr_stream_t out, nfloat_complex_srcptr x, gr_ctx_t ctx)
361+
int nfloat_complex_randtest(nfloat_complex_ptr res, flint_rand_t state, gr_ctx_t ctx)
362+
void nfloat_complex_swap(nfloat_complex_ptr x, nfloat_complex_ptr y, gr_ctx_t ctx)
363+
int nfloat_complex_set(nfloat_complex_ptr res, nfloat_complex_ptr x, gr_ctx_t ctx)
364+
int nfloat_complex_one(nfloat_complex_ptr res, gr_ctx_t ctx)
365+
int nfloat_complex_neg_one(nfloat_complex_ptr res, gr_ctx_t ctx)
366+
truth_t nfloat_complex_is_zero(nfloat_complex_srcptr x, gr_ctx_t ctx)
367+
truth_t nfloat_complex_is_one(nfloat_complex_srcptr x, gr_ctx_t ctx)
368+
truth_t nfloat_complex_is_neg_one(nfloat_complex_srcptr x, gr_ctx_t ctx)
369+
int nfloat_complex_i(nfloat_complex_ptr res, gr_ctx_t ctx)
370+
int nfloat_complex_pi(nfloat_complex_ptr res, gr_ctx_t ctx)
371+
int nfloat_complex_conj(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)
372+
int nfloat_complex_re(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)
373+
int nfloat_complex_im(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)
374+
truth_t nfloat_complex_equal(nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)
375+
int nfloat_complex_set_si(nfloat_complex_ptr res, slong x, gr_ctx_t ctx)
376+
int nfloat_complex_set_ui(nfloat_complex_ptr res, ulong x, gr_ctx_t ctx)
377+
int nfloat_complex_set_fmpz(nfloat_complex_ptr res, const fmpz_t x, gr_ctx_t ctx)
378+
int nfloat_complex_set_fmpq(nfloat_complex_ptr res, const fmpq_t x, gr_ctx_t ctx)
379+
int nfloat_complex_set_d(nfloat_complex_ptr res, double x, gr_ctx_t ctx)
380+
int nfloat_complex_neg(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)
381+
int nfloat_complex_add(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)
382+
int nfloat_complex_sub(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)
383+
int _nfloat_complex_sqr_naive(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, gr_ctx_t ctx)
384+
int _nfloat_complex_sqr_standard(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, gr_ctx_t ctx)
385+
int _nfloat_complex_sqr_karatsuba(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, gr_ctx_t ctx)
386+
int _nfloat_complex_sqr(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, gr_ctx_t ctx)
387+
int nfloat_complex_sqr(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)
388+
int _nfloat_complex_mul_naive(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, nfloat_srcptr c, nfloat_srcptr d, gr_ctx_t ctx)
389+
int _nfloat_complex_mul_standard(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, nfloat_srcptr c, nfloat_srcptr d, gr_ctx_t ctx)
390+
int _nfloat_complex_mul_karatsuba(nfloat_ptr res1, nfloat_ptr res2, nfloat_srcptr a, nfloat_srcptr b, nfloat_srcptr c, nfloat_srcptr d, gr_ctx_t ctx)
391+
int nfloat_complex_mul(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)
392+
int nfloat_complex_inv(nfloat_complex_ptr res, nfloat_complex_srcptr x, gr_ctx_t ctx)
393+
int nfloat_complex_div(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, gr_ctx_t ctx)
394+
void _nfloat_complex_vec_init(nfloat_complex_ptr res, slong len, gr_ctx_t ctx)
395+
void _nfloat_complex_vec_clear(nfloat_complex_ptr res, slong len, gr_ctx_t ctx)
396+
int _nfloat_complex_vec_zero(nfloat_complex_ptr res, slong len, gr_ctx_t ctx)
397+
int _nfloat_complex_vec_set(nfloat_complex_ptr res, nfloat_complex_srcptr x, slong len, gr_ctx_t ctx)
398+
int _nfloat_complex_vec_add(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, slong len, gr_ctx_t ctx)
399+
int _nfloat_complex_vec_sub(nfloat_complex_ptr res, nfloat_complex_srcptr x, nfloat_complex_srcptr y, slong len, gr_ctx_t ctx)
400+

src/gr.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ typedef enum
681681
GR_CTX_COMPLEX_EXTENDED_CA,
682682
GR_CTX_RR_ARB, GR_CTX_CC_ACB,
683683
GR_CTX_REAL_FLOAT_ARF, GR_CTX_COMPLEX_FLOAT_ACF,
684-
GR_CTX_NFLOAT,
684+
GR_CTX_NFLOAT, GR_CTX_NFLOAT_COMPLEX,
685685
GR_CTX_FMPZ_POLY, GR_CTX_FMPQ_POLY, GR_CTX_GR_POLY,
686686
GR_CTX_FMPZ_MPOLY, GR_CTX_GR_MPOLY,
687687
GR_CTX_FMPZ_MPOLY_Q,

src/gr/acb.c

+48
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "gr_generic.h"
2828
#include "gr_vec.h"
2929
#include "gr_poly.h"
30+
#include "nfloat.h"
3031

3132
typedef struct
3233
{
@@ -281,6 +282,18 @@ _gr_acb_set_other(acb_t res, gr_srcptr x, gr_ctx_t x_ctx, gr_ctx_t ctx)
281282
return GR_DOMAIN;
282283
}
283284

285+
case GR_CTX_NFLOAT_COMPLEX:
286+
if (NFLOAT_CTX_HAS_INF_NAN(x_ctx)) /* todo */
287+
{
288+
return GR_UNABLE;
289+
}
290+
else
291+
{
292+
nfloat_complex_get_acb(res, x, x_ctx);
293+
acb_set_round(res, res, ACB_CTX_PREC(ctx));
294+
return GR_SUCCESS;
295+
}
296+
284297
case GR_CTX_RR_ARB:
285298
arb_set_round(acb_realref(res), x, ACB_CTX_PREC(ctx));
286299
arb_zero(acb_imagref(res));
@@ -958,6 +971,39 @@ _gr_acb_arg(acb_t res, const acb_t x, const gr_ctx_t ctx)
958971
return GR_SUCCESS;
959972
}
960973

974+
int
975+
_gr_acb_cmp(int * res, const acb_t x, const acb_t y, const gr_ctx_t ctx)
976+
{
977+
if (arb_is_zero(acb_imagref(x)) && arb_is_zero(acb_imagref(y)) &&
978+
((arb_is_exact(acb_realref(x)) && arb_is_exact(acb_realref(y))) || !arb_overlaps(acb_realref(x), acb_realref(y))))
979+
{
980+
*res = arf_cmp(arb_midref(acb_realref(x)), arb_midref(acb_realref(y)));
981+
return GR_SUCCESS;
982+
}
983+
else
984+
{
985+
*res = 0;
986+
return GR_UNABLE;
987+
}
988+
}
989+
990+
int
991+
_gr_acb_cmpabs(int * res, const acb_t x, const acb_t y, const gr_ctx_t ctx)
992+
{
993+
acb_t t, u;
994+
995+
*t = *x;
996+
*u = *y;
997+
998+
if (arf_sgn(arb_midref(acb_realref(t))) < 0)
999+
ARF_NEG(arb_midref(acb_realref(t)));
1000+
1001+
if (arf_sgn(arb_midref(acb_realref(u))) < 0)
1002+
ARF_NEG(arb_midref(acb_realref(u)));
1003+
1004+
return _gr_acb_cmp(res, t, u, ctx);
1005+
}
1006+
9611007
int
9621008
_gr_acb_pi(acb_t res, const gr_ctx_t ctx)
9631009
{
@@ -2172,6 +2218,8 @@ gr_method_tab_input _acb_methods_input[] =
21722218
{GR_METHOD_SGN, (gr_funcptr) _gr_acb_sgn},
21732219
{GR_METHOD_CSGN, (gr_funcptr) _gr_acb_csgn},
21742220
{GR_METHOD_ARG, (gr_funcptr) _gr_acb_arg},
2221+
{GR_METHOD_CMP, (gr_funcptr) _gr_acb_cmp},
2222+
{GR_METHOD_CMPABS, (gr_funcptr) _gr_acb_cmpabs},
21752223
{GR_METHOD_PI, (gr_funcptr) _gr_acb_pi},
21762224
{GR_METHOD_EXP, (gr_funcptr) _gr_acb_exp},
21772225
{GR_METHOD_EXPM1, (gr_funcptr) _gr_acb_expm1},

src/gr/test_ring.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -1369,12 +1369,16 @@ gr_test_zero_one(gr_ctx_t R, flint_rand_t state, int test_flags)
13691369
}
13701370

13711371
status |= gr_randtest(a, state, R);
1372-
status |= gr_one(a, R);
1373-
status |= gr_neg(a, a, R);
1372+
status |= gr_neg_one(a, R);
13741373
equal = gr_is_neg_one(a, R);
13751374
if (status == GR_SUCCESS && equal == T_FALSE)
13761375
status = GR_TEST_FAIL;
13771376

1377+
status |= gr_neg(a, a, R);
1378+
equal = gr_is_one(a, R);
1379+
if (status == GR_SUCCESS && equal == T_FALSE)
1380+
status = GR_TEST_FAIL;
1381+
13781382
if ((test_flags & GR_TEST_ALWAYS_ABLE) && (status & GR_UNABLE))
13791383
status = GR_TEST_FAIL;
13801384

@@ -3939,7 +3943,8 @@ gr_test_floating_point(gr_ctx_t R, slong iters, int test_flags)
39393943
gr_test_iter(R, state, "add: aliasing", gr_test_add_aliasing, iters, test_flags);
39403944
gr_test_iter(R, state, "sub: equal neg add", gr_test_sub_equal_neg_add, iters, test_flags);
39413945
gr_test_iter(R, state, "sub: aliasing", gr_test_sub_aliasing, iters, test_flags);
3942-
gr_test_iter(R, state, "mul: commutative", gr_test_mul_commutative, iters, test_flags);
3946+
/* can fail for complex */
3947+
/* gr_test_iter(R, state, "mul: commutative", gr_test_mul_commutative, iters, test_flags); */
39433948
gr_test_iter(R, state, "mul: aliasing", gr_test_mul_aliasing, iters, test_flags);
39443949
gr_test_iter(R, state, "div: aliasing", gr_test_div_aliasing, iters, test_flags);
39453950
gr_test_iter(R, state, "pow: aliasing", gr_test_pow_aliasing, iters, test_flags);

src/mpn_extras.h

+14
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,20 @@ char * _flint_mpn_get_str(mp_srcptr x, mp_size_t n);
264264
(r0) = __r0; (r1) = __r1; (r2) = __r2; \
265265
} while (0)
266266

267+
#define FLINT_MPN_SQR_2X2(r3, r2, r1, r0, a1, a0) \
268+
do { \
269+
mp_limb_t __t1, __t2, __t3; \
270+
mp_limb_t __r3, __r2, __r1, __r0; \
271+
mp_limb_t __a1 = (a1), __a0 = (a0); \
272+
umul_ppmm(__t2, __t1, __a0, __a1); \
273+
add_sssaaaaaa(__t3, __t2, __t1, 0, __t2, __t1, 0, __t2, __t1); \
274+
umul_ppmm(__r1, __r0, __a0, __a0); \
275+
umul_ppmm(__r3, __r2, __a1, __a1); \
276+
add_sssaaaaaa(__r3, __r2, __r1, __r3, __r2, __r1, __t3, __t2, __t1); \
277+
(r0) = __r0; (r1) = __r1; (r2) = __r2; (r3) = __r3; \
278+
} while (0)
279+
280+
267281
/* {s0,s1,s2} = u[0]v[n-1] + u[1]v[n-2] + ... */
268282
/* Assumes n >= 2 */
269283
#define NN_DOTREV_S3_1X1(s2, s1, s0, u, v, n) \

0 commit comments

Comments
 (0)