From f5d37425f56c011592bb897396c3802ee36bb154 Mon Sep 17 00:00:00 2001 From: Fredrik Johansson Date: Tue, 13 May 2014 20:43:04 +0200 Subject: [PATCH] arb_poly module --- Makefile.in | 2 +- arb_poly.h | 669 +++++++++++++++ arb_poly/acos_series.c | 93 ++ arb_poly/add.c | 58 ++ arb_poly/asin_series.c | 84 ++ arb_poly/atan_series.c | 84 ++ arb_poly/binomial_transform.c | 63 ++ arb_poly/binomial_transform_basecase.c | 85 ++ arb_poly/binomial_transform_convolution.c | 82 ++ arb_poly/borel_transform.c | 57 ++ arb_poly/clear.c | 37 + arb_poly/compose.c | 106 +++ arb_poly/compose_divconquer.c | 196 +++++ arb_poly/compose_horner.c | 125 +++ arb_poly/compose_series.c | 129 +++ arb_poly/compose_series_horner.c | 120 +++ arb_poly/contains.c | 47 + arb_poly/contains_fmpq_poly.c | 56 ++ arb_poly/contains_fmpz_poly.c | 46 + arb_poly/cos_series.c | 80 ++ arb_poly/derivative.c | 52 ++ arb_poly/div_root.c | 60 ++ arb_poly/div_series.c | 80 ++ arb_poly/divrem.c | 137 +++ arb_poly/equal.c | 41 + arb_poly/evaluate.c | 53 ++ arb_poly/evaluate2.c | 52 ++ arb_poly/evaluate2_horner.c | 87 ++ arb_poly/evaluate2_rectangular.c | 117 +++ arb_poly/evaluate_horner.c | 73 ++ arb_poly/evaluate_rectangular.c | 89 ++ arb_poly/evaluate_vec_fast.c | 149 ++++ arb_poly/evaluate_vec_iter.c | 44 + arb_poly/exp_series.c | 188 ++++ arb_poly/exp_series_basecase.c | 114 +++ arb_poly/fit_length.c | 46 + arb_poly/get_coeff_fmprb.c | 36 + arb_poly/init.c | 41 + arb_poly/integral.c | 46 + arb_poly/interpolate_barycentric.c | 96 +++ arb_poly/interpolate_fast.c | 141 +++ arb_poly/interpolate_newton.c | 119 +++ arb_poly/inv_borel_transform.c | 57 ++ arb_poly/inv_series.c | 92 ++ arb_poly/log_series.c | 103 +++ arb_poly/mul.c | 67 ++ arb_poly/mullow.c | 83 ++ arb_poly/mullow_block.c | 803 ++++++++++++++++++ arb_poly/mullow_classical.c | 111 +++ arb_poly/newton_convergence_factor.c | 55 ++ arb_poly/newton_refine_root.c | 77 ++ arb_poly/newton_step.c | 76 ++ arb_poly/normalise.c | 37 + arb_poly/overlaps.c | 56 ++ arb_poly/pow_fmprb_series.c | 175 ++++ arb_poly/pow_series.c | 120 +++ arb_poly/pow_ui.c | 75 ++ arb_poly/pow_ui_trunc_binexp.c | 167 ++++ arb_poly/printd.c | 46 + arb_poly/product_roots.c | 69 ++ arb_poly/randtest.c | 45 + arb_poly/reverse.c | 55 ++ arb_poly/revert_series.c | 66 ++ arb_poly/revert_series_lagrange.c | 97 +++ arb_poly/revert_series_lagrange_fast.c | 122 +++ arb_poly/revert_series_newton.c | 106 +++ arb_poly/rsqrt_series.c | 98 +++ arb_poly/set.c | 36 + arb_poly/set_coeff_fmprb.c | 42 + arb_poly/set_coeff_si.c | 42 + arb_poly/set_fmpq_poly.c | 45 + arb_poly/set_fmpz_poly.c | 38 + arb_poly/set_length.c | 40 + arb_poly/set_si.c | 42 + arb_poly/shift_left.c | 70 ++ arb_poly/shift_right.c | 68 ++ arb_poly/sin_cos_series.c | 89 ++ arb_poly/sin_cos_series_basecase.c | 100 +++ arb_poly/sin_cos_series_tangent.c | 127 +++ arb_poly/sin_series.c | 73 ++ arb_poly/sqrt_series.c | 83 ++ arb_poly/sub.c | 58 ++ arb_poly/tan_series.c | 103 +++ arb_poly/test/t-acos_series.c | 101 +++ arb_poly/test/t-add.c | 96 +++ arb_poly/test/t-asin_series.c | 101 +++ arb_poly/test/t-atan_series.c | 114 +++ arb_poly/test/t-binomial_transform.c | 119 +++ arb_poly/test/t-binomial_transform_basecase.c | 119 +++ .../test/t-binomial_transform_convolution.c | 119 +++ arb_poly/test/t-borel_transform.c | 91 ++ arb_poly/test/t-compose.c | 116 +++ arb_poly/test/t-compose_divconquer.c | 114 +++ arb_poly/test/t-compose_horner.c | 114 +++ arb_poly/test/t-compose_series.c | 118 +++ arb_poly/test/t-compose_series_horner.c | 116 +++ arb_poly/test/t-div_series.c | 128 +++ arb_poly/test/t-divrem.c | 136 +++ arb_poly/test/t-evaluate.c | 104 +++ arb_poly/test/t-evaluate2.c | 87 ++ arb_poly/test/t-evaluate2_horner.c | 87 ++ arb_poly/test/t-evaluate2_rectangular.c | 87 ++ arb_poly/test/t-evaluate_horner.c | 104 +++ arb_poly/test/t-evaluate_rectangular.c | 75 ++ arb_poly/test/t-evaluate_vec_fast.c | 104 +++ arb_poly/test/t-evaluate_vec_iter.c | 104 +++ arb_poly/test/t-exp_series.c | 219 +++++ arb_poly/test/t-exp_series_basecase.c | 199 +++++ arb_poly/test/t-get_coeff_ptr.c | 73 ++ arb_poly/test/t-get_set_coeff_fmprb.c | 79 ++ arb_poly/test/t-interpolate_barycentric.c | 107 +++ arb_poly/test/t-interpolate_fast.c | 107 +++ arb_poly/test/t-interpolate_newton.c | 107 +++ arb_poly/test/t-inv_series.c | 100 +++ arb_poly/test/t-log_series.c | 190 +++++ arb_poly/test/t-mul.c | 141 +++ arb_poly/test/t-mullow.c | 144 ++++ arb_poly/test/t-mullow_block.c | 223 +++++ arb_poly/test/t-mullow_classical.c | 144 ++++ arb_poly/test/t-pow_fmprb_series.c | 115 +++ arb_poly/test/t-pow_series.c | 117 +++ arb_poly/test/t-pow_ui.c | 96 +++ arb_poly/test/t-pow_ui_trunc_binexp.c | 98 +++ arb_poly/test/t-revert_series.c | 101 +++ arb_poly/test/t-revert_series_lagrange.c | 101 +++ arb_poly/test/t-revert_series_lagrange_fast.c | 101 +++ arb_poly/test/t-revert_series_newton.c | 101 +++ arb_poly/test/t-rsqrt_series.c | 99 +++ arb_poly/test/t-shift_left_right.c | 126 +++ arb_poly/test/t-sin_cos_series.c | 114 +++ arb_poly/test/t-sin_cos_series_basecase.c | 114 +++ arb_poly/test/t-sin_cos_series_tangent.c | 114 +++ arb_poly/test/t-sin_series_cos_series.c | 115 +++ arb_poly/test/t-sqrt_series.c | 96 +++ arb_poly/test/t-sub.c | 96 +++ arb_poly/test/t-tan_series.c | 106 +++ arb_poly/tree.c | 121 +++ mag.h | 4 + mag/set_d_2exp_fmpz.c | 53 ++ mag/set_fmpr.c | 16 +- mag/set_fmpz_2exp_fmpz.c | 44 + mag/test/t-set_d_2exp_fmpz.c | 123 +++ 142 files changed, 14446 insertions(+), 6 deletions(-) create mode 100644 arb_poly.h create mode 100644 arb_poly/acos_series.c create mode 100644 arb_poly/add.c create mode 100644 arb_poly/asin_series.c create mode 100644 arb_poly/atan_series.c create mode 100644 arb_poly/binomial_transform.c create mode 100644 arb_poly/binomial_transform_basecase.c create mode 100644 arb_poly/binomial_transform_convolution.c create mode 100644 arb_poly/borel_transform.c create mode 100644 arb_poly/clear.c create mode 100644 arb_poly/compose.c create mode 100644 arb_poly/compose_divconquer.c create mode 100644 arb_poly/compose_horner.c create mode 100644 arb_poly/compose_series.c create mode 100644 arb_poly/compose_series_horner.c create mode 100644 arb_poly/contains.c create mode 100644 arb_poly/contains_fmpq_poly.c create mode 100644 arb_poly/contains_fmpz_poly.c create mode 100644 arb_poly/cos_series.c create mode 100644 arb_poly/derivative.c create mode 100644 arb_poly/div_root.c create mode 100644 arb_poly/div_series.c create mode 100644 arb_poly/divrem.c create mode 100644 arb_poly/equal.c create mode 100644 arb_poly/evaluate.c create mode 100644 arb_poly/evaluate2.c create mode 100644 arb_poly/evaluate2_horner.c create mode 100644 arb_poly/evaluate2_rectangular.c create mode 100644 arb_poly/evaluate_horner.c create mode 100644 arb_poly/evaluate_rectangular.c create mode 100644 arb_poly/evaluate_vec_fast.c create mode 100644 arb_poly/evaluate_vec_iter.c create mode 100644 arb_poly/exp_series.c create mode 100644 arb_poly/exp_series_basecase.c create mode 100644 arb_poly/fit_length.c create mode 100644 arb_poly/get_coeff_fmprb.c create mode 100644 arb_poly/init.c create mode 100644 arb_poly/integral.c create mode 100644 arb_poly/interpolate_barycentric.c create mode 100644 arb_poly/interpolate_fast.c create mode 100644 arb_poly/interpolate_newton.c create mode 100644 arb_poly/inv_borel_transform.c create mode 100644 arb_poly/inv_series.c create mode 100644 arb_poly/log_series.c create mode 100644 arb_poly/mul.c create mode 100644 arb_poly/mullow.c create mode 100644 arb_poly/mullow_block.c create mode 100644 arb_poly/mullow_classical.c create mode 100644 arb_poly/newton_convergence_factor.c create mode 100644 arb_poly/newton_refine_root.c create mode 100644 arb_poly/newton_step.c create mode 100644 arb_poly/normalise.c create mode 100644 arb_poly/overlaps.c create mode 100644 arb_poly/pow_fmprb_series.c create mode 100644 arb_poly/pow_series.c create mode 100644 arb_poly/pow_ui.c create mode 100644 arb_poly/pow_ui_trunc_binexp.c create mode 100644 arb_poly/printd.c create mode 100644 arb_poly/product_roots.c create mode 100644 arb_poly/randtest.c create mode 100644 arb_poly/reverse.c create mode 100644 arb_poly/revert_series.c create mode 100644 arb_poly/revert_series_lagrange.c create mode 100644 arb_poly/revert_series_lagrange_fast.c create mode 100644 arb_poly/revert_series_newton.c create mode 100644 arb_poly/rsqrt_series.c create mode 100644 arb_poly/set.c create mode 100644 arb_poly/set_coeff_fmprb.c create mode 100644 arb_poly/set_coeff_si.c create mode 100644 arb_poly/set_fmpq_poly.c create mode 100644 arb_poly/set_fmpz_poly.c create mode 100644 arb_poly/set_length.c create mode 100644 arb_poly/set_si.c create mode 100644 arb_poly/shift_left.c create mode 100644 arb_poly/shift_right.c create mode 100644 arb_poly/sin_cos_series.c create mode 100644 arb_poly/sin_cos_series_basecase.c create mode 100644 arb_poly/sin_cos_series_tangent.c create mode 100644 arb_poly/sin_series.c create mode 100644 arb_poly/sqrt_series.c create mode 100644 arb_poly/sub.c create mode 100644 arb_poly/tan_series.c create mode 100644 arb_poly/test/t-acos_series.c create mode 100644 arb_poly/test/t-add.c create mode 100644 arb_poly/test/t-asin_series.c create mode 100644 arb_poly/test/t-atan_series.c create mode 100644 arb_poly/test/t-binomial_transform.c create mode 100644 arb_poly/test/t-binomial_transform_basecase.c create mode 100644 arb_poly/test/t-binomial_transform_convolution.c create mode 100644 arb_poly/test/t-borel_transform.c create mode 100644 arb_poly/test/t-compose.c create mode 100644 arb_poly/test/t-compose_divconquer.c create mode 100644 arb_poly/test/t-compose_horner.c create mode 100644 arb_poly/test/t-compose_series.c create mode 100644 arb_poly/test/t-compose_series_horner.c create mode 100644 arb_poly/test/t-div_series.c create mode 100644 arb_poly/test/t-divrem.c create mode 100644 arb_poly/test/t-evaluate.c create mode 100644 arb_poly/test/t-evaluate2.c create mode 100644 arb_poly/test/t-evaluate2_horner.c create mode 100644 arb_poly/test/t-evaluate2_rectangular.c create mode 100644 arb_poly/test/t-evaluate_horner.c create mode 100644 arb_poly/test/t-evaluate_rectangular.c create mode 100644 arb_poly/test/t-evaluate_vec_fast.c create mode 100644 arb_poly/test/t-evaluate_vec_iter.c create mode 100644 arb_poly/test/t-exp_series.c create mode 100644 arb_poly/test/t-exp_series_basecase.c create mode 100644 arb_poly/test/t-get_coeff_ptr.c create mode 100644 arb_poly/test/t-get_set_coeff_fmprb.c create mode 100644 arb_poly/test/t-interpolate_barycentric.c create mode 100644 arb_poly/test/t-interpolate_fast.c create mode 100644 arb_poly/test/t-interpolate_newton.c create mode 100644 arb_poly/test/t-inv_series.c create mode 100644 arb_poly/test/t-log_series.c create mode 100644 arb_poly/test/t-mul.c create mode 100644 arb_poly/test/t-mullow.c create mode 100644 arb_poly/test/t-mullow_block.c create mode 100644 arb_poly/test/t-mullow_classical.c create mode 100644 arb_poly/test/t-pow_fmprb_series.c create mode 100644 arb_poly/test/t-pow_series.c create mode 100644 arb_poly/test/t-pow_ui.c create mode 100644 arb_poly/test/t-pow_ui_trunc_binexp.c create mode 100644 arb_poly/test/t-revert_series.c create mode 100644 arb_poly/test/t-revert_series_lagrange.c create mode 100644 arb_poly/test/t-revert_series_lagrange_fast.c create mode 100644 arb_poly/test/t-revert_series_newton.c create mode 100644 arb_poly/test/t-rsqrt_series.c create mode 100644 arb_poly/test/t-shift_left_right.c create mode 100644 arb_poly/test/t-sin_cos_series.c create mode 100644 arb_poly/test/t-sin_cos_series_basecase.c create mode 100644 arb_poly/test/t-sin_cos_series_tangent.c create mode 100644 arb_poly/test/t-sin_series_cos_series.c create mode 100644 arb_poly/test/t-sqrt_series.c create mode 100644 arb_poly/test/t-sub.c create mode 100644 arb_poly/test/t-tan_series.c create mode 100644 arb_poly/tree.c create mode 100644 mag/set_d_2exp_fmpz.c create mode 100644 mag/set_fmpz_2exp_fmpz.c create mode 100644 mag/test/t-set_d_2exp_fmpz.c diff --git a/Makefile.in b/Makefile.in index cfc2e6cf6..612a278b5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -102,5 +102,5 @@ build/%.lo: %.c build/%.o: %.c $(CC) -fPIC $(CFLAGS) $(INCS) -c $< -o $@ -BUILD_DIRS = fmpr arf mag arb fmprb fmprb_poly fmprb_mat fmprb_calc fmpcb fmpcb_poly fmpcb_mat fmpcb_calc elefun bernoulli hypgeom gamma zeta fmpz_extras partitions +BUILD_DIRS = fmpr arf mag arb arb_poly fmprb fmprb_poly fmprb_mat fmprb_calc fmpcb fmpcb_poly fmpcb_mat fmpcb_calc elefun bernoulli hypgeom gamma zeta fmpz_extras partitions diff --git a/arb_poly.h b/arb_poly.h new file mode 100644 index 000000000..842928426 --- /dev/null +++ b/arb_poly.h @@ -0,0 +1,669 @@ +/*============================================================================= + + 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 + +******************************************************************************/ + +#ifndef ARB_POLY_H +#define ARB_POLY_H + +#include "arb.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + arb_ptr coeffs; + long length; + long alloc; +} +arb_poly_struct; + +typedef arb_poly_struct arb_poly_t[1]; + + +/* Memory management */ + +void arb_poly_init(arb_poly_t poly); + +void arb_poly_init2(arb_poly_t poly, long len); + +void arb_poly_clear(arb_poly_t poly); + +void arb_poly_fit_length(arb_poly_t poly, long len); + +void _arb_poly_set_length(arb_poly_t poly, long len); + +void _arb_poly_normalise(arb_poly_t poly); + +static __inline__ void +arb_poly_swap(arb_poly_t poly1, arb_poly_t poly2) +{ + arb_poly_struct t = *poly1; + *poly1 = *poly2; + *poly2 = t; +} + +void arb_poly_set(arb_poly_t poly, const arb_poly_t src); + +/* Basic manipulation */ + +static __inline__ long arb_poly_length(const arb_poly_t poly) +{ + return poly->length; +} + +static __inline__ long arb_poly_degree(const arb_poly_t poly) +{ + return poly->length - 1; +} + +static __inline__ void arb_poly_zero(arb_poly_t poly) +{ + poly->length = 0; +} + +static __inline__ void +arb_poly_one(arb_poly_t poly) +{ + arb_poly_fit_length(poly, 1); + arb_one(poly->coeffs); + _arb_poly_set_length(poly, 1); +} + +void arb_poly_set_coeff_si(arb_poly_t poly, long n, long x); + +void arb_poly_set_coeff_arb(arb_poly_t poly, long n, const arb_t x); + +void arb_poly_get_coeff_arb(arb_t x, const arb_poly_t poly, long n); + +#define arb_poly_get_coeff_ptr(poly, n) \ + ((n) < (poly)->length ? (poly)->coeffs + (n) : NULL) + +void _arb_poly_reverse(arb_ptr res, arb_srcptr poly, long len, long n); + +void _arb_poly_shift_right(arb_ptr res, arb_srcptr poly, long len, long n); + +void arb_poly_shift_right(arb_poly_t res, const arb_poly_t poly, long n); + +void _arb_poly_shift_left(arb_ptr res, arb_srcptr poly, long len, long n); + +void arb_poly_shift_left(arb_poly_t res, const arb_poly_t poly, long n); + +static __inline__ void +arb_poly_truncate(arb_poly_t poly, long newlen) +{ + if (poly->length > newlen) + { + long i; + for (i = newlen; i < poly->length; i++) + arb_zero(poly->coeffs + i); + poly->length = newlen; + _arb_poly_normalise(poly); + } +} + +/* Conversions */ + +void arb_poly_set_fmpz_poly(arb_poly_t poly, const fmpz_poly_t src, long prec); + +void arb_poly_set_fmpq_poly(arb_poly_t poly, const fmpq_poly_t src, long prec); + +static __inline__ void +arb_poly_set_arb(arb_poly_t poly, const arb_t c) +{ + arb_poly_fit_length(poly, 1); + arb_set(poly->coeffs, c); + _arb_poly_set_length(poly, !arb_is_zero(poly->coeffs)); +} + +void arb_poly_set_si(arb_poly_t poly, long c); + +/* Comparisons */ + +int arb_poly_contains(const arb_poly_t poly1, const arb_poly_t poly2); + +int arb_poly_contains_fmpz_poly(const arb_poly_t poly1, const fmpz_poly_t poly2); + +int arb_poly_contains_fmpq_poly(const arb_poly_t poly1, const fmpq_poly_t poly2); + +int arb_poly_equal(const arb_poly_t A, const arb_poly_t B); + +int _arb_poly_overlaps(arb_srcptr poly1, long len1, arb_srcptr poly2, long len2); + +int arb_poly_overlaps(const arb_poly_t poly1, const arb_poly_t poly2); + +/* IO */ + +void arb_poly_printd(const arb_poly_t poly, long digits); + +/* Random generation */ + +void arb_poly_randtest(arb_poly_t poly, flint_rand_t state, long len, long prec, long mag_bits); + +/* Arithmetic */ + +void +_arb_poly_add(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec); + +void arb_poly_add(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long prec); + +void _arb_poly_sub(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec); + +void arb_poly_sub(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long prec); + +static __inline__ void +arb_poly_neg(arb_poly_t res, const arb_poly_t poly) +{ + arb_poly_fit_length(res, poly->length); + _arb_vec_neg(res->coeffs, poly->coeffs, poly->length); + _arb_poly_set_length(res, poly->length); +} + +static __inline__ void +arb_poly_scalar_mul_2exp_si(arb_poly_t res, const arb_poly_t poly, long c) +{ + arb_poly_fit_length(res, poly->length); + _arb_vec_scalar_mul_2exp_si(res->coeffs, poly->coeffs, poly->length, c); + _arb_poly_set_length(res, poly->length); +} + +void _arb_poly_mullow_ztrunc(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec); + +void arb_poly_mullow_ztrunc(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, + long n, long prec); + +void _arb_poly_mullow_classical(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec); + +void arb_poly_mullow_classical(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, + long n, long prec); + +void _arb_poly_mullow_block(arb_ptr C, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long n, long prec); + +void arb_poly_mullow_block(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long len, long prec); + +void _arb_poly_mullow(arb_ptr C, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long n, long prec); + +void arb_poly_mullow(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long len, long prec); + +void _arb_poly_mul(arb_ptr C, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long prec); + +void arb_poly_mul(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long prec); + +static __inline__ void +_arb_poly_mul_monic(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec) +{ + if (len1 + len2 - 2 > 0) + _arb_poly_mullow(res, poly1, len1, poly2, len2, len1 + len2 - 2, prec); + arb_one(res + len1 + len2 - 2); +} + +void _arb_poly_inv_series(arb_ptr Qinv, + arb_srcptr Q, long Qlen, long len, long prec); + +void arb_poly_inv_series(arb_poly_t Qinv, const arb_poly_t Q, long n, long prec); + +void _arb_poly_div_series(arb_ptr Q, arb_srcptr A, long Alen, + arb_srcptr B, long Blen, long n, long prec); + +void arb_poly_div_series(arb_poly_t Q, const arb_poly_t A, const arb_poly_t B, long n, long prec); + +void +_arb_poly_div(arb_ptr Q, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long prec); + +void _arb_poly_divrem(arb_ptr Q, arb_ptr R, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long prec); + +void _arb_poly_rem(arb_ptr R, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long prec); + +void arb_poly_divrem(arb_poly_t Q, arb_poly_t R, + const arb_poly_t A, const arb_poly_t B, long prec); + +void _arb_poly_div_root(arb_ptr Q, arb_t R, arb_srcptr A, + long len, const arb_t c, long prec); + +/* Product trees */ + +void _arb_poly_product_roots(arb_ptr poly, arb_srcptr xs, long n, long prec); + +void arb_poly_product_roots(arb_poly_t poly, arb_srcptr xs, long n, long prec); + +arb_ptr * _arb_poly_tree_alloc(long len); + +void _arb_poly_tree_free(arb_ptr * tree, long len); + +void _arb_poly_tree_build(arb_ptr * tree, arb_srcptr roots, long len, long prec); + +/* Composition */ + +void _arb_poly_compose(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec); + +void arb_poly_compose(arb_poly_t res, + const arb_poly_t poly1, const arb_poly_t poly2, long prec); + +void _arb_poly_compose_horner(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec); + +void arb_poly_compose_horner(arb_poly_t res, + const arb_poly_t poly1, const arb_poly_t poly2, long prec); + +void _arb_poly_compose_divconquer(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec); + +void arb_poly_compose_divconquer(arb_poly_t res, + const arb_poly_t poly1, const arb_poly_t poly2, long prec); + +void _arb_poly_compose_series_horner(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec); + +void arb_poly_compose_series_horner(arb_poly_t res, + const arb_poly_t poly1, + const arb_poly_t poly2, long n, long prec); + +void _arb_poly_compose_series(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec); + +void arb_poly_compose_series(arb_poly_t res, + const arb_poly_t poly1, + const arb_poly_t poly2, long n, long prec); + +/* Reversion */ + +void _arb_poly_revert_series_lagrange(arb_ptr Qinv, arb_srcptr Q, long Qlen, long n, long prec); +void arb_poly_revert_series_lagrange(arb_poly_t Qinv, const arb_poly_t Q, long n, long prec); + +void _arb_poly_revert_series_newton(arb_ptr Qinv, arb_srcptr Q, long Qlen, long n, long prec); +void arb_poly_revert_series_newton(arb_poly_t Qinv, const arb_poly_t Q, long n, long prec); + +void _arb_poly_revert_series_lagrange_fast(arb_ptr Qinv, arb_srcptr Q, long Qlen, long n, long prec); +void arb_poly_revert_series_lagrange_fast(arb_poly_t Qinv, const arb_poly_t Q, long n, long prec); + +void _arb_poly_revert_series(arb_ptr Qinv, arb_srcptr Q, long Qlen, long n, long prec); +void arb_poly_revert_series(arb_poly_t Qinv, const arb_poly_t Q, long n, long prec); + +/* Evaluation and interpolation */ + +void _arb_poly_evaluate_horner(arb_t res, arb_srcptr f, long len, const arb_t a, long prec); +void arb_poly_evaluate_horner(arb_t res, const arb_poly_t f, const arb_t a, long prec); + +void _arb_poly_evaluate_rectangular(arb_t y, arb_srcptr poly, long len, const arb_t x, long prec); +void arb_poly_evaluate_rectangular(arb_t res, const arb_poly_t f, const arb_t a, long prec); + +void _arb_poly_evaluate(arb_t res, arb_srcptr f, long len, const arb_t a, long prec); +void arb_poly_evaluate(arb_t res, const arb_poly_t f, const arb_t a, long prec); + +void _arb_poly_evaluate2_horner(arb_t y, arb_t z, arb_srcptr f, long len, const arb_t x, long prec); +void arb_poly_evaluate2_horner(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, long prec); + +void _arb_poly_evaluate2_rectangular(arb_t y, arb_t z, arb_srcptr f, long len, const arb_t x, long prec); +void arb_poly_evaluate2_rectangular(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, long prec); + +void _arb_poly_evaluate2(arb_t y, arb_t z, arb_srcptr f, long len, const arb_t x, long prec); +void arb_poly_evaluate2(arb_t y, arb_t z, const arb_poly_t f, const arb_t x, long prec); + + + + +void _arb_poly_evaluate_vec_iter(arb_ptr ys, arb_srcptr poly, long plen, + arb_srcptr xs, long n, long prec); + +void arb_poly_evaluate_vec_iter(arb_ptr ys, + const arb_poly_t poly, arb_srcptr xs, long n, long prec); + +void _arb_poly_evaluate_vec_fast_precomp(arb_ptr vs, arb_srcptr poly, + long plen, arb_ptr * tree, long len, long prec); + +void _arb_poly_evaluate_vec_fast(arb_ptr ys, arb_srcptr poly, long plen, + arb_srcptr xs, long n, long prec); + +void arb_poly_evaluate_vec_fast(arb_ptr ys, + const arb_poly_t poly, arb_srcptr xs, long n, long prec); + +void _arb_poly_interpolate_newton(arb_ptr poly, arb_srcptr xs, + arb_srcptr ys, long n, long prec); + +void arb_poly_interpolate_newton(arb_poly_t poly, + arb_srcptr xs, arb_srcptr ys, long n, long prec); + +void +_arb_poly_interpolate_barycentric(arb_ptr poly, + arb_srcptr xs, arb_srcptr ys, long n, long prec); + +void arb_poly_interpolate_barycentric(arb_poly_t poly, + arb_srcptr xs, arb_srcptr ys, long n, long prec); + +void _arb_poly_interpolation_weights(arb_ptr w, + arb_ptr * tree, long len, long prec); + +void _arb_poly_interpolate_fast_precomp(arb_ptr poly, + arb_srcptr ys, arb_ptr * tree, arb_srcptr weights, + long len, long prec); + +void _arb_poly_interpolate_fast(arb_ptr poly, + arb_srcptr xs, arb_srcptr ys, long len, long prec); + +void arb_poly_interpolate_fast(arb_poly_t poly, + arb_srcptr xs, arb_srcptr ys, long n, long prec); + +/* Derivative and integral */ + +void _arb_poly_derivative(arb_ptr res, arb_srcptr poly, long len, long prec); + +void arb_poly_derivative(arb_poly_t res, const arb_poly_t poly, long prec); + +void _arb_poly_integral(arb_ptr res, arb_srcptr poly, long len, long prec); + +void arb_poly_integral(arb_poly_t res, const arb_poly_t poly, long prec); + +/* Transforms */ + +void arb_poly_borel_transform(arb_poly_t res, const arb_poly_t poly, long prec); + +void _arb_poly_borel_transform(arb_ptr res, arb_srcptr poly, long len, long prec); + +void arb_poly_inv_borel_transform(arb_poly_t res, const arb_poly_t poly, long prec); + +void _arb_poly_inv_borel_transform(arb_ptr res, arb_srcptr poly, long len, long prec); + +void _arb_poly_binomial_transform_basecase(arb_ptr b, arb_srcptr a, long alen, long len, long prec); + +void arb_poly_binomial_transform_basecase(arb_poly_t b, const arb_poly_t a, long len, long prec); + +void _arb_poly_binomial_transform_convolution(arb_ptr b, arb_srcptr a, long alen, long len, long prec); + +void arb_poly_binomial_transform_convolution(arb_poly_t b, const arb_poly_t a, long len, long prec); + +void _arb_poly_binomial_transform(arb_ptr b, arb_srcptr a, long alen, long len, long prec); + +void arb_poly_binomial_transform(arb_poly_t b, const arb_poly_t a, long len, long prec); + +/* Special functions */ + +void _arb_poly_pow_ui_trunc_binexp(arb_ptr res, + arb_srcptr f, long flen, ulong exp, long len, long prec); + +void arb_poly_pow_ui_trunc_binexp(arb_poly_t res, + const arb_poly_t poly, ulong exp, long len, long prec); + +void _arb_poly_pow_ui(arb_ptr res, arb_srcptr f, long flen, ulong exp, long prec); + +void arb_poly_pow_ui(arb_poly_t res, const arb_poly_t poly, ulong exp, long prec); + +void _arb_poly_pow_series(arb_ptr h, + arb_srcptr f, long flen, + arb_srcptr g, long glen, long len, long prec); + +void arb_poly_pow_series(arb_poly_t h, + const arb_poly_t f, const arb_poly_t g, long len, long prec); + +void _arb_poly_pow_arb_series(arb_ptr h, + arb_srcptr f, long flen, const arb_t g, long len, long prec); + +void arb_poly_pow_arb_series(arb_poly_t h, + const arb_poly_t f, const arb_t g, long len, long prec); + +void _arb_poly_rsqrt_series(arb_ptr g, + arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_rsqrt_series(arb_poly_t g, const arb_poly_t h, long n, long prec); + +void _arb_poly_sqrt_series(arb_ptr g, + arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_sqrt_series(arb_poly_t g, const arb_poly_t h, long n, long prec); + +void _arb_poly_log_series(arb_ptr res, arb_srcptr f, long flen, long n, long prec); + +void arb_poly_log_series(arb_poly_t res, const arb_poly_t f, long n, long prec); + +void _arb_poly_atan_series(arb_ptr res, arb_srcptr f, long flen, long n, long prec); + +void arb_poly_atan_series(arb_poly_t res, const arb_poly_t f, long n, long prec); + +void _arb_poly_asin_series(arb_ptr res, arb_srcptr f, long flen, long n, long prec); + +void arb_poly_asin_series(arb_poly_t res, const arb_poly_t f, long n, long prec); + +void _arb_poly_acos_series(arb_ptr res, arb_srcptr f, long flen, long n, long prec); + +void arb_poly_acos_series(arb_poly_t res, const arb_poly_t f, long n, long prec); + +void _arb_poly_exp_series_basecase(arb_ptr f, + arb_srcptr h, long hlen, long n, long prec); + +void arb_poly_exp_series_basecase(arb_poly_t f, const arb_poly_t h, long n, long prec); + +void _arb_poly_exp_series(arb_ptr f, arb_srcptr h, long hlen, long n, long prec); + +void arb_poly_exp_series(arb_poly_t f, const arb_poly_t h, long n, long prec); + +void _arb_poly_sin_cos_series_basecase(arb_ptr s, + arb_ptr c, arb_srcptr h, long hlen, long n, long prec); + +void arb_poly_sin_cos_series_basecase(arb_poly_t s, arb_poly_t c, + const arb_poly_t h, long n, long prec); + +void _arb_poly_sin_cos_series_tangent(arb_ptr s, arb_ptr c, + const arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_sin_cos_series_tangent(arb_poly_t s, arb_poly_t c, + const arb_poly_t h, long n, long prec); + +void _arb_poly_sin_cos_series(arb_ptr s, arb_ptr c, + const arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_sin_cos_series(arb_poly_t s, arb_poly_t c, + const arb_poly_t h, long n, long prec); + +void _arb_poly_sin_series(arb_ptr g, arb_srcptr h, long hlen, long n, long prec); + +void arb_poly_sin_series(arb_poly_t g, const arb_poly_t h, long n, long prec); + +void _arb_poly_cos_series(arb_ptr g, arb_srcptr h, long hlen, long n, long prec); + +void arb_poly_cos_series(arb_poly_t g, const arb_poly_t h, long n, long prec); + +void _arb_poly_tan_series(arb_ptr g, arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_tan_series(arb_poly_t g, const arb_poly_t h, long n, long prec); + +/* +TBD: + +must also update compose(): + +void _arb_poly_compose_series_brent_kung(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec); + +void arb_poly_compose_series_brent_kung(arb_poly_t res, + const arb_poly_t poly1, + const arb_poly_t poly2, long n, long prec); + + +void _arb_poly_evaluate_fmpcb_horner(fmpcb_t res, arb_srcptr f, long len, const fmpcb_t x, long prec); +void arb_poly_evaluate_fmpcb_horner(fmpcb_t res, const arb_poly_t f, const fmpcb_t a, long prec); + +void _arb_poly_evaluate_fmpcb_rectangular(fmpcb_t y, arb_srcptr poly, long len, const fmpcb_t x, long prec); +void arb_poly_evaluate_fmpcb_rectangular(fmpcb_t res, const arb_poly_t f, const fmpcb_t a, long prec); + +void _arb_poly_evaluate_fmpcb(fmpcb_t res, arb_srcptr f, long len, const fmpcb_t x, long prec); +void arb_poly_evaluate_fmpcb(fmpcb_t res, const arb_poly_t f, const fmpcb_t a, long prec); + +void _arb_poly_evaluate2_fmpcb_horner(fmpcb_t y, fmpcb_t z, arb_srcptr f, long len, const fmpcb_t x, long prec); +void arb_poly_evaluate2_fmpcb_horner(fmpcb_t y, fmpcb_t z, const arb_poly_t f, const fmpcb_t x, long prec); + +void _arb_poly_evaluate2_fmpcb_rectangular(fmpcb_t y, fmpcb_t z, arb_srcptr f, long len, const fmpcb_t x, long prec); +void arb_poly_evaluate2_fmpcb_rectangular(fmpcb_t y, fmpcb_t z, const arb_poly_t f, const fmpcb_t x, long prec); + +void _arb_poly_evaluate2_fmpcb(fmpcb_t y, fmpcb_t z, arb_srcptr f, long len, const fmpcb_t x, long prec); +void arb_poly_evaluate2_fmpcb(fmpcb_t y, fmpcb_t z, const arb_poly_t f, const fmpcb_t x, long prec); + + + +void _arb_poly_gamma_series(arb_ptr res, arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_gamma_series(arb_poly_t res, const arb_poly_t f, long n, long prec); + +void _arb_poly_rgamma_series(arb_ptr res, arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_rgamma_series(arb_poly_t res, const arb_poly_t f, long n, long prec); + +void _arb_poly_lgamma_series(arb_ptr res, arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_lgamma_series(arb_poly_t res, const arb_poly_t f, long n, long prec); + +void _arb_poly_rising_ui_series(arb_ptr res, arb_srcptr f, long flen, ulong r, long trunc, long prec); + +void arb_poly_rising_ui_series(arb_poly_t res, const arb_poly_t f, ulong r, long trunc, long prec); + +void _arb_poly_zeta_series(arb_ptr res, arb_srcptr h, long hlen, const arb_t a, int deflate, long len, long prec); + +void arb_poly_zeta_series(arb_poly_t res, const arb_poly_t f, const arb_t a, int deflate, long n, long prec); + +void _arb_poly_riemann_siegel_theta_series(arb_ptr res, arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_riemann_siegel_theta_series(arb_poly_t res, const arb_poly_t h, long n, long prec); + +void _arb_poly_riemann_siegel_z_series(arb_ptr res, arb_srcptr h, long hlen, long len, long prec); + +void arb_poly_riemann_siegel_z_series(arb_poly_t res, const arb_poly_t h, long n, long prec); +*/ + +/* Root-finding */ + +void _arb_poly_newton_convergence_factor(arf_t convergence_factor, + arb_srcptr poly, long len, + const arb_t convergence_interval, long prec); + +int _arb_poly_newton_step(arb_t xnew, arb_srcptr poly, long len, + const arb_t x, + const arb_t convergence_interval, + const arf_t convergence_factor, long prec); + +void _arb_poly_newton_refine_root(arb_t r, arb_srcptr poly, + long len, const arb_t start, + const arb_t convergence_interval, + const arf_t convergence_factor, + long eval_extra_prec, + long prec); + +/* Macros */ + + +/* FIXME: redefinition */ +#include "fmprb_poly.h" + + +/* counts zero bits in the binary representation of e */ +/* +static __inline__ int +n_zerobits(mp_limb_t e) +{ + int zeros = 0; + + while (e > 1) + { + zeros += !(e & 1); + e >>= 1; + } + + return zeros; +} + +static __inline__ long +poly_pow_length(long poly_len, ulong exp, long trunc) +{ + mp_limb_t hi, lo; + umul_ppmm(hi, lo, poly_len - 1, exp); + add_ssaaaa(hi, lo, hi, lo, 0, 1); + if (hi != 0 || lo > (mp_limb_t) LONG_MAX) + return trunc; + return FLINT_MIN(lo, trunc); +} +*/ + +#ifndef NEWTON_INIT + +#define NEWTON_INIT(from, to) \ + { \ + long __steps[FLINT_BITS], __i, __from, __to; \ + __steps[__i = 0] = __to = (to); \ + __from = (from); \ + while (__to > __from) \ + __steps[++__i] = (__to = (__to + 1) / 2); \ + +#define NEWTON_BASECASE(bc_to) { long bc_to = __to; + +#define NEWTON_END_BASECASE } + +#define NEWTON_LOOP(step_from, step_to) \ + { \ + for (__i--; __i >= 0; __i--) \ + { \ + long step_from = __steps[__i+1]; \ + long step_to = __steps[__i]; \ + +#define NEWTON_END_LOOP }} + +#define NEWTON_END } + +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/arb_poly/acos_series.c b/arb_poly/acos_series.c new file mode 100644 index 000000000..58e07f6e1 --- /dev/null +++ b/arb_poly/acos_series.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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_acos_series(arb_ptr g, arb_srcptr h, long hlen, long n, long prec) +{ + arb_t c; + arb_init(c); + + arb_acos(c, h, prec); + + hlen = FLINT_MIN(hlen, n); + + if (hlen == 1) + { + _arb_vec_zero(g + 1, n - 1); + } + else + { + arb_ptr t, u; + long ulen; + + t = _arb_vec_init(n); + u = _arb_vec_init(n); + + /* acos(h(x)) = integral(-h'(x)/sqrt(1-h(x)^2)) */ + ulen = FLINT_MIN(n, 2 * hlen - 1); + _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); + arb_sub_ui(u, u, 1, prec); + _arb_vec_neg(u, u, ulen); + _arb_poly_rsqrt_series(t, u, ulen, n, prec); + _arb_poly_derivative(u, h, hlen, prec); + _arb_poly_mullow(g, t, n, u, hlen - 1, n, prec); + _arb_poly_integral(g, g, n, prec); + _arb_vec_neg(g, g, n); + + _arb_vec_clear(t, n); + _arb_vec_clear(u, n); + } + + arb_swap(g, c); + arb_clear(c); +} + +void +arb_poly_acos_series(arb_poly_t g, const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (hlen == 0) + { + if (n == 0) + arb_poly_zero(g); + else + { + arb_poly_fit_length(g, 1); + arb_const_pi(g->coeffs, prec); + arb_mul_2exp_si(g->coeffs, g->coeffs, -1); + _arb_poly_set_length(g, 1); + } + return; + } + + arb_poly_fit_length(g, n); + _arb_poly_acos_series(g->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(g, n); + _arb_poly_normalise(g); +} + diff --git a/arb_poly/add.c b/arb_poly/add.c new file mode 100644 index 000000000..e7d8e8c01 --- /dev/null +++ b/arb_poly/add.c @@ -0,0 +1,58 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_add(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec) +{ + long i, min = FLINT_MIN(len1, len2); + + for (i = 0; i < min; i++) + arb_add(res + i, poly1 + i, poly2 + i, prec); + + for (i = min; i < len1; i++) + arb_set_round(res + i, poly1 + i, prec); + + for (i = min; i < len2; i++) + arb_set_round(res + i, poly2 + i, prec); +} + +void +arb_poly_add(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long prec) +{ + long max = FLINT_MAX(poly1->length, poly2->length); + + arb_poly_fit_length(res, max); + + _arb_poly_add(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, + poly2->length, prec); + + _arb_poly_set_length(res, max); + _arb_poly_normalise(res); +} + diff --git a/arb_poly/asin_series.c b/arb_poly/asin_series.c new file mode 100644 index 000000000..94eae7a80 --- /dev/null +++ b/arb_poly/asin_series.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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_asin_series(arb_ptr g, arb_srcptr h, long hlen, long n, long prec) +{ + arb_t c; + arb_init(c); + + arb_asin(c, h, prec); + + hlen = FLINT_MIN(hlen, n); + + if (hlen == 1) + { + _arb_vec_zero(g + 1, n - 1); + } + else + { + arb_ptr t, u; + long ulen; + + t = _arb_vec_init(n); + u = _arb_vec_init(n); + + /* asin(h(x)) = integral(h'(x)/sqrt(1-h(x)^2)) */ + ulen = FLINT_MIN(n, 2 * hlen - 1); + _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); + arb_sub_ui(u, u, 1, prec); + _arb_vec_neg(u, u, ulen); + _arb_poly_rsqrt_series(t, u, ulen, n, prec); + _arb_poly_derivative(u, h, hlen, prec); + _arb_poly_mullow(g, t, n, u, hlen - 1, n, prec); + _arb_poly_integral(g, g, n, prec); + + _arb_vec_clear(t, n); + _arb_vec_clear(u, n); + } + + arb_swap(g, c); + arb_clear(c); +} + +void +arb_poly_asin_series(arb_poly_t g, const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (hlen == 0 || n == 0) + { + arb_poly_zero(g); + return; + } + + arb_poly_fit_length(g, n); + _arb_poly_asin_series(g->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(g, n); + _arb_poly_normalise(g); +} + diff --git a/arb_poly/atan_series.c b/arb_poly/atan_series.c new file mode 100644 index 000000000..7ccd57cda --- /dev/null +++ b/arb_poly/atan_series.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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + + +void +_arb_poly_atan_series(arb_ptr g, arb_srcptr h, long hlen, long n, long prec) +{ + arb_t c; + arb_init(c); + + arb_atan(c, h, prec); + + hlen = FLINT_MIN(hlen, n); + + if (hlen == 1) + { + _arb_vec_zero(g + 1, n - 1); + } + else + { + arb_ptr t, u; + long ulen; + + t = _arb_vec_init(n); + u = _arb_vec_init(n); + + /* atan(h(x)) = integral(h'(x)/(1+h(x)^2)) */ + ulen = FLINT_MIN(n, 2 * hlen - 1); + _arb_poly_mullow(u, h, hlen, h, hlen, ulen, prec); + arb_add_ui(u, u, 1, prec); + + _arb_poly_derivative(t, h, hlen, prec); + _arb_poly_div_series(g, t, hlen - 1, u, ulen, n, prec); + _arb_poly_integral(g, g, n, prec); + + _arb_vec_clear(t, n); + _arb_vec_clear(u, n); + } + + arb_swap(g, c); + arb_clear(c); +} + +void +arb_poly_atan_series(arb_poly_t g, const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (hlen == 0 || n == 0) + { + arb_poly_zero(g); + return; + } + + arb_poly_fit_length(g, n); + _arb_poly_atan_series(g->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(g, n); + _arb_poly_normalise(g); +} + diff --git a/arb_poly/binomial_transform.c b/arb_poly/binomial_transform.c new file mode 100644 index 000000000..194cb587c --- /dev/null +++ b/arb_poly/binomial_transform.c @@ -0,0 +1,63 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_binomial_transform(arb_ptr b, arb_srcptr a, long alen, long len, long prec) +{ + if (alen < 10 || len < 10) + _arb_poly_binomial_transform_basecase(b, a, alen, len, prec); + else + _arb_poly_binomial_transform_convolution(b, a, alen, len, prec); +} + +void +arb_poly_binomial_transform(arb_poly_t b, const arb_poly_t a, long len, long prec) +{ + if (len == 0 || a->length == 0) + { + arb_poly_zero(b); + return; + } + + if (b == a) + { + arb_poly_t c; + arb_poly_init2(c, len); + _arb_poly_binomial_transform(c->coeffs, a->coeffs, a->length, len, prec); + arb_poly_swap(b, c); + arb_poly_clear(c); + } + else + { + arb_poly_fit_length(b, len); + _arb_poly_binomial_transform(b->coeffs, a->coeffs, a->length, len, prec); + } + + _arb_poly_set_length(b, len); + _arb_poly_normalise(b); +} + diff --git a/arb_poly/binomial_transform_basecase.c b/arb_poly/binomial_transform_basecase.c new file mode 100644 index 000000000..16aba5848 --- /dev/null +++ b/arb_poly/binomial_transform_basecase.c @@ -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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_binomial_transform_basecase(arb_ptr b, arb_srcptr a, long alen, long len, long prec) +{ + long n, k; + + fmpz_t t; + fmpz_init(t); + + for (n = 0; n < len; n++) + { + arb_zero(b + n); + + for (k = 0; k < FLINT_MIN(n + 1, alen); k++) + { + if (k == 0) + { + fmpz_one(t); + } + else + { + fmpz_mul_si(t, t, -(n - k + 1)); + fmpz_divexact_ui(t, t, k); + } + + arb_addmul_fmpz(b + n, a + k, t, prec); + } + } + + fmpz_clear(t); +} + +void +arb_poly_binomial_transform_basecase(arb_poly_t b, const arb_poly_t a, long len, long prec) +{ + if (len == 0 || a->length == 0) + { + arb_poly_zero(b); + return; + } + + if (b == a) + { + arb_poly_t c; + arb_poly_init2(c, len); + _arb_poly_binomial_transform_basecase(c->coeffs, a->coeffs, a->length, len, prec); + arb_poly_swap(b, c); + arb_poly_clear(c); + } + else + { + arb_poly_fit_length(b, len); + _arb_poly_binomial_transform_basecase(b->coeffs, a->coeffs, a->length, len, prec); + } + + _arb_poly_set_length(b, len); + _arb_poly_normalise(b); +} + diff --git a/arb_poly/binomial_transform_convolution.c b/arb_poly/binomial_transform_convolution.c new file mode 100644 index 000000000..db9a701d3 --- /dev/null +++ b/arb_poly/binomial_transform_convolution.c @@ -0,0 +1,82 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arb_poly.h" + +void +_arb_poly_binomial_transform_convolution(arb_ptr b, arb_srcptr a, long alen, long len, long prec) +{ + long i; + arb_ptr c, d; + + alen = FLINT_MIN(alen, len); + + c = _arb_vec_init(alen); + d = _arb_vec_init(len); + + _arb_poly_borel_transform(c, a, alen, prec); + for (i = 1; i < alen; i += 2) + arb_neg(c + i, c + i); + + arb_one(d); + for (i = 1; i < len; i++) + arb_div_ui(d + i, d + i - 1, i, prec); + + _arb_poly_mullow(b, d, len, c, alen, len, prec); + + _arb_poly_inv_borel_transform(b, b, len, prec); + + _arb_vec_clear(c, alen); + _arb_vec_clear(d, len); +} + +void +arb_poly_binomial_transform_convolution(arb_poly_t b, const arb_poly_t a, long len, long prec) +{ + if (len == 0 || a->length == 0) + { + arb_poly_zero(b); + return; + } + + if (b == a) + { + arb_poly_t c; + arb_poly_init2(c, len); + _arb_poly_binomial_transform_convolution(c->coeffs, a->coeffs, a->length, len, prec); + arb_poly_swap(b, c); + arb_poly_clear(c); + } + else + { + arb_poly_fit_length(b, len); + _arb_poly_binomial_transform_convolution(b->coeffs, a->coeffs, a->length, len, prec); + } + + _arb_poly_set_length(b, len); + _arb_poly_normalise(b); +} + diff --git a/arb_poly/borel_transform.c b/arb_poly/borel_transform.c new file mode 100644 index 000000000..e07c4a166 --- /dev/null +++ b/arb_poly/borel_transform.c @@ -0,0 +1,57 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_borel_transform(arb_ptr res, arb_srcptr poly, long len, long prec) +{ + long i; + + arb_t t; + arb_init(t); + + arb_one(t); + + for (i = 0; i < len; i++) + { + if (i > 1) + arb_mul_ui(t, t, i, prec); + + arb_div(res + i, poly + i, t, prec); + } + + arb_clear(t); +} + +void +arb_poly_borel_transform(arb_poly_t res, const arb_poly_t poly, long prec) +{ + arb_poly_fit_length(res, poly->length); + _arb_poly_borel_transform(res->coeffs, poly->coeffs, poly->length, prec); + _arb_poly_set_length(res, poly->length); + _arb_poly_normalise(res); +} + diff --git a/arb_poly/clear.c b/arb_poly/clear.c new file mode 100644 index 000000000..1990006b6 --- /dev/null +++ b/arb_poly/clear.c @@ -0,0 +1,37 @@ +/*============================================================================= + + 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_poly.h" + +void +arb_poly_clear(arb_poly_t poly) +{ + long i; + + for (i = 0; i < poly->alloc; i++) + arb_clear(poly->coeffs + i); + + flint_free(poly->coeffs); +} diff --git a/arb_poly/compose.c b/arb_poly/compose.c new file mode 100644 index 000000000..005e73fbd --- /dev/null +++ b/arb_poly/compose.c @@ -0,0 +1,106 @@ +/*============================================================================= + + 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) 2010 William Hart + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_compose(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec) +{ + if (len2 == 1) + { + _arb_poly_evaluate(res, poly1, len1, poly2, prec); + } + else if (_arb_vec_is_zero(poly2, len2 - 1)) /* poly2 is a monomial */ + { + long i; + arb_t t; + + arb_init(t); + arb_set(t, poly2 + len2 - 1); + arb_set_round(res, poly1, prec); + + for (i = 1; i < len1; i++) + { + arb_mul(res + i * (len2 - 1), poly1 + i, t, prec); + if (i + 1 < len1) + arb_mul(t, t, poly2 + len2 - 1, prec); + + _arb_vec_zero(res + (i - 1) * (len2 - 1) + 1, len2 - 2); + } + + arb_clear(t); + } + else if (len1 <= 7) + { + _arb_poly_compose_horner(res, poly1, len1, poly2, len2, prec); + } + else + { + _arb_poly_compose_divconquer(res, poly1, len1, poly2, len2, prec); + } +} + +void arb_poly_compose(arb_poly_t res, + const arb_poly_t poly1, const arb_poly_t poly2, long prec) +{ + const long len1 = poly1->length; + const long len2 = poly2->length; + + if (len1 == 0) + { + arb_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + arb_poly_set_arb(res, poly1->coeffs); + } + else + { + const long lenr = (len1 - 1) * (len2 - 1) + 1; + + if (res != poly1 && res != poly2) + { + arb_poly_fit_length(res, lenr); + _arb_poly_compose(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, prec); + } + else + { + arb_poly_t t; + arb_poly_init2(t, lenr); + _arb_poly_compose(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, prec); + arb_poly_swap(res, t); + arb_poly_clear(t); + } + + _arb_poly_set_length(res, lenr); + _arb_poly_normalise(res); + } +} diff --git a/arb_poly/compose_divconquer.c b/arb_poly/compose_divconquer.c new file mode 100644 index 000000000..ad57ce9b3 --- /dev/null +++ b/arb_poly/compose_divconquer.c @@ -0,0 +1,196 @@ +/*============================================================================= + + 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) 2010 William Hart + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_compose_divconquer(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec) +{ + long i, j, k, n; + long *hlen, alloc, powlen; + arb_ptr v, pow, temp; + arb_ptr * h; + + if (len1 == 1) + { + arb_set(res, poly1); + return; + } + if (len2 == 1) + { + _arb_poly_evaluate(res, poly1, len1, poly2, prec); + return; + } + if (len1 == 2) + { + _arb_poly_compose_horner(res, poly1, len1, poly2, len2, prec); + return; + } + + /* Initialisation */ + + hlen = (long *) flint_malloc(((len1 + 1) / 2) * sizeof(long)); + + for (k = 1; (2 << k) < len1; k++) ; + + hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1; + for (i = k - 1; i > 0; i--) + { + long hi = (len1 + (1 << i) - 1) / (1 << i); + for (n = (hi + 1) / 2; n < hi; n++) + hlen[n] = ((1 << i) - 1) * (len2 - 1) + 1; + } + powlen = (1 << k) * (len2 - 1) + 1; + + alloc = 0; + for (i = 0; i < (len1 + 1) / 2; i++) + alloc += hlen[i]; + + v = _arb_vec_init(alloc + 2 * powlen); + h = (arb_ptr *) flint_malloc(((len1 + 1) / 2) * sizeof(arb_ptr)); + h[0] = v; + for (i = 0; i < (len1 - 1) / 2; i++) + { + h[i + 1] = h[i] + hlen[i]; + hlen[i] = 0; + } + hlen[(len1 - 1) / 2] = 0; + pow = v + alloc; + temp = pow + powlen; + + /* Let's start the actual work */ + + for (i = 0, j = 0; i < len1 / 2; i++, j += 2) + { + if (!arb_is_zero(poly1 + j + 1)) + { + _arb_vec_scalar_mul(h[i], poly2, len2, poly1 + j + 1, prec); + arb_add(h[i], h[i], poly1 + j, prec); + hlen[i] = len2; + } + else if (!arb_is_zero(poly1 + j)) + { + arb_set(h[i], poly1 + j); + hlen[i] = 1; + } + } + if ((len1 & 1L)) + { + if (!arb_is_zero(poly1 + j)) + { + arb_set(h[i], poly1 + j); + hlen[i] = 1; + } + } + + _arb_poly_mul(pow, poly2, len2, poly2, len2, prec); + powlen = 2 * len2 - 1; + + for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2) + { + if (hlen[1] > 0) + { + long templen = powlen + hlen[1] - 1; + _arb_poly_mul(temp, pow, powlen, h[1], hlen[1], prec); + _arb_poly_add(h[0], temp, templen, h[0], hlen[0], prec); + hlen[0] = FLINT_MAX(hlen[0], templen); + } + + for (i = 1; i < n / 2; i++) + { + if (hlen[2*i + 1] > 0) + { + _arb_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1], prec); + hlen[i] = hlen[2*i + 1] + powlen - 1; + } else + hlen[i] = 0; + _arb_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i], prec); + hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]); + } + if ((n & 1L)) + { + _arb_vec_set(h[i], h[2*i], hlen[2*i]); + hlen[i] = hlen[2*i]; + } + + _arb_poly_mul(temp, pow, powlen, pow, powlen, prec); + powlen += powlen - 1; + { + arb_ptr t = pow; + pow = temp; + temp = t; + } + } + + _arb_poly_mul(res, pow, powlen, h[1], hlen[1], prec); + _arb_vec_add(res, res, h[0], hlen[0], prec); + + _arb_vec_clear(v, alloc + 2 * powlen); + flint_free(h); + flint_free(hlen); +} + +void +arb_poly_compose_divconquer(arb_poly_t res, + const arb_poly_t poly1, const arb_poly_t poly2, long prec) +{ + const long len1 = poly1->length; + const long len2 = poly2->length; + + if (len1 == 0) + { + arb_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + arb_poly_set_arb(res, poly1->coeffs); + } + else + { + const long lenr = (len1 - 1) * (len2 - 1) + 1; + + if (res != poly1 && res != poly2) + { + arb_poly_fit_length(res, lenr); + _arb_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, prec); + } + else + { + arb_poly_t t; + arb_poly_init2(t, lenr); + _arb_poly_compose_divconquer(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, prec); + arb_poly_swap(res, t); + arb_poly_clear(t); + } + + _arb_poly_set_length(res, lenr); + _arb_poly_normalise(res); + } +} diff --git a/arb_poly/compose_horner.c b/arb_poly/compose_horner.c new file mode 100644 index 000000000..b3d292bf0 --- /dev/null +++ b/arb_poly/compose_horner.c @@ -0,0 +1,125 @@ +/*============================================================================= + + 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) 2010 William Hart + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_compose_horner(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec) +{ + if (len1 == 1) + { + arb_set(res, poly1); + } + else if (len2 == 1) + { + _arb_poly_evaluate(res, poly1, len1, poly2, prec); + } + else if (len1 == 2) + { + _arb_vec_scalar_mul(res, poly2, len2, poly1 + 1, prec); + arb_add(res, res, poly1, prec); + } + else + { + const long alloc = (len1 - 1) * (len2 - 1) + 1; + long i = len1 - 1, lenr = len2; + arb_ptr t, t1, t2; + t = _arb_vec_init(alloc); + + if (len1 % 2 == 0) + { + t1 = res; + t2 = t; + } + else + { + t1 = t; + t2 = res; + } + + /* Perform the first two steps as one, + "res = a(m) * poly2 + a(m-1)". */ + { + _arb_vec_scalar_mul(t1, poly2, len2, poly1 + i, prec); + i--; + arb_add(t1 + 0, t1 + 0, poly1 + i, prec); + } + while (i--) + { + _arb_poly_mul(t2, t1, lenr, poly2, len2, prec); + lenr += len2 - 1; + { + void *t_ = t1; + t1 = t2; + t2 = t_; + } + arb_add(t1 + 0, t1 + 0, poly1 + i, prec); + } + _arb_vec_clear(t, alloc); + } +} + +void arb_poly_compose_horner(arb_poly_t res, + const arb_poly_t poly1, const arb_poly_t poly2, long prec) +{ + const long len1 = poly1->length; + const long len2 = poly2->length; + + if (len1 == 0) + { + arb_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + arb_poly_set_arb(res, poly1->coeffs); + } + else + { + const long lenr = (len1 - 1) * (len2 - 1) + 1; + + if (res != poly1 && res != poly2) + { + arb_poly_fit_length(res, lenr); + _arb_poly_compose_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, prec); + } + else + { + arb_poly_t t; + arb_poly_init2(t, lenr); + _arb_poly_compose_horner(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, prec); + arb_poly_swap(res, t); + arb_poly_clear(t); + } + + _arb_poly_set_length(res, lenr); + _arb_poly_normalise(res); + } +} diff --git a/arb_poly/compose_series.c b/arb_poly/compose_series.c new file mode 100644 index 000000000..7f7d28a2a --- /dev/null +++ b/arb_poly/compose_series.c @@ -0,0 +1,129 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_compose_series(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec) +{ + if (len2 == 1) + { + arb_set_round(res, poly1, prec); + _arb_vec_zero(res + 1, n - 1); + } + else if (_arb_vec_is_zero(poly2 + 1, len2 - 2)) /* poly2 is a monomial */ + { + long i, j; + arb_t t; + + arb_init(t); + arb_set(t, poly2 + len2 - 1); + arb_set_round(res, poly1, prec); + + for (i = 1, j = len2 - 1; i < len1 && j < n; i++, j += len2 - 1) + { + arb_mul(res + j, poly1 + i, t, prec); + + if (i + 1 < len1 && j + len2 - 1 < n) + arb_mul(t, t, poly2 + len2 - 1, prec); + } + + if (len2 != 2) + for (i = 1; i < n; i++) + if (i % (len2 - 1) != 0) + arb_zero(res + i); + + arb_clear(t); + } +#if 0 + else if (len1 < 6 || n < 6) + { + _arb_poly_compose_series_horner(res, poly1, len1, poly2, len2, n, prec); + } + else + { + _arb_poly_compose_series_brent_kung(res, poly1, len1, poly2, len2, n, prec); + } +#else + else + { + _arb_poly_compose_series_horner(res, poly1, len1, poly2, len2, n, prec); + } +#endif +} + +void +arb_poly_compose_series(arb_poly_t res, + const arb_poly_t poly1, + const arb_poly_t poly2, long n, long prec) +{ + long len1 = poly1->length; + long len2 = poly2->length; + long lenr; + + if (len2 != 0 && !arb_is_zero(poly2->coeffs)) + { + printf("exception: compose_series: inner " + "polynomial must have zero constant term\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + arb_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + arb_poly_set_arb(res, poly1->coeffs); + return; + } + + lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); + len1 = FLINT_MIN(len1, lenr); + len2 = FLINT_MIN(len2, lenr); + + if ((res != poly1) && (res != poly2)) + { + arb_poly_fit_length(res, lenr); + _arb_poly_compose_series(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, prec); + _arb_poly_set_length(res, lenr); + _arb_poly_normalise(res); + } + else + { + arb_poly_t t; + arb_poly_init2(t, lenr); + _arb_poly_compose_series(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, prec); + _arb_poly_set_length(t, lenr); + _arb_poly_normalise(t); + arb_poly_swap(res, t); + arb_poly_clear(t); + } +} diff --git a/arb_poly/compose_series_horner.c b/arb_poly/compose_series_horner.c new file mode 100644 index 000000000..11f4e6c7a --- /dev/null +++ b/arb_poly/compose_series_horner.c @@ -0,0 +1,120 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_compose_series_horner(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec) +{ + if (n == 1) + { + arb_set(res, poly1); + } + else + { + long i = len1 - 1; + long lenr; + + arb_ptr t = _arb_vec_init(n); + + lenr = len2; + _arb_vec_scalar_mul(res, poly2, len2, poly1 + i, prec); + i--; + arb_add(res, res, poly1 + i, prec); + + while (i > 0) + { + i--; + if (lenr + len2 - 1 < n) + { + _arb_poly_mul(t, res, lenr, poly2, len2, prec); + lenr = lenr + len2 - 1; + } + else + { + _arb_poly_mullow(t, res, lenr, poly2, len2, n, prec); + lenr = n; + } + _arb_poly_add(res, t, lenr, poly1 + i, 1, prec); + } + + _arb_vec_zero(res + lenr, n - lenr); + _arb_vec_clear(t, n); + } +} + +void +arb_poly_compose_series_horner(arb_poly_t res, + const arb_poly_t poly1, + const arb_poly_t poly2, long n, long prec) +{ + long len1 = poly1->length; + long len2 = poly2->length; + long lenr; + + if (len2 != 0 && !arb_is_zero(poly2->coeffs)) + { + printf("exception: compose_series: inner " + "polynomial must have zero constant term\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + arb_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + arb_poly_set_arb(res, poly1->coeffs); + return; + } + + lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); + len1 = FLINT_MIN(len1, lenr); + len2 = FLINT_MIN(len2, lenr); + + if ((res != poly1) && (res != poly2)) + { + arb_poly_fit_length(res, lenr); + _arb_poly_compose_series_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, prec); + _arb_poly_set_length(res, lenr); + _arb_poly_normalise(res); + } + else + { + arb_poly_t t; + arb_poly_init2(t, lenr); + _arb_poly_compose_series_horner(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, prec); + _arb_poly_set_length(t, lenr); + _arb_poly_normalise(t); + arb_poly_swap(res, t); + arb_poly_clear(t); + } +} diff --git a/arb_poly/contains.c b/arb_poly/contains.c new file mode 100644 index 000000000..0afee0e3e --- /dev/null +++ b/arb_poly/contains.c @@ -0,0 +1,47 @@ +/*============================================================================= + + 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_poly.h" + +int +arb_poly_contains(const arb_poly_t poly1, const arb_poly_t poly2) +{ + long i; + + if (poly2->length > poly1->length) + return 0; + + for (i = 0; i < poly2->length; i++) + { + if (!arb_contains(poly1->coeffs + i, poly2->coeffs + i)) + return 0; + } + + for (i = poly2->length; i < poly1->length; i++) + if (!arb_contains_zero(poly1->coeffs + i)) + return 0; + + return 1; +} diff --git a/arb_poly/contains_fmpq_poly.c b/arb_poly/contains_fmpq_poly.c new file mode 100644 index 000000000..42a12ec2c --- /dev/null +++ b/arb_poly/contains_fmpq_poly.c @@ -0,0 +1,56 @@ +/*============================================================================= + + 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_poly.h" + +int +arb_poly_contains_fmpq_poly(const arb_poly_t poly1, const fmpq_poly_t poly2) +{ + long i; + fmpq_t t; + + if (poly2->length > poly1->length) + return 0; + + fmpq_init(t); + + for (i = 0; i < poly2->length; i++) + { + fmpq_poly_get_coeff_fmpq(t, poly2, i); + if (!arb_contains_fmpq(poly1->coeffs + i, t)) + { + fmpq_clear(t); + return 0; + } + } + + fmpq_clear(t); + + for (i = poly2->length; i < poly1->length; i++) + if (!arb_contains_zero(poly1->coeffs + i)) + return 0; + + return 1; +} diff --git a/arb_poly/contains_fmpz_poly.c b/arb_poly/contains_fmpz_poly.c new file mode 100644 index 000000000..7481a9b68 --- /dev/null +++ b/arb_poly/contains_fmpz_poly.c @@ -0,0 +1,46 @@ +/*============================================================================= + + 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_poly.h" + +int +arb_poly_contains_fmpz_poly(const arb_poly_t poly1, const fmpz_poly_t poly2) +{ + long i; + + if (poly2->length > poly1->length) + return 0; + + for (i = 0; i < poly2->length; i++) + if (!arb_contains_fmpz(poly1->coeffs + i, poly2->coeffs + i)) + return 0; + + for (i = poly2->length; i < poly1->length; i++) + if (!arb_contains_zero(poly1->coeffs + i)) + return 0; + + return 1; +} + diff --git a/arb_poly/cos_series.c b/arb_poly/cos_series.c new file mode 100644 index 000000000..60c98a5de --- /dev/null +++ b/arb_poly/cos_series.c @@ -0,0 +1,80 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_cos_series(arb_ptr g, arb_srcptr h, long hlen, long n, long prec) +{ + hlen = FLINT_MIN(hlen, n); + + if (hlen == 1) + { + arb_cos(g, h, prec); + _arb_vec_zero(g + 1, n - 1); + } + else if (n == 2) + { + arb_t t; + arb_init(t); + arb_sin_cos(t, g, h, prec); + arb_neg(t, t); + arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ + arb_clear(t); + } + else + { + arb_ptr t = _arb_vec_init(n); + _arb_poly_sin_cos_series(t, g, h, hlen, n, prec); + _arb_vec_clear(t, n); + } +} + +void +arb_poly_cos_series(arb_poly_t g, const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (n == 0) + { + arb_poly_zero(g); + return; + } + + if (hlen == 0) + { + arb_poly_one(g); + return; + } + + if (hlen == 1) + n = 1; + + arb_poly_fit_length(g, n); + _arb_poly_cos_series(g->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(g, n); + _arb_poly_normalise(g); +} + diff --git a/arb_poly/derivative.c b/arb_poly/derivative.c new file mode 100644 index 000000000..a32e7af85 --- /dev/null +++ b/arb_poly/derivative.c @@ -0,0 +1,52 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_derivative(arb_ptr res, arb_srcptr poly, long len, long prec) +{ + long i; + + for (i = 1; i < len; i++) + arb_mul_ui(res + i - 1, poly + i, i, prec); +} + +void +arb_poly_derivative(arb_poly_t res, const arb_poly_t poly, long prec) +{ + long len = poly->length; + + if (len < 2) + { + arb_poly_zero(res); + } + else + { + arb_poly_fit_length(res, len - 1); + _arb_poly_derivative(res->coeffs, poly->coeffs, len, prec); + _arb_poly_set_length(res, len - 1); + } +} diff --git a/arb_poly/div_root.c b/arb_poly/div_root.c new file mode 100644 index 000000000..bd41b5f7d --- /dev/null +++ b/arb_poly/div_root.c @@ -0,0 +1,60 @@ +/*============================================================================= + + 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) 2011 William Hart + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_div_root(arb_ptr Q, arb_t R, arb_srcptr A, + long len, const arb_t c, long prec) +{ + arb_t r, t; + long i; + + if (len < 2) + { + arb_zero(R); + return; + } + + arb_init(r); + arb_init(t); + + arb_set(t, A + len - 2); + arb_set(Q + len - 2, A + len - 1); + arb_set(r, Q + len - 2); + + /* TODO: avoid the extra assignments (but still support aliasing) */ + for (i = len - 2; i > 0; i--) + { + arb_mul(r, r, c, prec); + arb_add(r, r, t, prec); + arb_set(t, A + i - 1); + arb_set(Q + i - 1, r); + } + + arb_mul(r, r, c, prec); + arb_add(R, r, t, prec); +} diff --git a/arb_poly/div_series.c b/arb_poly/div_series.c new file mode 100644 index 000000000..1a26a7c73 --- /dev/null +++ b/arb_poly/div_series.c @@ -0,0 +1,80 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_div_series(arb_ptr Q, arb_srcptr A, long Alen, + arb_srcptr B, long Blen, long n, long prec) +{ + Alen = FLINT_MIN(Alen, n); + Blen = FLINT_MIN(Blen, n); + + if (Blen == 1) + { + _arb_vec_scalar_div(Q, A, Alen, B, prec); + _arb_vec_zero(Q + Alen, n - Alen); + } + else + { + arb_ptr Binv; + Binv = _arb_vec_init(n); + _arb_poly_inv_series(Binv, B, Blen, n, prec); + _arb_poly_mullow(Q, Binv, n, A, Alen, n, prec); + _arb_vec_clear(Binv, n); + } +} + +void +arb_poly_div_series(arb_poly_t Q, const arb_poly_t A, const arb_poly_t B, long n, long prec) +{ + if (n == 0 || B->length == 0) + { + printf("arb_poly_inv_series: require n > 0 and nonzero input\n"); + abort(); + } + + if (A->length == 0) + { + arb_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + arb_poly_t t; + arb_poly_init(t); + arb_poly_div_series(t, A, B, n, prec); + arb_poly_swap(Q, t); + arb_poly_clear(t); + return; + } + + arb_poly_fit_length(Q, n); + _arb_poly_div_series(Q->coeffs, A->coeffs, A->length, B->coeffs, B->length, n, prec); + _arb_poly_set_length(Q, n); + _arb_poly_normalise(Q); +} + diff --git a/arb_poly/divrem.c b/arb_poly/divrem.c new file mode 100644 index 000000000..ee31e44ee --- /dev/null +++ b/arb_poly/divrem.c @@ -0,0 +1,137 @@ +/*============================================================================= + + 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) 2011 William Hart + Copyright (C) 2012, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +/* TODO: tighten this code */ + +void +_arb_poly_div(arb_ptr Q, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long prec) +{ + long lenQ, lenB2; + arb_ptr Arev, Brev; + + lenQ = lenA - lenB + 1; + + Arev = _arb_vec_init(2 * lenQ); + Brev = Arev + lenQ; + + _arb_poly_reverse(Arev, A + (lenA - lenQ), lenQ, lenQ); + + if (lenB >= lenQ) + { + _arb_poly_reverse(Brev, B + (lenB - lenQ), lenQ, lenQ); + lenB2 = lenQ; + } + else + { + _arb_poly_reverse(Brev, B, lenB, lenB); + lenB2 = lenB; + } + + _arb_poly_div_series(Q, Arev, lenQ, Brev, lenB2, lenQ, prec); + _arb_poly_reverse(Q, Q, lenQ, lenQ); + + _arb_vec_clear(Arev, 2 * lenQ); +} + +void _arb_poly_divrem(arb_ptr Q, arb_ptr R, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long prec) +{ + const long lenQ = lenA - lenB + 1; + _arb_poly_div(Q, A, lenA, B, lenB, prec); + + if (lenB > 1) + { + if (lenQ >= lenB - 1) + _arb_poly_mullow(R, Q, lenQ, B, lenB - 1, lenB - 1, prec); + else + _arb_poly_mullow(R, B, lenB - 1, Q, lenQ, lenB - 1, prec); + _arb_vec_sub(R, A, R, lenB - 1, prec); + } +} + +void _arb_poly_rem(arb_ptr R, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long prec) +{ + const long lenQ = lenA - lenB + 1; + arb_ptr Q = _arb_vec_init(lenQ); + _arb_poly_divrem(Q, R, A, lenA, B, lenB, prec); + _arb_vec_clear(Q, lenQ); +} + +void arb_poly_divrem(arb_poly_t Q, arb_poly_t R, + const arb_poly_t A, const arb_poly_t B, long prec) +{ + const long lenA = A->length, lenB = B->length; + + if (lenB == 0 || arb_contains_zero(B->coeffs + lenB - 1)) + { + printf("Exception: division by zero in arb_poly_divrem\n"); + abort(); + } + + if (lenA < lenB) + { + arb_poly_set(R, A); + arb_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + arb_poly_t T; + arb_poly_init(T); + arb_poly_divrem(T, R, A, B, prec); + arb_poly_swap(Q, T); + arb_poly_clear(T); + return; + } + + if (R == A || R == B) + { + arb_poly_t U; + arb_poly_init(U); + arb_poly_divrem(Q, U, A, B, prec); + arb_poly_swap(R, U); + arb_poly_clear(U); + return; + } + + arb_poly_fit_length(Q, lenA - lenB + 1); + arb_poly_fit_length(R, lenB - 1); + + _arb_poly_divrem(Q->coeffs, R->coeffs, A->coeffs, lenA, + B->coeffs, lenB, prec); + + _arb_poly_set_length(Q, lenA - lenB + 1); + _arb_poly_set_length(R, lenB - 1); + _arb_poly_normalise(R); +} diff --git a/arb_poly/equal.c b/arb_poly/equal.c new file mode 100644 index 000000000..668cbcbe6 --- /dev/null +++ b/arb_poly/equal.c @@ -0,0 +1,41 @@ +/*============================================================================= + + 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_poly.h" + +int +arb_poly_equal(const arb_poly_t A, const arb_poly_t B) +{ + long i; + + if (A->length != B->length) + return 0; + + for (i = 0; i < A->length; i++) + if (!arb_equal(A->coeffs + i, B->coeffs + i)) + return 0; + + return 1; +} diff --git a/arb_poly/evaluate.c b/arb_poly/evaluate.c new file mode 100644 index 000000000..4b37ec2b9 --- /dev/null +++ b/arb_poly/evaluate.c @@ -0,0 +1,53 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_evaluate(arb_t res, arb_srcptr f, long len, + const arb_t x, long prec) +{ + if ((prec >= 1024) && (len >= 5 + 20000 / prec)) + { + long fbits; + + fbits = _arb_vec_bits(f, len); + + if (fbits <= prec / 2) + { + _arb_poly_evaluate_rectangular(res, f, len, x, prec); + return; + } + } + + _arb_poly_evaluate_horner(res, f, len, x, prec); +} + +void +arb_poly_evaluate(arb_t res, const arb_poly_t f, const arb_t a, long prec) +{ + _arb_poly_evaluate(res, f->coeffs, f->length, a, prec); +} + diff --git a/arb_poly/evaluate2.c b/arb_poly/evaluate2.c new file mode 100644 index 000000000..04ac30cd8 --- /dev/null +++ b/arb_poly/evaluate2.c @@ -0,0 +1,52 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_evaluate2(arb_t y, arb_t z, arb_srcptr f, long len, const arb_t x, long prec) +{ + if ((prec >= 1024) && (len >= 5 + 20000 / prec)) + { + long fbits; + + fbits = _arb_vec_bits(f, len); + + if (fbits <= prec / 2) + { + _arb_poly_evaluate2_rectangular(y, z, f, len, x, prec); + return; + } + } + + _arb_poly_evaluate2_horner(y, z, f, len, x, prec); +} + +void +arb_poly_evaluate2(arb_t r, arb_t s, const arb_poly_t f, const arb_t a, long prec) +{ + _arb_poly_evaluate2(r, s, f->coeffs, f->length, a, prec); +} + diff --git a/arb_poly/evaluate2_horner.c b/arb_poly/evaluate2_horner.c new file mode 100644 index 000000000..9fc1075cf --- /dev/null +++ b/arb_poly/evaluate2_horner.c @@ -0,0 +1,87 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_evaluate2_horner(arb_t y, arb_t z, arb_srcptr poly, + long len, const arb_t x, long prec) +{ + if (len == 0) + { + arb_zero(y); + arb_zero(z); + } + else if (len == 1) + { + arb_set_round(y, poly + 0, prec); + arb_zero(z); + } + else if (arb_is_zero(x)) + { + arb_set_round(y, poly + 0, prec); + arb_set_round(z, poly + 1, prec); + } + else if (len == 2) + { + arb_mul(y, x, poly + 1, prec); + arb_add(y, y, poly + 0, prec); + arb_set_round(z, poly + 1, prec); + } + else + { + arb_t t, u, v; + long i; + + arb_init(t); + arb_init(u); + arb_init(v); + + arb_set_round(u, poly + len - 1, prec); + arb_zero(v); + + for (i = len - 2; i >= 0; i--) + { + arb_mul(t, v, x, prec); + arb_add(v, u, t, prec); + arb_mul(t, u, x, prec); + arb_add(u, t, poly + i, prec); + } + + arb_swap(y, u); + arb_swap(z, v); + + arb_clear(t); + arb_clear(u); + arb_clear(v); + } +} + +void +arb_poly_evaluate2_horner(arb_t r, arb_t s, const arb_poly_t f, const arb_t a, long prec) +{ + _arb_poly_evaluate2_horner(r, s, f->coeffs, f->length, a, prec); +} + diff --git a/arb_poly/evaluate2_rectangular.c b/arb_poly/evaluate2_rectangular.c new file mode 100644 index 000000000..324f41d7b --- /dev/null +++ b/arb_poly/evaluate2_rectangular.c @@ -0,0 +1,117 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_evaluate2_rectangular(arb_t y, arb_t z, arb_srcptr poly, + long len, const arb_t x, long prec) +{ + long i, j, m, r; + arb_ptr xs; + arb_t s, t, c; + + if (len < 3) + { + if (len == 0) + { + arb_zero(y); + arb_zero(z); + } + else if (len == 1) + { + arb_set_round(y, poly + 0, prec); + arb_zero(z); + } + else if (len == 2) + { + arb_mul(y, x, poly + 1, prec); + arb_add(y, y, poly + 0, prec); + arb_set_round(z, poly + 1, prec); + } + return; + } + + m = n_sqrt(len) + 1; + m *= 1; + + r = (len + m - 1) / m; + + xs = _arb_vec_init(m + 1); + arb_init(s); + arb_init(t); + arb_init(c); + + _arb_vec_set_powers(xs, x, m + 1, prec); + + arb_set(y, poly + (r - 1) * m); + for (j = 1; (r - 1) * m + j < len; j++) + arb_addmul(y, xs + j, poly + (r - 1) * m + j, prec); + + for (i = r - 2; i >= 0; i--) + { + arb_set(s, poly + i * m); + for (j = 1; j < m; j++) + arb_addmul(s, xs + j, poly + i * m + j, prec); + + arb_mul(y, y, xs + m, prec); + arb_add(y, y, s, prec); + } + + len -= 1; + r = (len + m - 1) / m; + arb_mul_ui(z, poly + (r - 1) * m + 1, (r - 1) * m + 1, FMPR_PREC_EXACT); + for (j = 1; (r - 1) * m + j < len; j++) + { + arb_mul_ui(c, poly + (r - 1) * m + j + 1, (r - 1) * m + j + 1, FMPR_PREC_EXACT); + arb_addmul(z, xs + j, c, prec); + } + + for (i = r - 2; i >= 0; i--) + { + arb_mul_ui(s, poly + i * m + 1, i * m + 1, FMPR_PREC_EXACT); + + for (j = 1; j < m; j++) + { + arb_mul_ui(c, poly + i * m + j + 1, i * m + j + 1, FMPR_PREC_EXACT); + arb_addmul(s, xs + j, c, prec); + } + + arb_mul(z, z, xs + m, prec); + arb_add(z, z, s, prec); + } + + _arb_vec_clear(xs, m + 1); + arb_clear(s); + arb_clear(t); + arb_clear(c); +} + +void +arb_poly_evaluate2_rectangular(arb_t r, arb_t s, const arb_poly_t f, const arb_t a, long prec) +{ + _arb_poly_evaluate2_rectangular(r, s, f->coeffs, f->length, a, prec); +} + diff --git a/arb_poly/evaluate_horner.c b/arb_poly/evaluate_horner.c new file mode 100644 index 000000000..86b7042a1 --- /dev/null +++ b/arb_poly/evaluate_horner.c @@ -0,0 +1,73 @@ +/*============================================================================= + + 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) 2010 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_evaluate_horner(arb_t y, arb_srcptr f, long len, + const arb_t x, long prec) +{ + if (len == 0) + { + arb_zero(y); + } + else if (len == 1 || arb_is_zero(x)) + { + arb_set_round(y, f, prec); + } + else if (len == 2) + { + arb_mul(y, x, f + 1, prec); + arb_add(y, y, f + 0, prec); + } + else + { + long i = len - 1; + arb_t t, u; + + arb_init(t); + arb_init(u); + arb_set(u, f + i); + + for (i = len - 2; i >= 0; i--) + { + arb_mul(t, u, x, prec); + arb_add(u, f + i, t, prec); + } + + arb_swap(y, u); + + arb_clear(t); + arb_clear(u); + } +} + +void +arb_poly_evaluate_horner(arb_t res, const arb_poly_t f, const arb_t a, long prec) +{ + _arb_poly_evaluate_horner(res, f->coeffs, f->length, a, prec); +} + diff --git a/arb_poly/evaluate_rectangular.c b/arb_poly/evaluate_rectangular.c new file mode 100644 index 000000000..9a6152208 --- /dev/null +++ b/arb_poly/evaluate_rectangular.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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_evaluate_rectangular(arb_t y, arb_srcptr poly, + long len, const arb_t x, long prec) +{ + long i, j, m, r; + arb_ptr xs; + arb_t s, t, c; + + if (len < 3) + { + if (len == 0) + { + arb_zero(y); + } + else if (len == 1) + { + arb_set_round(y, poly + 0, prec); + } + else if (len == 2) + { + arb_mul(y, x, poly + 1, prec); + arb_add(y, y, poly + 0, prec); + } + return; + } + + m = n_sqrt(len) + 1; + r = (len + m - 1) / m; + + xs = _arb_vec_init(m + 1); + arb_init(s); + arb_init(t); + arb_init(c); + + _arb_vec_set_powers(xs, x, m + 1, prec); + + arb_set(y, poly + (r - 1) * m); + for (j = 1; (r - 1) * m + j < len; j++) + arb_addmul(y, xs + j, poly + (r - 1) * m + j, prec); + + for (i = r - 2; i >= 0; i--) + { + arb_set(s, poly + i * m); + for (j = 1; j < m; j++) + arb_addmul(s, xs + j, poly + i * m + j, prec); + + arb_mul(y, y, xs + m, prec); + arb_add(y, y, s, prec); + } + + _arb_vec_clear(xs, m + 1); + arb_clear(s); + arb_clear(t); + arb_clear(c); +} + +void +arb_poly_evaluate_rectangular(arb_t res, const arb_poly_t f, const arb_t a, long prec) +{ + _arb_poly_evaluate_rectangular(res, f->coeffs, f->length, a, prec); +} + diff --git a/arb_poly/evaluate_vec_fast.c b/arb_poly/evaluate_vec_fast.c new file mode 100644 index 000000000..515481d2f --- /dev/null +++ b/arb_poly/evaluate_vec_fast.c @@ -0,0 +1,149 @@ +/*============================================================================= + + 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_poly.h" + +/* This gives some speedup for small lengths. */ +static __inline__ void +_arb_poly_rem_2(arb_ptr r, arb_srcptr a, long al, + arb_srcptr b, long bl, long prec) +{ + if (al == 2) + { + arb_mul(r + 0, a + 1, b + 0, prec); + arb_sub(r + 0, a + 0, r + 0, prec); + } + else + { + _arb_poly_rem(r, a, al, b, bl, prec); + } +} + +void +_arb_poly_evaluate_vec_fast_precomp(arb_ptr vs, arb_srcptr poly, + long plen, arb_ptr * tree, long len, long prec) +{ + long height, i, j, pow, left; + long tree_height; + long tlen; + arb_ptr t, u, swap, pa, pb, pc; + + /* avoid worrying about some degenerate cases */ + if (len < 2 || plen < 2) + { + if (len == 1) + { + arb_t tmp; + arb_init(tmp); + arb_neg(tmp, tree[0] + 0); + _arb_poly_evaluate(vs + 0, poly, plen, tmp, prec); + arb_clear(tmp); + } + else if (len != 0 && plen == 0) + { + _arb_vec_zero(vs, len); + } + else if (len != 0 && plen == 1) + { + for (i = 0; i < len; i++) + arb_set(vs + i, poly + 0); + } + return; + } + + t = _arb_vec_init(len); + u = _arb_vec_init(len); + + left = len; + + /* Initial reduction. We allow the polynomial to be larger + or smaller than the number of points. */ + height = FLINT_BIT_COUNT(plen - 1) - 1; + tree_height = FLINT_CLOG2(len); + while (height >= tree_height) + height--; + pow = 1L << height; + + for (i = j = 0; i < len; i += pow, j += (pow + 1)) + { + tlen = ((i + pow) <= len) ? pow : len % pow; + _arb_poly_rem(t + i, poly, plen, tree[height] + j, tlen + 1, prec); + } + + for (i = height - 1; i >= 0; i--) + { + pow = 1L << i; + left = len; + pa = tree[i]; + pb = t; + pc = u; + + while (left >= 2 * pow) + { + _arb_poly_rem_2(pc, pb, 2 * pow, pa, pow + 1, prec); + _arb_poly_rem_2(pc + pow, pb, 2 * pow, pa + pow + 1, pow + 1, prec); + + pa += 2 * pow + 2; + pb += 2 * pow; + pc += 2 * pow; + left -= 2 * pow; + } + + if (left > pow) + { + _arb_poly_rem(pc, pb, left, pa, pow + 1, prec); + _arb_poly_rem(pc + pow, pb, left, pa + pow + 1, left - pow + 1, prec); + } + else if (left > 0) + _arb_vec_set(pc, pb, left); + + swap = t; + t = u; + u = swap; + } + + _arb_vec_set(vs, t, len); + _arb_vec_clear(t, len); + _arb_vec_clear(u, len); +} + +void _arb_poly_evaluate_vec_fast(arb_ptr ys, arb_srcptr poly, long plen, + arb_srcptr xs, long n, long prec) +{ + arb_ptr * tree; + + tree = _arb_poly_tree_alloc(n); + _arb_poly_tree_build(tree, xs, n, prec); + _arb_poly_evaluate_vec_fast_precomp(ys, poly, plen, tree, n, prec); + _arb_poly_tree_free(tree, n); +} + +void +arb_poly_evaluate_vec_fast(arb_ptr ys, + const arb_poly_t poly, arb_srcptr xs, long n, long prec) +{ + _arb_poly_evaluate_vec_fast(ys, poly->coeffs, + poly->length, xs, n, prec); +} diff --git a/arb_poly/evaluate_vec_iter.c b/arb_poly/evaluate_vec_iter.c new file mode 100644 index 000000000..744f6796a --- /dev/null +++ b/arb_poly/evaluate_vec_iter.c @@ -0,0 +1,44 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_evaluate_vec_iter(arb_ptr ys, arb_srcptr poly, long plen, + arb_srcptr xs, long n, long prec) +{ + long i; + + for (i = 0; i < n; i++) + _arb_poly_evaluate(ys + i, poly, plen, xs + i, prec); +} + +void +arb_poly_evaluate_vec_iter(arb_ptr ys, + const arb_poly_t poly, arb_srcptr xs, long n, long prec) +{ + _arb_poly_evaluate_vec_iter(ys, poly->coeffs, + poly->length, xs, n, prec); +} diff --git a/arb_poly/exp_series.c b/arb_poly/exp_series.c new file mode 100644 index 000000000..a4d42c3fb --- /dev/null +++ b/arb_poly/exp_series.c @@ -0,0 +1,188 @@ +/*============================================================================= + + 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_poly.h" + +#define NEWTON_EXP_CUTOFF 120 + +/* with inverse=1 simultaneously computes g = exp(-x) to length n +with inverse=0 uses g as scratch space, computing +g = exp(-x) only to length (n+1)/2 */ +static void +_arb_poly_exp_series_newton(arb_ptr f, arb_ptr g, + arb_srcptr h, long len, long prec, int inverse, long cutoff) +{ + long alloc; + arb_ptr T, U, hprime; + + alloc = 3 * len; + T = _arb_vec_init(alloc); + U = T + len; + hprime = U + len; + + _arb_poly_derivative(hprime, h, len, prec); + arb_zero(hprime + len - 1); + + NEWTON_INIT(cutoff, len) + + /* f := exp(h) + O(x^m), g := exp(-h) + O(x^m2) */ + NEWTON_BASECASE(n) + _arb_poly_exp_series_basecase(f, h, n, n, prec); + _arb_poly_inv_series(g, f, (n + 1) / 2, (n + 1) / 2, prec); + NEWTON_END_BASECASE + + /* extend from length m to length n */ + NEWTON_LOOP(m, n) + + long m2 = (m + 1) / 2; + long l = m - 1; /* shifted for derivative */ + + /* g := exp(-h) + O(x^m) */ + _arb_poly_mullow(T, f, m, g, m2, m, prec); + _arb_poly_mullow(g + m2, g, m2, T + m2, m - m2, m - m2, prec); + _arb_vec_neg(g + m2, g + m2, m - m2); + + /* U := h' + g (f' - f h') + O(x^(n-1)) + Note: should replace h' by h' mod x^(m-1) */ + _arb_vec_zero(f + m, n - m); + _arb_poly_mullow(T, f, n, hprime, n, n, prec); /* should be mulmid */ + _arb_poly_derivative(U, f, n, prec); arb_zero(U + n - 1); /* should skip low terms */ + _arb_vec_sub(U + l, U + l, T + l, n - l, prec); + _arb_poly_mullow(T + l, g, n - m, U + l, n - m, n - m, prec); + _arb_vec_add(U + l, hprime + l, T + l, n - m, prec); + + /* f := f + f * (h - int U) + O(x^n) = exp(h) + O(x^n) */ + _arb_poly_integral(U, U, n, prec); /* should skip low terms */ + _arb_vec_sub(U + m, h + m, U + m, n - m, prec); + _arb_poly_mullow(f + m, f, n - m, U + m, n - m, n - m, prec); + + /* g := exp(-h) + O(x^n) */ + /* not needed if we only want exp(x) */ + if (n == len && inverse) + { + _arb_poly_mullow(T, f, n, g, m, n, prec); + _arb_poly_mullow(g + m, g, m, T + m, n - m, n - m, prec); + _arb_vec_neg(g + m, g + m, n - m); + } + + NEWTON_END_LOOP + + NEWTON_END + + _arb_vec_clear(T, alloc); +} + +void +_arb_poly_exp_series(arb_ptr f, arb_srcptr h, long hlen, long n, long prec) +{ + hlen = FLINT_MIN(hlen, n); + + if (hlen == 1) + { + arb_exp(f, h, prec); + _arb_vec_zero(f + 1, n - 1); + } + else if (n == 2) + { + arb_exp(f, h, prec); + arb_mul(f + 1, f, h + 1, prec); /* safe since hlen >= 2 */ + } + else if (_arb_vec_is_zero(h + 1, hlen - 2)) /* h = a + bx^d */ + { + long i, j, d = hlen - 1; + arb_t t; + arb_init(t); + arb_set(t, h + d); + arb_exp(f, h, prec); + for (i = 1, j = d; j < n; j += d, i++) + { + arb_mul(f + j, f + j - d, t, prec); + arb_div_ui(f + j, f + j, i, prec); + _arb_vec_zero(f + j - d + 1, hlen - 2); + } + _arb_vec_zero(f + j - d + 1, n - (j - d + 1)); + arb_clear(t); + } + else if (hlen <= NEWTON_EXP_CUTOFF) + { + _arb_poly_exp_series_basecase(f, h, hlen, n, prec); + } + else + { + arb_ptr g, t; + arb_t u; + int fix; + + g = _arb_vec_init((n + 1) / 2); + fix = (hlen < n || h == f || !arb_is_zero(h)); + + if (fix) + { + t = _arb_vec_init(n); + _arb_vec_set(t + 1, h + 1, hlen - 1); + } + else + t = (arb_ptr) h; + + arb_init(u); + arb_exp(u, h, prec); + + _arb_poly_exp_series_newton(f, g, t, n, prec, 0, NEWTON_EXP_CUTOFF); + + if (!arb_is_one(u)) + _arb_vec_scalar_mul(f, f, n, u, prec); + + _arb_vec_clear(g, (n + 1) / 2); + if (fix) + _arb_vec_clear(t, n); + arb_clear(u); + } +} + +void +arb_poly_exp_series(arb_poly_t f, const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (n == 0) + { + arb_poly_zero(f); + return; + } + + if (hlen == 0) + { + arb_poly_one(f); + return; + } + + if (hlen == 1) + n = 1; + + arb_poly_fit_length(f, n); + _arb_poly_exp_series(f->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(f, n); + _arb_poly_normalise(f); +} diff --git a/arb_poly/exp_series_basecase.c b/arb_poly/exp_series_basecase.c new file mode 100644 index 000000000..1256942cb --- /dev/null +++ b/arb_poly/exp_series_basecase.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_poly.h" + +#define MUL_CUTOFF 24 + +static void +_arb_poly_exp_series_basecase_rec(arb_ptr f, arb_ptr a, + arb_srcptr h, long hlen, long n, long prec) +{ + long j, k; + + arb_t s; + arb_init(s); + + arb_exp(f, h, prec); + + for (k = 1; k < hlen; k++) + arb_mul_ui(a + k, h + k, k, prec); + + for (k = 1; k < n; k++) + { + arb_zero(s); + for (j = 1; j < FLINT_MIN(k + 1, hlen); j++) + arb_addmul(s, a + j, f + k - j, prec); + + arb_div_ui(f + k, s, k, prec); + } + + arb_clear(s); +} + +void +_arb_poly_exp_series_basecase(arb_ptr f, + arb_srcptr h, long hlen, long n, long prec) +{ + hlen = FLINT_MIN(n, hlen); + + if (n < MUL_CUTOFF || hlen < 0.9 * n) + { + arb_ptr t = _arb_vec_init(hlen); + _arb_poly_exp_series_basecase_rec(f, t, h, hlen, n, prec); + _arb_vec_clear(t, hlen); + } + else + { + long m, v; + arb_ptr t, u; + + m = (n + 2) / 3; + v = m * 2; + + t = _arb_vec_init(n); + u = _arb_vec_init(n - m); + + _arb_poly_mullow(t, h + m, hlen - m, h + m, hlen - m, n - v, prec); + _arb_vec_scalar_mul_2exp_si(t, t, n - v, -1); + + _arb_vec_set(u, h + m, v - m); + _arb_poly_add(u + v - m, t, n - v, h + v, hlen - v, prec); + _arb_poly_exp_series_basecase_rec(f, t, h, m, n, prec); + _arb_poly_mullow(t, f, n, u, n - m, n - m, prec); + _arb_poly_add(f + m, f + m, n - m, t, n - m, prec); + + _arb_vec_clear(t, n); + _arb_vec_clear(u, n - m); + } +} + +void +arb_poly_exp_series_basecase(arb_poly_t f, const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (n == 0) + { + arb_poly_zero(f); + return; + } + + if (hlen == 0) + { + arb_poly_one(f); + return; + } + + arb_poly_fit_length(f, n); + _arb_poly_exp_series_basecase(f->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(f, n); + _arb_poly_normalise(f); +} diff --git a/arb_poly/fit_length.c b/arb_poly/fit_length.c new file mode 100644 index 000000000..184743486 --- /dev/null +++ b/arb_poly/fit_length.c @@ -0,0 +1,46 @@ +/*============================================================================= + + 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_poly.h" + +void +arb_poly_fit_length(arb_poly_t poly, long len) +{ + long i; + + if (len > poly->alloc) + { + if (len < 2 * poly->alloc) + len = 2 * poly->alloc; + + poly->coeffs = flint_realloc(poly->coeffs, + len * sizeof(arb_struct)); + + for (i = poly->alloc; i < len; i++) + arb_init(poly->coeffs + i); + + poly->alloc = len; + } +} diff --git a/arb_poly/get_coeff_fmprb.c b/arb_poly/get_coeff_fmprb.c new file mode 100644 index 000000000..2f71b2614 --- /dev/null +++ b/arb_poly/get_coeff_fmprb.c @@ -0,0 +1,36 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +arb_poly_get_coeff_arb(arb_t x, const arb_poly_t poly, long n) +{ + if (n < poly->length) + arb_set(x, poly->coeffs + n); + else + arb_zero(x); +} + diff --git a/arb_poly/init.c b/arb_poly/init.c new file mode 100644 index 000000000..bd7a1bde3 --- /dev/null +++ b/arb_poly/init.c @@ -0,0 +1,41 @@ +/*============================================================================= + + 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_poly.h" + +void +arb_poly_init(arb_poly_t poly) +{ + poly->coeffs = NULL; + poly->length = 0; + poly->alloc = 0; +} + +void +arb_poly_init2(arb_poly_t poly, long len) +{ + arb_poly_init(poly); + arb_poly_fit_length(poly, len); +} diff --git a/arb_poly/integral.c b/arb_poly/integral.c new file mode 100644 index 000000000..4c14d3d37 --- /dev/null +++ b/arb_poly/integral.c @@ -0,0 +1,46 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_integral(arb_ptr res, arb_srcptr poly, long len, long prec) +{ + long k = len - 1; + + for (k = len - 1; k > 0; k--) + arb_div_ui(res + k, poly + k - 1, k, prec); + + arb_zero(res); +} + +void +arb_poly_integral(arb_poly_t res, const arb_poly_t poly, long prec) +{ + arb_poly_fit_length(res, poly->length + 1); + _arb_poly_integral(res->coeffs, poly->coeffs, poly->length + 1, prec); + _arb_poly_set_length(res, poly->length + 1); + _arb_poly_normalise(res); +} diff --git a/arb_poly/interpolate_barycentric.c b/arb_poly/interpolate_barycentric.c new file mode 100644 index 000000000..41200f450 --- /dev/null +++ b/arb_poly/interpolate_barycentric.c @@ -0,0 +1,96 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_interpolate_barycentric(arb_ptr poly, + arb_srcptr xs, arb_srcptr ys, long n, long prec) +{ + arb_ptr P, Q, w; + arb_t t; + long i, j; + + if (n == 1) + { + arb_set(poly, ys); + return; + } + + P = _arb_vec_init(n + 1); + Q = _arb_vec_init(n); + w = _arb_vec_init(n); + arb_init(t); + + _arb_poly_product_roots(P, xs, n, prec); + + for (i = 0; i < n; i++) + { + arb_one(w + i); + + for (j = 0; j < n; j++) + { + if (i != j) + { + arb_sub(t, xs + i, xs + j, prec); + arb_mul(w + i, w + i, t, prec); + } + } + + arb_inv(w + i, w + i, prec); + } + + _arb_vec_zero(poly, n); + + for (i = 0; i < n; i++) + { + _arb_poly_div_root(Q, t, P, n + 1, xs + i, prec); + arb_mul(t, w + i, ys + i, prec); + _arb_vec_scalar_addmul(poly, Q, n, t, prec); + } + + _arb_vec_clear(P, n + 1); + _arb_vec_clear(Q, n); + _arb_vec_clear(w, n); + arb_clear(t); +} + +void +arb_poly_interpolate_barycentric(arb_poly_t poly, + arb_srcptr xs, arb_srcptr ys, long n, long prec) +{ + if (n == 0) + { + arb_poly_zero(poly); + } + else + { + arb_poly_fit_length(poly, n); + _arb_poly_set_length(poly, n); + _arb_poly_interpolate_barycentric(poly->coeffs, + xs, ys, n, prec); + _arb_poly_normalise(poly); + } +} diff --git a/arb_poly/interpolate_fast.c b/arb_poly/interpolate_fast.c new file mode 100644 index 000000000..14b008873 --- /dev/null +++ b/arb_poly/interpolate_fast.c @@ -0,0 +1,141 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_interpolation_weights(arb_ptr w, + arb_ptr * tree, long len, long prec) +{ + arb_ptr tmp; + long i, n, height; + + if (len == 0) + return; + + if (len == 1) + { + arb_one(w); + return; + } + + tmp = _arb_vec_init(len + 1); + height = FLINT_CLOG2(len); + n = 1L << (height - 1); + + _arb_poly_mul_monic(tmp, tree[height-1], n + 1, + tree[height-1] + (n + 1), (len - n + 1), prec); + + _arb_poly_derivative(tmp, tmp, len + 1, prec); + _arb_poly_evaluate_vec_fast_precomp(w, tmp, len, tree, len, prec); + + for (i = 0; i < len; i++) + arb_inv(w + i, w + i, prec); + + _arb_vec_clear(tmp, len + 1); +} + +void +_arb_poly_interpolate_fast_precomp(arb_ptr poly, + arb_srcptr ys, arb_ptr * tree, arb_srcptr weights, + long len, long prec) +{ + arb_ptr t, u, pa, pb; + long i, pow, left; + + if (len == 0) + return; + + t = _arb_vec_init(len); + u = _arb_vec_init(len); + + for (i = 0; i < len; i++) + arb_mul(poly + i, weights + i, ys + i, prec); + + for (i = 0; i < FLINT_CLOG2(len); i++) + { + pow = (1L << i); + pa = tree[i]; + pb = poly; + left = len; + + while (left >= 2 * pow) + { + _arb_poly_mul(t, pa, pow + 1, pb + pow, pow, prec); + _arb_poly_mul(u, pa + pow + 1, pow + 1, pb, pow, prec); + _arb_vec_add(pb, t, u, 2 * pow, prec); + + left -= 2 * pow; + pa += 2 * pow + 2; + pb += 2 * pow; + } + + if (left > pow) + { + _arb_poly_mul(t, pa, pow + 1, pb + pow, left - pow, prec); + _arb_poly_mul(u, pb, pow, pa + pow + 1, left - pow + 1, prec); + _arb_vec_add(pb, t, u, left, prec); + } + } + + _arb_vec_clear(t, len); + _arb_vec_clear(u, len); +} + +void +_arb_poly_interpolate_fast(arb_ptr poly, + arb_srcptr xs, arb_srcptr ys, long len, long prec) +{ + arb_ptr * tree; + arb_ptr w; + + tree = _arb_poly_tree_alloc(len); + _arb_poly_tree_build(tree, xs, len, prec); + + w = _arb_vec_init(len); + _arb_poly_interpolation_weights(w, tree, len, prec); + + _arb_poly_interpolate_fast_precomp(poly, ys, tree, w, len, prec); + + _arb_vec_clear(w, len); + _arb_poly_tree_free(tree, len); +} + +void +arb_poly_interpolate_fast(arb_poly_t poly, + arb_srcptr xs, arb_srcptr ys, long n, long prec) +{ + if (n == 0) + { + arb_poly_zero(poly); + } + else + { + arb_poly_fit_length(poly, n); + _arb_poly_set_length(poly, n); + _arb_poly_interpolate_fast(poly->coeffs, xs, ys, n, prec); + _arb_poly_normalise(poly); + } +} diff --git a/arb_poly/interpolate_newton.c b/arb_poly/interpolate_newton.c new file mode 100644 index 000000000..c38fb7d8d --- /dev/null +++ b/arb_poly/interpolate_newton.c @@ -0,0 +1,119 @@ +/*============================================================================= + + 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_poly.h" + +static void +_interpolate_newton(arb_ptr ys, arb_srcptr xs, long n, long prec) +{ + arb_t p, q, t; + long i, j; + + arb_init(p); + arb_init(q); + arb_init(t); + + for (i = 1; i < n; i++) + { + arb_set(t, ys + i - 1); + + for (j = i; j < n; j++) + { + arb_sub(p, ys + j, t, prec); + arb_sub(q, xs + j, xs + j - i, prec); + arb_set(t, ys + j); + arb_div(ys + j, p, q, prec); + } + } + + arb_clear(p); + arb_clear(q); + arb_clear(t); +} + +static void +_newton_to_monomial(arb_ptr ys, arb_srcptr xs, long n, long prec) +{ + arb_t t, u; + long i, j; + + arb_init(t); + arb_init(u); + + for (i = n - 2; i >= 0; i--) + { + arb_set(t, ys + i); + arb_set(ys + i, ys + i + 1); + + for (j = i + 1; j < n - 1; j++) + { + arb_mul(u, ys + j, xs + i, prec); + arb_sub(ys + j, ys + j + 1, u, prec); + } + + arb_mul(u, ys + n - 1, xs + i, prec); + arb_sub(ys + n - 1, t, u, prec); + } + + _arb_poly_reverse(ys, ys, n, n); + + arb_clear(t); + arb_clear(u); +} + +void +_arb_poly_interpolate_newton(arb_ptr poly, arb_srcptr xs, + arb_srcptr ys, long n, long prec) +{ + if (n == 1) + { + arb_set(poly, ys); + } + else + { + _arb_vec_set(poly, ys, n); + _interpolate_newton(poly, xs, n, prec); + while (n > 0 && arb_is_zero(poly + n - 1)) n--; + _newton_to_monomial(poly, xs, n, prec); + } +} + +void +arb_poly_interpolate_newton(arb_poly_t poly, + arb_srcptr xs, arb_srcptr ys, long n, long prec) +{ + if (n == 0) + { + arb_poly_zero(poly); + } + else + { + arb_poly_fit_length(poly, n); + _arb_poly_set_length(poly, n); + _arb_poly_interpolate_newton(poly->coeffs, + xs, ys, n, prec); + _arb_poly_normalise(poly); + } +} diff --git a/arb_poly/inv_borel_transform.c b/arb_poly/inv_borel_transform.c new file mode 100644 index 000000000..81a43def0 --- /dev/null +++ b/arb_poly/inv_borel_transform.c @@ -0,0 +1,57 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_inv_borel_transform(arb_ptr res, arb_srcptr poly, long len, long prec) +{ + long i; + + arb_t t; + arb_init(t); + + arb_one(t); + + for (i = 0; i < len; i++) + { + if (i > 1) + arb_mul_ui(t, t, i, prec); + + arb_mul(res + i, poly + i, t, prec); + } + + arb_clear(t); +} + +void +arb_poly_inv_borel_transform(arb_poly_t res, const arb_poly_t poly, long prec) +{ + arb_poly_fit_length(res, poly->length); + _arb_poly_inv_borel_transform(res->coeffs, poly->coeffs, poly->length, prec); + _arb_poly_set_length(res, poly->length); + _arb_poly_normalise(res); +} + diff --git a/arb_poly/inv_series.c b/arb_poly/inv_series.c new file mode 100644 index 000000000..6ef8ce66a --- /dev/null +++ b/arb_poly/inv_series.c @@ -0,0 +1,92 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +#define MULLOW(z, x, xn, y, yn, nn, prec) \ + if ((xn) >= (yn)) \ + _arb_poly_mullow(z, x, xn, y, yn, nn, prec); \ + else \ + _arb_poly_mullow(z, y, yn, x, xn, nn, prec); \ + +void +_arb_poly_inv_series(arb_ptr Qinv, + arb_srcptr Q, long Qlen, long len, long prec) +{ + arb_inv(Qinv, Q, prec); + + if (Qlen == 1) + { + _arb_vec_zero(Qinv + 1, len - 1); + } + else + { + long Qnlen, Wlen, W2len; + arb_ptr W; + + W = _arb_vec_init(len); + + NEWTON_INIT(1, len) + NEWTON_LOOP(m, n) + + Qnlen = FLINT_MIN(Qlen, n); + Wlen = FLINT_MIN(Qnlen + m - 1, n); + W2len = Wlen - m; + MULLOW(W, Q, Qnlen, Qinv, m, Wlen, prec); + MULLOW(Qinv + m, Qinv, m, W + m, W2len, n - m, prec); + _arb_vec_neg(Qinv + m, Qinv + m, n - m); + + NEWTON_END_LOOP + NEWTON_END + + _arb_vec_clear(W, len); + } +} + +void +arb_poly_inv_series(arb_poly_t Qinv, const arb_poly_t Q, long n, long prec) +{ + if (n == 0 || Q->length == 0) + { + printf("arb_poly_inv_series: require n > 0 and nonzero input\n"); + abort(); + } + + if (Qinv == Q) + { + arb_poly_t t; + arb_poly_init(t); + arb_poly_inv_series(t, Q, n, prec); + arb_poly_swap(Qinv, t); + arb_poly_clear(t); + return; + } + + arb_poly_fit_length(Qinv, n); + _arb_poly_inv_series(Qinv->coeffs, Q->coeffs, Q->length, n, prec); + _arb_poly_set_length(Qinv, n); + _arb_poly_normalise(Qinv); +} + diff --git a/arb_poly/log_series.c b/arb_poly/log_series.c new file mode 100644 index 000000000..a3aff00dc --- /dev/null +++ b/arb_poly/log_series.c @@ -0,0 +1,103 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_log_series(arb_ptr res, arb_srcptr f, long flen, long n, long prec) +{ + flen = FLINT_MIN(flen, n); + + if (flen == 1) + { + arb_log(res, f, prec); + _arb_vec_zero(res + 1, n - 1); + } + else if (n == 2) + { + arb_div(res + 1, f + 1, f + 0, prec); /* safe since hlen >= 2 */ + arb_log(res, f, prec); + } + else if (_arb_vec_is_zero(f + 1, flen - 2)) /* f = a + bx^d */ + { + long i, j, d = flen - 1; + + for (i = 1, j = d; j < n; j += d, i++) + { + if (i == 1) + arb_div(res + j, f + d, f + 0, prec); + else + arb_mul(res + j, res + j - d, res + d, prec); + _arb_vec_zero(res + j - d + 1, flen - 2); + } + _arb_vec_zero(res + j - d + 1, n - (j - d + 1)); + + for (i = 2, j = 2 * d; j < n; j += d, i++) + arb_div_si(res + j, res + j, i % 2 ? i : -i, prec); + + arb_log(res, f, prec); /* done last to allow aliasing */ + } + else + { + arb_ptr f_diff, f_inv; + arb_t a; + long alloc; + + alloc = n + flen - 1; + f_inv = _arb_vec_init(alloc); + f_diff = f_inv + n; + + arb_init(a); + arb_log(a, f, prec); + + _arb_poly_derivative(f_diff, f, flen, prec); + _arb_poly_inv_series(f_inv, f, flen, n, prec); + _arb_poly_mullow(res, f_inv, n - 1, f_diff, flen - 1, n - 1, prec); + _arb_poly_integral(res, res, n, prec); + arb_swap(res, a); + + arb_clear(a); + _arb_vec_clear(f_inv, alloc); + } +} + +void +arb_poly_log_series(arb_poly_t res, const arb_poly_t f, long n, long prec) +{ + if (n == 0) + { + arb_poly_zero(res); + return; + } + + arb_poly_fit_length(res, n); + if (f->length == 0) + _arb_vec_indeterminate(res->coeffs, n); + else + _arb_poly_log_series(res->coeffs, f->coeffs, f->length, n, prec); + _arb_poly_set_length(res, n); + _arb_poly_normalise(res); +} + diff --git a/arb_poly/mul.c b/arb_poly/mul.c new file mode 100644 index 000000000..38d635ecf --- /dev/null +++ b/arb_poly/mul.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_poly.h" + +void _arb_poly_mul(arb_ptr C, + arb_srcptr A, long lenA, + arb_srcptr B, long lenB, long prec) +{ + _arb_poly_mullow(C, A, lenA, B, lenB, lenA + lenB - 1, prec); +} + +void +arb_poly_mul(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long prec) +{ + long len_out; + + if ((poly1->length == 0) || (poly2->length == 0)) + { + arb_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + + if (res == poly1 || res == poly2) + { + arb_poly_t temp; + arb_poly_init2(temp, len_out); + _arb_poly_mul(temp->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, prec); + arb_poly_swap(res, temp); + arb_poly_clear(temp); + } + else + { + arb_poly_fit_length(res, len_out); + _arb_poly_mul(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, prec); + } + + _arb_poly_set_length(res, len_out); + _arb_poly_normalise(res); +} diff --git a/arb_poly/mullow.c b/arb_poly/mullow.c new file mode 100644 index 000000000..dd41c3b25 --- /dev/null +++ b/arb_poly/mullow.c @@ -0,0 +1,83 @@ +/*============================================================================= + + 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_poly.h" + +#define BLOCK_CUTOFF 18 + +void +_arb_poly_mullow(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec) +{ + if (n == 1) + { + arb_mul(res, poly1, poly2, prec); + } + else + { + if (n < BLOCK_CUTOFF || len1 < BLOCK_CUTOFF || len2 < BLOCK_CUTOFF) + _arb_poly_mullow_classical(res, poly1, len1, poly2, len2, n, prec); + else + _arb_poly_mullow_block(res, poly1, len1, poly2, len2, n, prec); + } +} + +void +arb_poly_mullow(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, + long n, long prec) +{ + long len_out; + + if (poly1->length == 0 || poly2->length == 0 || n == 0) + { + arb_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + if (n > len_out) + n = len_out; + + if (res == poly1 || res == poly2) + { + arb_poly_t t; + arb_poly_init2(t, n); + _arb_poly_mullow(t->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, n, prec); + arb_poly_swap(res, t); + arb_poly_clear(t); + } + else + { + arb_poly_fit_length(res, n); + _arb_poly_mullow(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, n, prec); + } + + _arb_poly_set_length(res, n); + _arb_poly_normalise(res); +} diff --git a/arb_poly/mullow_block.c b/arb_poly/mullow_block.c new file mode 100644 index 000000000..1dd92c078 --- /dev/null +++ b/arb_poly/mullow_block.c @@ -0,0 +1,803 @@ +/*============================================================================= + + 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 +#include "arb_poly.h" + + +typedef mag_struct * mag_ptr; +typedef const mag_struct * mag_srcptr; + +static __inline__ mag_ptr +_mag_vec_init(long n) +{ + long i; + mag_ptr v = (mag_ptr) flint_malloc(sizeof(mag_struct) * n); + + for (i = 0; i < n; i++) + mag_init(v + i); + + return v; +} + +static __inline__ void +_mag_vec_clear(mag_ptr v, long n) +{ + long i; + for (i = 0; i < n; i++) + mag_clear(v + i); + flint_free(v); +} + +void +arb_get_mag(mag_t z, const arb_t x) +{ + mag_t t; + mag_init_set_arf(t, arb_midref(x)); + mag_add(z, t, arb_radref(x)); + mag_clear(t); +} + +#if 0 + +void +arb_add_fmpz_2exp(arb_t z, const arb_t x, const fmpz_t man, const fmpz_t exp, long prec) +{ + arb_t t; + arb_init(t); + arb_set_fmpz(t, man); + arb_mul_2exp_fmpz(t, t, exp); + arb_add(z, x, t, prec); + arb_clear(t); +} + +#else + +int +arf_add_fmpz_2exp(arf_ptr z, arf_srcptr x, const fmpz_t y, const fmpz_t exp, long prec, arf_rnd_t rnd) +{ + mp_size_t xn, yn; + mp_srcptr xptr, yptr; + mp_limb_t ytmp; + int xsgnbit, ysgnbit, inexact; + fmpz_t yexp; + long shift; + + if (fmpz_is_zero(y)) + { + return arf_set_round(z, x, prec, rnd); + } + else if (arf_is_special(x)) + { + if (arf_is_zero(x)) + { + inexact = arf_set_round_fmpz(z, y, prec, rnd); + arf_mul_2exp_fmpz(z, z, exp); + return inexact; + } + else + { + arf_set(z, x); + return 0; + } + } + + FMPZ_GET_MPN_READONLY(ysgnbit, yn, yptr, ytmp, *y) + fmpz_init(yexp); + fmpz_add_ui(yexp, exp, yn * FLINT_BITS); + shift = _fmpz_sub_small(ARF_EXPREF(x), yexp); + + xsgnbit = ARF_SGNBIT(x); + ARF_GET_MPN_READONLY(xptr, xn, x); + + if (shift >= 0) + inexact = _arf_add_mpn(z, xptr, xn, xsgnbit, ARF_EXPREF(x), + yptr, yn, ysgnbit, shift, prec, rnd); + else + inexact = _arf_add_mpn(z, yptr, yn, ysgnbit, yexp, + xptr, xn, xsgnbit, -shift, prec, rnd); + + fmpz_clear(yexp); + return inexact; +} + +void +arb_add_fmpz_2exp(arb_t z, const arb_t x, const fmpz_t man, const fmpz_t exp, long prec) +{ + int inexact; + inexact = arf_add_fmpz_2exp(arb_midref(z), arb_midref(x), man, exp, prec, ARB_RND); + if (inexact) + arf_mag_add_ulp(arb_radref(z), arb_radref(x), arb_midref(z), prec); + else + mag_set(arb_radref(z), arb_radref(x)); +} + +#endif + + +void +_arb_poly_get_scale(fmpz_t scale, arb_srcptr x, long xlen, + arb_srcptr y, long ylen) +{ + long xa, xb, ya, yb, den; + + fmpz_zero(scale); + + /* ignore zeros (and infs/nans!); find the first and last + finite nonzero entries to determine the scale */ + xa = 0; + xb = xlen - 1; + while (xa < xlen && arf_is_special(arb_midref(x + xa))) xa++; + while (xb > xa && arf_is_special(arb_midref(x + xb))) xb--; + + ya = 0; + yb = ylen - 1; + while (ya < ylen && arf_is_special(arb_midref(y + ya))) ya++; + while (yb > ya && arf_is_special(arb_midref(y + yb))) yb--; + + /* compute average of exponent differences, weighted by the lengths */ + if (xa <= xb && ya <= yb && (xa < xb || ya < yb)) + { + fmpz_add(scale, scale, ARF_EXPREF(arb_midref(x + xb))); + fmpz_sub(scale, scale, ARF_EXPREF(arb_midref(x + xa))); + fmpz_add(scale, scale, ARF_EXPREF(arb_midref(y + yb))); + fmpz_sub(scale, scale, ARF_EXPREF(arb_midref(y + ya))); + + den = (xb - xa) + (yb - ya); + + /* scale = floor(scale / den + 1/2) = floor((2 scale + den) / (2 den)) */ + fmpz_mul_2exp(scale, scale, 1); + fmpz_add_ui(scale, scale, den); + fmpz_fdiv_q_ui(scale, scale, 2 * den); + } +} + +static int +_arb_vec_is_finite(arb_srcptr x, long len) +{ + long i; + + for (i = 0; i < len; i++) + if (!arb_is_finite(x + i)) + return 0; + + return 1; +} + +/* Break vector into same-exponent blocks where the largest block + has a height of at most ALPHA*prec + BETA bits. These are just + tuning parameters. Note that ALPHA * MAG_BITS + BETA + should be smaller than DOUBLE_BLOCK_MAX_HEIGHT if we want to use + doubles for error bounding. */ +#define ALPHA 3.0 +#define BETA 512 + + +/* Maximum length of block for which we use double multiplication + (for longer blocks, we use fmpz_poly multiplication). This is essentially + just a tuning parameter, but note that it must be considered when + compensating for rounding error below. */ +#define DOUBLE_BLOCK_MAX_LENGTH 1000 + +/* Computing a dot product of length DOUBLE_BLOCK_MAX_LENGTH involving + only nonnegative numbers, and then multiplying by this factor, must give + an upper bound for the exact dot product (we can assume that no + overflow or underflow occurs). The following is certainly + sufficient, but it would be nice to include a formal proof here. */ +#define DOUBLE_ROUNDING_FACTOR (1.0 + 1e-9) + +/* Maximum height for which we use double multiplication. Since the dynamic + exponent range of doubles is about +/- 1024, this must be less than about + 1024 (to allow the product of two numbers). This must also + account for adding MAG_BITS bits. */ +#define DOUBLE_BLOCK_MAX_HEIGHT 800 + +/* We divide coefficients by 2^DOUBLE_BLOCK_SHIFT when converting them to + doubles, in order to use the whole exponent range. Note that this means + numbers of size (2^(-DOUBLE_BLOCK_SHIFT))^2 must not underflow. */ +#define DOUBLE_BLOCK_SHIFT (DOUBLE_BLOCK_MAX_HEIGHT / 2) + + +static __inline__ void +_mag_vec_get_fmpz_2exp_blocks(fmpz * coeffs, + double * dblcoeffs, fmpz * exps, long * blocks, const fmpz_t scale, + arb_srcptr x, mag_srcptr xm, long len) +{ + fmpz_t top, bot, t, b, v, block_top, block_bot; + long i, j, s, block, bits, maxheight; + int in_zero; + mag_srcptr cur; + + fmpz_init(top); + fmpz_init(bot); + fmpz_init(t); + fmpz_init(b); + fmpz_init(v); + fmpz_init(block_top); + fmpz_init(block_bot); + + blocks[0] = 0; + block = 0; + in_zero = 1; + + maxheight = ALPHA * MAG_BITS + BETA; + if (maxheight > DOUBLE_BLOCK_MAX_HEIGHT) + abort(); + + for (i = 0; i < len; i++) + { + cur = (x == NULL) ? (xm + i) : arb_radref(x + i); + + /* Skip (must be zero, since we assume there are no Infs/NaNs). */ + if (mag_is_special(cur)) + continue; + + /* Bottom and top exponent of current number */ + bits = MAG_BITS; + fmpz_set(top, MAG_EXPREF(cur)); + fmpz_submul_ui(top, scale, i); + fmpz_sub_ui(bot, top, bits); + + /* Extend current block. */ + if (in_zero) + { + fmpz_swap(block_top, top); + fmpz_swap(block_bot, bot); + } + else + { + fmpz_max(t, top, block_top); + fmpz_min(b, bot, block_bot); + fmpz_sub(v, t, b); + + /* extend current block */ + if (fmpz_cmp_ui(v, maxheight) < 0) + { + fmpz_swap(block_top, t); + fmpz_swap(block_bot, b); + } + else /* start new block */ + { + /* write exponent for previous block */ + fmpz_set(exps + block, block_bot); + + block++; + blocks[block] = i; + + fmpz_swap(block_top, top); + fmpz_swap(block_bot, bot); + } + } + + in_zero = 0; + } + + /* write exponent for last block */ + fmpz_set(exps + block, block_bot); + + /* end marker */ + blocks[block + 1] = len; + + /* write the block data */ + for (i = 0; blocks[i] != len; i++) + { + for (j = blocks[i]; j < blocks[i + 1]; j++) + { + cur = (x == NULL) ? (xm + j) : arb_radref(x + j); + + if (mag_is_special(cur)) + { + fmpz_zero(coeffs + j); + dblcoeffs[j] = 0.0; + } + else + { + mp_limb_t man; + double c; + + man = MAG_MAN(cur); + + /* TODO: only write and use doubles when block is short? */ + + /* Divide by 2^(scale * j) */ + fmpz_mul_ui(t, scale, j); + fmpz_sub(t, MAG_EXPREF(cur), t); + + fmpz_sub_ui(t, t, MAG_BITS); /* bottom exponent */ + s = _fmpz_sub_small(t, exps + i); + + if (s < 0) abort(); /* Bug catcher */ + + fmpz_set_ui(coeffs + j, man); + fmpz_mul_2exp(coeffs + j, coeffs + j, s); + c = man; + c = ldexp(c, s - DOUBLE_BLOCK_SHIFT); + if (c < 1e-150 || c > 1e150) /* Bug catcher */ + abort(); + dblcoeffs[j] = c; + } + } + } + + fmpz_clear(top); + fmpz_clear(bot); + fmpz_clear(t); + fmpz_clear(b); + fmpz_clear(v); + fmpz_clear(block_top); + fmpz_clear(block_bot); +} + +static __inline__ void +_arb_vec_get_fmpz_2exp_blocks(fmpz * coeffs, fmpz * exps, + long * blocks, const fmpz_t scale, arb_srcptr x, long len, long prec) +{ + fmpz_t top, bot, t, b, v, block_top, block_bot; + long i, j, s, block, bits, maxheight; + int in_zero; + + fmpz_init(top); + fmpz_init(bot); + fmpz_init(t); + fmpz_init(b); + fmpz_init(v); + fmpz_init(block_top); + fmpz_init(block_bot); + + blocks[0] = 0; + block = 0; + in_zero = 1; + + if (prec == ARF_PREC_EXACT) + maxheight = ARF_PREC_EXACT; + else + maxheight = ALPHA * prec + BETA; + + for (i = 0; i < len; i++) + { + bits = arf_bits(arb_midref(x + i)); + + /* Skip (must be zero, since we assume there are no Infs/NaNs). */ + if (bits == 0) + continue; + + /* Bottom and top exponent of current number */ + fmpz_set(top, ARF_EXPREF(arb_midref(x + i))); + fmpz_submul_ui(top, scale, i); + fmpz_sub_ui(bot, top, bits); + + /* Extend current block. */ + if (in_zero) + { + fmpz_swap(block_top, top); + fmpz_swap(block_bot, bot); + } + else + { + fmpz_max(t, top, block_top); + fmpz_min(b, bot, block_bot); + fmpz_sub(v, t, b); + + /* extend current block */ + if (fmpz_cmp_ui(v, maxheight) < 0) + { + fmpz_swap(block_top, t); + fmpz_swap(block_bot, b); + } + else /* start new block */ + { + /* write exponent for previous block */ + fmpz_set(exps + block, block_bot); + + block++; + blocks[block] = i; + + fmpz_swap(block_top, top); + fmpz_swap(block_bot, bot); + } + } + + in_zero = 0; + } + + /* write exponent for last block */ + fmpz_set(exps + block, block_bot); + + /* end marker */ + blocks[block + 1] = len; + + /* write the block data */ + for (i = 0; blocks[i] != len; i++) + { + for (j = blocks[i]; j < blocks[i + 1]; j++) + { + if (arf_is_special(arb_midref(x + j))) + { + fmpz_zero(coeffs + j); + } + else + { + /* TODO: make this a single operation */ + arf_get_fmpz_2exp(coeffs + j, bot, arb_midref(x + j)); + + fmpz_mul_ui(t, scale, j); + fmpz_sub(t, bot, t); + s = _fmpz_sub_small(t, exps + i); + if (s < 0) abort(); /* Bug catcher */ + fmpz_mul_2exp(coeffs + j, coeffs + j, s); + } + } + } + + fmpz_clear(top); + fmpz_clear(bot); + fmpz_clear(t); + fmpz_clear(b); + fmpz_clear(v); + fmpz_clear(block_top); + fmpz_clear(block_bot); +} + +static __inline__ void +_arb_poly_addmullow_rad(arb_ptr z, fmpz * zz, + const fmpz * xz, const double * xdbl, const fmpz * xexps, + const long * xblocks, long xlen, + const fmpz * yz, const double * ydbl, const fmpz * yexps, + const long * yblocks, long ylen, long n) +{ + long i, j, k, ii, xp, yp, xl, yl, bn; + fmpz_t zexp; + mag_t t; + + fmpz_init(zexp); + mag_init(t); + + for (i = 0; (xp = xblocks[i]) != xlen; i++) + { + for (j = 0; (yp = yblocks[j]) != ylen; j++) + { + if (xp + yp >= n) + continue; + + xl = xblocks[i + 1] - xp; + yl = yblocks[j + 1] - yp; + bn = FLINT_MIN(xl + yl - 1, n - xp - yp); + xl = FLINT_MIN(xl, bn); + yl = FLINT_MIN(yl, bn); + + fmpz_add_inline(zexp, xexps + i, yexps + j); + + if (xl > 1 && yl > 1 && + (xl < DOUBLE_BLOCK_MAX_LENGTH || yl < DOUBLE_BLOCK_MAX_LENGTH)) + { + fmpz_add_ui(zexp, zexp, 2 * DOUBLE_BLOCK_SHIFT); + + for (k = 0; k < bn; k++) + { + /* Classical multiplication (may round down!) */ + double ss = 0.0; + + for (ii = FLINT_MAX(0, k - yl + 1); + ii <= FLINT_MIN(xl - 1, k); ii++) + { + ss += xdbl[xp + ii] * ydbl[yp + k - ii]; + } + + /* Compensate for rounding error */ + ss *= DOUBLE_ROUNDING_FACTOR; + + mag_set_d_2exp_fmpz(t, ss, zexp); + mag_add(arb_radref(z + xp + yp + k), + arb_radref(z + xp + yp + k), t); + } + } + else + { + if (xl >= yl) + _fmpz_poly_mullow(zz, xz + xp, xl, yz + yp, yl, bn); + else + _fmpz_poly_mullow(zz, yz + yp, yl, xz + xp, xl, bn); + + for (k = 0; k < bn; k++) + { + mag_set_fmpz_2exp_fmpz(t, zz + k, zexp); + mag_add(arb_radref(z + xp + yp + k), + arb_radref(z + xp + yp + k), t); + } + } + } + } + + fmpz_clear(zexp); + mag_clear(t); +} + +static __inline__ void +_arb_poly_addmullow_block(arb_ptr z, fmpz * zz, + const fmpz * xz, const fmpz * xexps, const long * xblocks, long xlen, + const fmpz * yz, const fmpz * yexps, const long * yblocks, long ylen, + long n, long prec, int squaring) +{ + long i, j, k, xp, yp, xl, yl, bn; + fmpz_t zexp; + + fmpz_init(zexp); + + if (squaring) + { + for (i = 0; (xp = xblocks[i]) != xlen; i++) + { + if (2 * xp >= n) + continue; + + xl = xblocks[i + 1] - xp; + bn = FLINT_MIN(2 * xl - 1, n - 2 * xp); + xl = FLINT_MIN(xl, bn); + + _fmpz_poly_sqrlow(zz, xz + xp, xl, bn); + _fmpz_add2_fast(zexp, xexps + i, xexps + i, 0); + + for (k = 0; k < bn; k++) + arb_add_fmpz_2exp(z + 2 * xp + k, z + 2 * xp + k, zz + k, zexp, prec); + } + } + + for (i = 0; (xp = xblocks[i]) != xlen; i++) + { + for (j = squaring ? i + 1 : 0; (yp = yblocks[j]) != ylen; j++) + { + if (xp + yp >= n) + continue; + + xl = xblocks[i + 1] - xp; + yl = yblocks[j + 1] - yp; + bn = FLINT_MIN(xl + yl - 1, n - xp - yp); + xl = FLINT_MIN(xl, bn); + yl = FLINT_MIN(yl, bn); + + if (xl >= yl) + _fmpz_poly_mullow(zz, xz + xp, xl, yz + yp, yl, bn); + else + _fmpz_poly_mullow(zz, yz + yp, yl, xz + xp, xl, bn); + + _fmpz_add2_fast(zexp, xexps + i, yexps + j, squaring); + + for (k = 0; k < bn; k++) + arb_add_fmpz_2exp(z + xp + yp + k, z + xp + yp + k, zz + k, zexp, prec); + } + } + + fmpz_clear(zexp); +} + +void +_arb_poly_mullow_block(arb_ptr z, arb_srcptr x, long xlen, + arb_srcptr y, long ylen, long n, long prec) +{ + long xmlen, xrlen, ymlen, yrlen, i; + fmpz *xz, *yz, *zz; + fmpz *xe, *ye; + long *xblocks, *yblocks; + int squaring; + fmpz_t scale, t; + + xlen = FLINT_MIN(xlen, n); + ylen = FLINT_MIN(ylen, n); + + squaring = (x == y) && (xlen == ylen); + + /* Strip trailing zeros */ + xmlen = xrlen = xlen; + while (xmlen > 0 && arf_is_zero(arb_midref(x + xmlen - 1))) xmlen--; + while (xrlen > 0 && mag_is_zero(arb_radref(x + xrlen - 1))) xrlen--; + + if (squaring) + { + ymlen = xmlen; + yrlen = xrlen; + } + else + { + ymlen = yrlen = ylen; + while (ymlen > 0 && arf_is_zero(arb_midref(y + ymlen - 1))) ymlen--; + while (yrlen > 0 && mag_is_zero(arb_radref(y + yrlen - 1))) yrlen--; + } + + /* We don't know how to deal with infinities or NaNs */ + if (!_arb_vec_is_finite(x, xlen) || + (!squaring && !_arb_vec_is_finite(y, ylen))) + { + _arb_poly_mullow_classical(z, x, xlen, y, ylen, n, prec); + return; + } + + xlen = FLINT_MAX(xmlen, xrlen); + ylen = FLINT_MAX(ymlen, yrlen); + + /* Start with the zero polynomial */ + _arb_vec_zero(z, n); + + /* Nothing to do */ + if (xlen == 0 || ylen == 0) + return; + + n = FLINT_MIN(n, xlen + ylen - 1); + + fmpz_init(scale); + fmpz_init(t); + xz = _fmpz_vec_init(xlen); + yz = _fmpz_vec_init(ylen); + zz = _fmpz_vec_init(n); + xe = _fmpz_vec_init(xlen); + ye = _fmpz_vec_init(ylen); + xblocks = flint_malloc(sizeof(long) * (xlen + 1)); + yblocks = flint_malloc(sizeof(long) * (ylen + 1)); + + _arb_poly_get_scale(scale, x, xlen, y, ylen); + + /* Error propagation */ + /* (xm + xr)*(ym + yr) = (xm*ym) + (xr*ym + xm*yr + xr*yr) + = (xm*ym) + (xm*yr + xr*(ym + yr)) */ + if (xrlen != 0 || yrlen != 0) + { + mag_ptr tmp; + double *xdbl, *ydbl; + + tmp = _mag_vec_init(FLINT_MAX(xlen, ylen)); + xdbl = flint_malloc(sizeof(double) * xlen); + ydbl = flint_malloc(sizeof(double) * ylen); + + /* (xm + xr)^2 = (xm*ym) + (xr^2 + 2 xm xr) + = (xm*ym) + xr*(2 xm + xr) */ + if (squaring) + { + _mag_vec_get_fmpz_2exp_blocks(xz, xdbl, xe, xblocks, scale, x, NULL, xrlen); + + for (i = 0; i < xlen; i++) + { + arf_get_mag(tmp + i, arb_midref(x + i)); + mag_mul_2exp_si(tmp + i, tmp + i, 1); + mag_add(tmp + i, tmp + i, arb_radref(x + i)); + } + + _mag_vec_get_fmpz_2exp_blocks(yz, ydbl, ye, yblocks, scale, NULL, tmp, xlen); + _arb_poly_addmullow_rad(z, zz, xz, xdbl, xe, xblocks, xrlen, yz, ydbl, ye, yblocks, xlen, n); + } + else if (yrlen == 0) + { + /* xr * |ym| */ + _mag_vec_get_fmpz_2exp_blocks(xz, xdbl, xe, xblocks, scale, x, NULL, xrlen); + + for (i = 0; i < ymlen; i++) + arf_get_mag(tmp + i, arb_midref(y + i)); + + _mag_vec_get_fmpz_2exp_blocks(yz, ydbl, ye, yblocks, scale, NULL, tmp, ymlen); + _arb_poly_addmullow_rad(z, zz, xz, xdbl, xe, xblocks, xrlen, yz, ydbl, ye, yblocks, ymlen, n); + } + else + { + /* |xm| * yr */ + for (i = 0; i < xmlen; i++) + arf_get_mag(tmp + i, arb_midref(x + i)); + + _mag_vec_get_fmpz_2exp_blocks(xz, xdbl, xe, xblocks, scale, NULL, tmp, xmlen); + _mag_vec_get_fmpz_2exp_blocks(yz, ydbl, ye, yblocks, scale, y, NULL, yrlen); + _arb_poly_addmullow_rad(z, zz, xz, xdbl, xe, xblocks, xmlen, yz, ydbl, ye, yblocks, yrlen, n); + + /* xr*(|ym| + yr) */ + if (xrlen != 0) + { + _mag_vec_get_fmpz_2exp_blocks(xz, xdbl, xe, xblocks, scale, x, NULL, xrlen); + + for (i = 0; i < ylen; i++) + arb_get_mag(tmp + i, y + i); + + _mag_vec_get_fmpz_2exp_blocks(yz, ydbl, ye, yblocks, scale, NULL, tmp, ylen); + _arb_poly_addmullow_rad(z, zz, xz, xdbl, xe, xblocks, xrlen, yz, ydbl, ye, yblocks, ylen, n); + } + } + + _mag_vec_clear(tmp, FLINT_MAX(xlen, ylen)); + flint_free(xdbl); + flint_free(ydbl); + } + + /* multiply midpoints */ + if (xmlen != 0 && ymlen != 0) + { + _arb_vec_get_fmpz_2exp_blocks(xz, xe, xblocks, scale, x, xmlen, prec); + + if (squaring) + { + _arb_poly_addmullow_block(z, zz, xz, xe, xblocks, xmlen, xz, xe, xblocks, xmlen, n, prec, 1); + } + else + { + _arb_vec_get_fmpz_2exp_blocks(yz, ye, yblocks, scale, y, ymlen, prec); + _arb_poly_addmullow_block(z, zz, xz, xe, xblocks, xmlen, yz, ye, yblocks, ymlen, n, prec, 0); + } + } + + /* Unscale. */ + if (!fmpz_is_zero(scale)) + { + fmpz_zero(t); + for (i = 0; i < n; i++) + { + arb_mul_2exp_fmpz(z + i, z + i, t); + fmpz_add(t, t, scale); + } + } + + _fmpz_vec_clear(xz, xlen); + _fmpz_vec_clear(yz, ylen); + _fmpz_vec_clear(zz, n); + _fmpz_vec_clear(xe, xlen); + _fmpz_vec_clear(ye, ylen); + flint_free(xblocks); + flint_free(yblocks); + fmpz_clear(scale); + fmpz_clear(t); +} + +void +arb_poly_mullow_block(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long n, long prec) +{ + long xlen, ylen, zlen; + + xlen = poly1->length; + ylen = poly2->length; + + if (xlen == 0 || ylen == 0 || n == 0) + { + arb_poly_zero(res); + return; + } + + xlen = FLINT_MIN(xlen, n); + ylen = FLINT_MIN(ylen, n); + zlen = FLINT_MIN(xlen + ylen - 1, n); + + if (res == poly1 || res == poly2) + { + arb_poly_t tmp; + arb_poly_init2(tmp, zlen); + _arb_poly_mullow_block(tmp->coeffs, poly1->coeffs, xlen, + poly2->coeffs, ylen, zlen, prec); + arb_poly_swap(res, tmp); + arb_poly_clear(tmp); + } + else + { + arb_poly_fit_length(res, zlen); + _arb_poly_mullow_block(res->coeffs, poly1->coeffs, xlen, + poly2->coeffs, ylen, zlen, prec); + } + + _arb_poly_set_length(res, zlen); + _arb_poly_normalise(res); +} + diff --git a/arb_poly/mullow_classical.c b/arb_poly/mullow_classical.c new file mode 100644 index 000000000..c1b55f733 --- /dev/null +++ b/arb_poly/mullow_classical.c @@ -0,0 +1,111 @@ +/*============================================================================= + + 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) 2008, 2009 William Hart + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_mullow_classical(arb_ptr res, + arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long n, long prec) +{ + len1 = FLINT_MIN(len1, n); + len2 = FLINT_MIN(len2, n); + + if (n == 1) + { + arb_mul(res, poly1, poly2, prec); + } + else if (poly1 == poly2 && len1 == len2) + { + long i; + + _arb_vec_scalar_mul(res, poly1, FLINT_MIN(len1, n), poly1, prec); + _arb_vec_scalar_mul(res + len1, poly1 + 1, n - len1, poly1 + len1 - 1, prec); + + for (i = 1; i < len1 - 1; i++) + _arb_vec_scalar_addmul(res + i + 1, poly1 + 1, + FLINT_MIN(i - 1, n - (i + 1)), poly1 + i, prec); + + for (i = 1; i < FLINT_MIN(2 * len1 - 2, n); i++) + arb_mul_2exp_si(res + i, res + i, 1); + + for (i = 1; i < FLINT_MIN(len1 - 1, (n + 1) / 2); i++) + arb_addmul(res + 2 * i, poly1 + i, poly1 + i, prec); + } + else + { + long i; + + _arb_vec_scalar_mul(res, poly1, FLINT_MIN(len1, n), poly2, prec); + + if (n > len1) + _arb_vec_scalar_mul(res + len1, poly2 + 1, n - len1, + poly1 + len1 - 1, prec); + + for (i = 0; i < FLINT_MIN(len1, n) - 1; i++) + _arb_vec_scalar_addmul(res + i + 1, poly2 + 1, + FLINT_MIN(len2, n - i) - 1, + poly1 + i, prec); + } +} + +void +arb_poly_mullow_classical(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, + long n, long prec) +{ + long len_out; + + if (poly1->length == 0 || poly2->length == 0 || n == 0) + { + arb_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + if (n > len_out) + n = len_out; + + if (res == poly1 || res == poly2) + { + arb_poly_t t; + arb_poly_init2(t, n); + _arb_poly_mullow_classical(t->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, n, prec); + arb_poly_swap(res, t); + arb_poly_clear(t); + } + else + { + arb_poly_fit_length(res, n); + _arb_poly_mullow_classical(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, n, prec); + } + + _arb_poly_set_length(res, n); + _arb_poly_normalise(res); +} diff --git a/arb_poly/newton_convergence_factor.c b/arb_poly/newton_convergence_factor.c new file mode 100644 index 000000000..5e044e932 --- /dev/null +++ b/arb_poly/newton_convergence_factor.c @@ -0,0 +1,55 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_newton_convergence_factor(arf_t convergence_factor, + arb_srcptr poly, long len, + const arb_t convergence_interval, long prec) +{ + arb_ptr deriv; + arb_t t, u; + + arb_init(t); + arb_init(u); + deriv = _arb_vec_init(len - 1); + + _arb_poly_derivative(deriv, poly, len, prec); + _arb_poly_evaluate(t, deriv, len - 1, convergence_interval, prec); + + _arb_poly_derivative(deriv, deriv, len - 1, prec); + _arb_poly_evaluate(u, deriv, len - 2, convergence_interval, prec); + + arb_div(t, u, t, prec); + arb_mul_2exp_si(t, t, -1); + + arb_get_abs_ubound_arf(convergence_factor, t, prec); + + _arb_vec_clear(deriv, len - 1); + arb_clear(t); + arb_clear(u); +} + diff --git a/arb_poly/newton_refine_root.c b/arb_poly/newton_refine_root.c new file mode 100644 index 000000000..189bb2f57 --- /dev/null +++ b/arb_poly/newton_refine_root.c @@ -0,0 +1,77 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +static __inline__ long _arf_mag(const arf_t c) +{ + long m = arf_abs_bound_lt_2exp_si(c); + return FLINT_MAX(m, 0); +} + +void +_arb_poly_newton_refine_root(arb_t r, arb_srcptr poly, long len, + const arb_t start, + const arb_t convergence_interval, + const arf_t convergence_factor, + long eval_extra_prec, + long prec) +{ + long precs[FLINT_BITS]; + long i, iters, wp, padding, start_prec; + + start_prec = arb_rel_accuracy_bits(start); + + padding = 5 + _arf_mag(convergence_factor); + precs[0] = prec + padding; + iters = 1; + while ((iters < FLINT_BITS) && (precs[iters-1] + padding > 2*start_prec)) + { + precs[iters] = (precs[iters-1] / 2) + padding; + iters++; + + if (iters == FLINT_BITS) + { + printf("newton_refine_root: initial value too imprecise\n"); + abort(); + } + } + + arb_set(r, start); + + for (i = iters - 1; i >= 0; i--) + { + wp = precs[i] + eval_extra_prec; + + if (!_arb_poly_newton_step(r, poly, len, r, convergence_interval, + convergence_factor, wp)) + { + printf("warning: newton_refine_root: improvement failed\n"); + break; + } + + } +} + diff --git a/arb_poly/newton_step.c b/arb_poly/newton_step.c new file mode 100644 index 000000000..b8ef27823 --- /dev/null +++ b/arb_poly/newton_step.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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int +_arb_poly_newton_step(arb_t xnew, arb_srcptr poly, long len, + const arb_t x, + const arb_t convergence_interval, + const arf_t convergence_factor, long prec) +{ + arf_t err; + arb_t t, u, v; + int result; + + arf_init(err); + arb_init(t); + arb_init(u); + arb_init(v); + + arf_set_mag(err, arb_radref(x)); + arf_mul(err, err, err, MAG_BITS, ARF_RND_UP); + arf_mul(err, err, convergence_factor, MAG_BITS, ARF_RND_UP); + + arf_set(arb_midref(t), arb_midref(x)); + mag_zero(arb_radref(t)); + + _arb_poly_evaluate2(u, v, poly, len, t, prec); + + arb_div(u, u, v, prec); + arb_sub(u, t, u, prec); + + arb_add_error_arf(u, err); + + if (arb_contains(convergence_interval, u) && + (arf_cmpabs_mag(arb_radref(u), arb_radref(x)) < 0)) + { + arb_swap(xnew, u); + result = 1; + } + else + { + arb_set(xnew, x); + result = 0; + } + + arb_clear(t); + arb_clear(u); + arb_clear(v); + arf_clear(err); + + return result; +} + diff --git a/arb_poly/normalise.c b/arb_poly/normalise.c new file mode 100644 index 000000000..869c0a9dc --- /dev/null +++ b/arb_poly/normalise.c @@ -0,0 +1,37 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_normalise(arb_poly_t poly) +{ + long i; + + for (i = poly->length - 1; + (i >= 0) && arb_is_zero(poly->coeffs + i); i--); + + poly->length = i + 1; +} diff --git a/arb_poly/overlaps.c b/arb_poly/overlaps.c new file mode 100644 index 000000000..3292e748d --- /dev/null +++ b/arb_poly/overlaps.c @@ -0,0 +1,56 @@ +/*============================================================================= + + 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_poly.h" + +int +_arb_poly_overlaps(arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2) +{ + long i; + + for (i = 0; i < len2; i++) + if (!arb_overlaps(poly1 + i, poly2 + i)) + return 0; + + for (i = len2; i < len1; i++) + if (!arb_contains_zero(poly1 + i)) + return 0; + + return 1; +} + +int +arb_poly_overlaps(const arb_poly_t poly1, const arb_poly_t poly2) +{ + long len1 = poly1->length; + long len2 = poly2->length; + + if (len1 >= len2) + return _arb_poly_overlaps(poly1->coeffs, len1, poly2->coeffs, len2); + else + return _arb_poly_overlaps(poly2->coeffs, len2, poly1->coeffs, len1); +} + diff --git a/arb_poly/pow_fmprb_series.c b/arb_poly/pow_fmprb_series.c new file mode 100644 index 000000000..b689a097d --- /dev/null +++ b/arb_poly/pow_fmprb_series.c @@ -0,0 +1,175 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_pow_arb_series(arb_ptr h, + arb_srcptr f, long flen, const arb_t g, long len, long prec) +{ + int f_binomial, g_exact, g_int; + + while (flen > 0 && arb_is_zero(f + flen - 1)) + flen--; + + if (flen <= 1) + { + arb_pow(h, f, g, prec); + _arb_vec_zero(h + 1, len - 1); + return; + } + + g_exact = arb_is_exact(g); + g_int = arb_is_int(g); + f_binomial = _arb_vec_is_zero(f + 1, flen - 2); + + /* g = small integer */ + if (g_exact && g_int && + arf_cmpabs_2exp_si(arb_midref(g), FLINT_BITS - 1) < 0) + { + long e, hlen; + + /* TODO: fixme */ + { + fmpr_t t; + fmpr_init(t); + arf_get_fmpr(t, arb_midref(g)); + e = fmpz_get_si(fmpr_manref(t)) << fmpz_get_ui(fmpr_expref(t)); + fmpr_clear(t); + } + + hlen = poly_pow_length(flen, FLINT_ABS(e), len); + + if (e >= 0) + { + _arb_poly_pow_ui_trunc_binexp(h, f, flen, e, hlen, prec); + _arb_vec_zero(h + hlen, len - hlen); + return; + } + else if (!f_binomial) + { + arb_ptr t; + t = _arb_vec_init(hlen); + _arb_poly_pow_ui_trunc_binexp(t, f, flen, -e, hlen, prec); + _arb_poly_inv_series(h, t, hlen, len, prec); + _arb_vec_clear(t, hlen); + return; + } + } + + /* (a + bx^c)^g */ + if (f_binomial) + { + long i, j, d; + arb_t t; + + arb_init(t); + + d = flen - 1; + arb_pow(h, f, g, prec); + arb_div(t, f + d, f, prec); + + for (i = 1, j = d; j < len; i++, j += d) + { + arb_sub_ui(h + j, g, i - 1, prec); + arb_mul(h + j, h + j, h + j - d, prec); + arb_mul(h + j, h + j, t, prec); + arb_div_ui(h + j, h + j, i, prec); + } + + if (d > 1) + { + for (i = 1; i < len; i++) + if (i % d != 0) + arb_zero(h + i); + } + + arb_clear(t); + return; + } + + /* g = +/- 1/2 */ + if (g_exact && arf_cmpabs_2exp_si(arb_midref(g), -1) == 0) + { + if (arf_sgn(arb_midref(g)) > 0) + _arb_poly_sqrt_series(h, f, flen, len, prec); + else + _arb_poly_rsqrt_series(h, f, flen, len, prec); + return; + } + + /* f^g = exp(g*log(f)) */ + _arb_poly_log_series(h, f, flen, len, prec); + _arb_vec_scalar_mul(h, h, len, g, prec); + _arb_poly_exp_series(h, h, len, len, prec); + +} + +void +arb_poly_pow_arb_series(arb_poly_t h, + const arb_poly_t f, const arb_t g, long len, long prec) +{ + long flen; + + flen = f->length; + flen = FLINT_MIN(flen, len); + + if (len == 0) + { + arb_poly_zero(h); + return; + } + + if (arb_is_zero(g)) + { + arb_poly_one(h); + return; + } + + if (flen == 0) + { + arb_poly_zero(h); + return; + } + + if (f == h) + { + arb_poly_t t; + arb_poly_init2(t, len); + _arb_poly_pow_arb_series(t->coeffs, f->coeffs, flen, g, len, prec); + _arb_poly_set_length(t, len); + _arb_poly_normalise(t); + arb_poly_swap(t, h); + arb_poly_clear(t); + } + else + { + arb_poly_fit_length(h, len); + _arb_poly_pow_arb_series(h->coeffs, f->coeffs, flen, g, len, prec); + _arb_poly_set_length(h, len); + _arb_poly_normalise(h); + } +} + diff --git a/arb_poly/pow_series.c b/arb_poly/pow_series.c new file mode 100644 index 000000000..b955c9ba9 --- /dev/null +++ b/arb_poly/pow_series.c @@ -0,0 +1,120 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_pow_series(arb_ptr h, + arb_srcptr f, long flen, + arb_srcptr g, long glen, long len, long prec) +{ + if (glen == 1) + { + _arb_poly_pow_arb_series(h, f, flen, g, len, prec); + return; + } + + /* f^g = exp(g * log(f)) */ + if (flen == 1) + { + arb_t t; + arb_init(t); + arb_log(t, f, prec); + _arb_vec_scalar_mul(h, g, glen, t, prec); + _arb_poly_exp_series(h, h, glen, len, prec); + arb_clear(t); + } + else + { + arb_ptr t; + t = _arb_vec_init(len); + _arb_poly_log_series(t, f, flen, len, prec); + _arb_poly_mullow(h, t, len, g, glen, len, prec); + _arb_poly_exp_series(h, h, len, len, prec); + _arb_vec_clear(t, len); + + } +} + +void +arb_poly_pow_series(arb_poly_t h, + const arb_poly_t f, const arb_poly_t g, long len, long prec) +{ + long flen, glen; + + flen = f->length; + glen = g->length; + + flen = FLINT_MIN(flen, len); + glen = FLINT_MIN(glen, len); + + if (len == 0) + { + arb_poly_zero(h); + return; + } + + if (glen == 0) + { + arb_poly_one(h); + return; + } + + if (flen == 0) + { + arb_poly_zero(h); + return; + } + + if (flen == 1 && glen == 1) + { + arb_poly_fit_length(h, 1); + arb_pow(h->coeffs, f->coeffs, g->coeffs, prec); + _arb_poly_set_length(h, 1); + _arb_poly_normalise(h); + return; + } + + if (f == h || g == h) + { + arb_poly_t t; + arb_poly_init2(t, len); + _arb_poly_pow_series(t->coeffs, + f->coeffs, flen, g->coeffs, glen, len, prec); + _arb_poly_set_length(t, len); + _arb_poly_normalise(t); + arb_poly_swap(t, h); + arb_poly_clear(t); + } + else + { + arb_poly_fit_length(h, len); + _arb_poly_pow_series(h->coeffs, + f->coeffs, flen, g->coeffs, glen, len, prec); + _arb_poly_set_length(h, len); + _arb_poly_normalise(h); + } +} + diff --git a/arb_poly/pow_ui.c b/arb_poly/pow_ui.c new file mode 100644 index 000000000..00e8c167d --- /dev/null +++ b/arb_poly/pow_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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_pow_ui(arb_ptr res, arb_srcptr f, long flen, ulong exp, long prec) +{ + _arb_poly_pow_ui_trunc_binexp(res, f, flen, exp, exp * (flen - 1) + 1, prec); +} + +void +arb_poly_pow_ui(arb_poly_t res, + const arb_poly_t poly, ulong exp, long prec) +{ + long flen, rlen; + + flen = poly->length; + + if (exp == 0) + { + arb_poly_one(res); + } + else if (flen == 0) + { + arb_poly_zero(res); + } + else + { + rlen = exp * (flen - 1) + 1; + + if (res != poly) + { + arb_poly_fit_length(res, rlen); + _arb_poly_pow_ui(res->coeffs, + poly->coeffs, flen, exp, prec); + _arb_poly_set_length(res, rlen); + _arb_poly_normalise(res); + } + else + { + arb_poly_t t; + arb_poly_init2(t, rlen); + _arb_poly_pow_ui(t->coeffs, + poly->coeffs, flen, exp, prec); + _arb_poly_set_length(t, rlen); + _arb_poly_normalise(t); + arb_poly_swap(res, t); + arb_poly_clear(t); + } + } +} + diff --git a/arb_poly/pow_ui_trunc_binexp.c b/arb_poly/pow_ui_trunc_binexp.c new file mode 100644 index 000000000..62095eaf0 --- /dev/null +++ b/arb_poly/pow_ui_trunc_binexp.c @@ -0,0 +1,167 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +#define MUL(z, zlen, x, xlen, y, ylen, trunc, prec) \ + do { \ + long slen = FLINT_MIN(xlen + ylen - 1, trunc); \ + _arb_poly_mullow(z, x, xlen, y, ylen, slen, prec); \ + zlen = slen; \ + } while (0) + +void +_arb_poly_pow_ui_trunc_binexp(arb_ptr res, + arb_srcptr f, long flen, ulong exp, long len, long prec) +{ + arb_ptr v, R, S, T; + long rlen; + ulong bit; + + if (exp <= 1) + { + if (exp == 0) + arb_one(res); + else if (exp == 1) + _arb_vec_set_round(res, f, len, prec); + return; + } + + /* (f * x^r)^m = x^(rm) * f^m */ + while (flen > 1 && arb_is_zero(f)) + { + if (((ulong) len) > exp) + { + _arb_vec_zero(res, exp); + len -= exp; + res += exp; + } + else + { + _arb_vec_zero(res, len); + return; + } + + f++; + flen--; + } + + if (exp == 2) + { + _arb_poly_mullow(res, f, flen, f, flen, len, prec); + return; + } + + if (flen == 1) + { + arb_pow_ui(res, f, exp, prec); + return; + } + + v = _arb_vec_init(len); + bit = 1UL << (FLINT_BIT_COUNT(exp) - 2); + + if (n_zerobits(exp) % 2) + { + R = res; + S = v; + } + else + { + R = v; + S = res; + } + + MUL(R, rlen, f, flen, f, flen, len, prec); + + if (bit & exp) + { + MUL(S, rlen, R, rlen, f, flen, len, prec); + T = R; + R = S; + S = T; + } + + while (bit >>= 1) + { + if (bit & exp) + { + MUL(S, rlen, R, rlen, R, rlen, len, prec); + MUL(R, rlen, S, rlen, f, flen, len, prec); + } + else + { + MUL(S, rlen, R, rlen, R, rlen, len, prec); + T = R; + R = S; + S = T; + } + } + + _arb_vec_clear(v, len); +} + +void +arb_poly_pow_ui_trunc_binexp(arb_poly_t res, + const arb_poly_t poly, ulong exp, long len, long prec) +{ + long flen, rlen; + + flen = poly->length; + + if (exp == 0 && len != 0) + { + arb_poly_one(res); + } + else if (flen == 0 || len == 0) + { + arb_poly_zero(res); + } + else + { + rlen = poly_pow_length(flen, exp, len); + + if (res != poly) + { + arb_poly_fit_length(res, rlen); + _arb_poly_pow_ui_trunc_binexp(res->coeffs, + poly->coeffs, flen, exp, rlen, prec); + _arb_poly_set_length(res, rlen); + _arb_poly_normalise(res); + } + else + { + arb_poly_t t; + arb_poly_init2(t, rlen); + _arb_poly_pow_ui_trunc_binexp(t->coeffs, + poly->coeffs, flen, exp, rlen, prec); + _arb_poly_set_length(t, rlen); + _arb_poly_normalise(t); + arb_poly_swap(res, t); + arb_poly_clear(t); + } + } +} + diff --git a/arb_poly/printd.c b/arb_poly/printd.c new file mode 100644 index 000000000..f920ac8de --- /dev/null +++ b/arb_poly/printd.c @@ -0,0 +1,46 @@ +/*============================================================================= + + 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_poly.h" + +void +arb_poly_printd(const arb_poly_t poly, long digits) +{ + long i; + + printf("["); + + for (i = 0; i < poly->length; i++) + { + printf("("); + arb_printd(poly->coeffs + i, digits); + printf(")"); + + if (i + 1 < poly->length) + printf(", "); + } + + printf("]"); +} diff --git a/arb_poly/product_roots.c b/arb_poly/product_roots.c new file mode 100644 index 000000000..5dc5732f9 --- /dev/null +++ b/arb_poly/product_roots.c @@ -0,0 +1,69 @@ +/*============================================================================= + + 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) 2011 William Hart + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_product_roots(arb_ptr poly, arb_srcptr xs, long n, long prec) +{ + if (n == 0) + { + arb_one(poly); + } + else if (n == 1) + { + arb_neg(poly, xs); + arb_one(poly + 1); + } + else if (n == 2) + { + arb_mul(poly, xs + 0, xs + 1, prec); + arb_add(poly + 1, xs + 0, xs + 1, prec); + arb_neg(poly + 1, poly + 1); + arb_one(poly + 2); + } + else + { + const long m = (n + 1) / 2; + arb_ptr tmp; + + tmp = _arb_vec_init(n + 2); + + _arb_poly_product_roots(tmp, xs, m, prec); + _arb_poly_product_roots(tmp + m + 1, xs + m, n - m, prec); + _arb_poly_mul_monic(poly, tmp, m + 1, tmp + m + 1, n - m + 1, prec); + + _arb_vec_clear(tmp, n + 2); + } +} + +void +arb_poly_product_roots(arb_poly_t poly, arb_srcptr xs, long n, long prec) +{ + arb_poly_fit_length(poly, n + 1); + _arb_poly_product_roots(poly->coeffs, xs, n, prec); + _arb_poly_set_length(poly, n + 1); +} diff --git a/arb_poly/randtest.c b/arb_poly/randtest.c new file mode 100644 index 000000000..a14c6eb47 --- /dev/null +++ b/arb_poly/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_poly.h" + +void +arb_poly_randtest(arb_poly_t poly, flint_rand_t state, long len, long prec, long mag_bits) +{ + long i; + + arb_poly_fit_length(poly, len); + + if (n_randint(state, 2)) + for (i = 0; i < len; i++) + arb_randtest(poly->coeffs + i, state, prec, mag_bits); + else + for (i = 0; i < len; i++) + arb_randtest_precise(poly->coeffs + i, state, prec, mag_bits); + + _arb_poly_set_length(poly, len); + _arb_poly_normalise(poly); +} + diff --git a/arb_poly/reverse.c b/arb_poly/reverse.c new file mode 100644 index 000000000..66fca654d --- /dev/null +++ b/arb_poly/reverse.c @@ -0,0 +1,55 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_reverse(arb_ptr res, arb_srcptr poly, long len, long n) +{ + if (res == poly) + { + long i; + + for (i = 0; i < n / 2; i++) + { + arb_struct t = res[i]; + res[i] = res[n - 1 - i]; + res[n - 1 - i] = t; + } + + for (i = 0; i < n - len; i++) + arb_zero(res + i); + } + else + { + long i; + + for (i = 0; i < n - len; i++) + arb_zero(res + i); + + for (i = 0; i < len; i++) + arb_set(res + (n - len) + i, poly + (len - 1) - i); + } +} diff --git a/arb_poly/revert_series.c b/arb_poly/revert_series.c new file mode 100644 index 000000000..7f0c1c0ab --- /dev/null +++ b/arb_poly/revert_series.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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_revert_series(arb_ptr Qinv, + arb_srcptr Q, long Qlen, long n, long prec) +{ + _arb_poly_revert_series_lagrange_fast(Qinv, Q, Qlen, n, prec); +} + +void +arb_poly_revert_series(arb_poly_t Qinv, + const arb_poly_t Q, long n, long prec) +{ + long Qlen = Q->length; + + if (Qlen < 2 || !arb_is_zero(Q->coeffs) + || arb_contains_zero(Q->coeffs + 1)) + { + printf("Exception (arb_poly_revert_series). Input must \n" + "have zero constant term and nonzero coefficient of x^1.\n"); + abort(); + } + + if (Qinv != Q) + { + arb_poly_fit_length(Qinv, n); + _arb_poly_revert_series(Qinv->coeffs, Q->coeffs, Qlen, n, prec); + } + else + { + arb_poly_t t; + arb_poly_init2(t, n); + _arb_poly_revert_series(t->coeffs, Q->coeffs, Qlen, n, prec); + arb_poly_swap(Qinv, t); + arb_poly_clear(t); + } + + _arb_poly_set_length(Qinv, n); + _arb_poly_normalise(Qinv); +} + diff --git a/arb_poly/revert_series_lagrange.c b/arb_poly/revert_series_lagrange.c new file mode 100644 index 000000000..7815689c8 --- /dev/null +++ b/arb_poly/revert_series_lagrange.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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_revert_series_lagrange(arb_ptr Qinv, + arb_srcptr Q, long Qlen, long n, long prec) +{ + long i; + arb_ptr R, S, T, tmp; + + if (n <= 2) + { + if (n >= 1) + arb_zero(Qinv); + if (n == 2) + arb_inv(Qinv + 1, Q + 1, prec); + return; + } + + R = _arb_vec_init(n - 1); + S = _arb_vec_init(n - 1); + T = _arb_vec_init(n - 1); + + arb_zero(Qinv); + arb_inv(Qinv + 1, Q + 1, prec); + + _arb_poly_inv_series(R, Q + 1, FLINT_MIN(Qlen, n) - 1, n - 1, prec); + _arb_vec_set(S, R, n - 1); + + for (i = 2; i < n; i++) + { + _arb_poly_mullow(T, S, n - 1, R, n - 1, n - 1, prec); + arb_div_ui(Qinv + i, T + i - 1, i, prec); + tmp = S; S = T; T = tmp; + } + + _arb_vec_clear(R, n - 1); + _arb_vec_clear(S, n - 1); + _arb_vec_clear(T, n - 1); +} + +void +arb_poly_revert_series_lagrange(arb_poly_t Qinv, + const arb_poly_t Q, long n, long prec) +{ + long Qlen = Q->length; + + if (Qlen < 2 || !arb_is_zero(Q->coeffs) + || arb_contains_zero(Q->coeffs + 1)) + { + printf("Exception (arb_poly_revert_series_lagrange). Input must \n" + "have zero constant term and nonzero coefficient of x^1.\n"); + abort(); + } + + if (Qinv != Q) + { + arb_poly_fit_length(Qinv, n); + _arb_poly_revert_series_lagrange(Qinv->coeffs, Q->coeffs, Qlen, n, prec); + } + else + { + arb_poly_t t; + arb_poly_init2(t, n); + _arb_poly_revert_series_lagrange(t->coeffs, Q->coeffs, Qlen, n, prec); + arb_poly_swap(Qinv, t); + arb_poly_clear(t); + } + + _arb_poly_set_length(Qinv, n); + _arb_poly_normalise(Qinv); +} + diff --git a/arb_poly/revert_series_lagrange_fast.c b/arb_poly/revert_series_lagrange_fast.c new file mode 100644 index 000000000..3dc8a0603 --- /dev/null +++ b/arb_poly/revert_series_lagrange_fast.c @@ -0,0 +1,122 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +/* pointer to (x/Q)^i */ +#define Ri(ii) (R + (n-1)*((ii)-1)) + +void +_arb_poly_revert_series_lagrange_fast(arb_ptr Qinv, arb_srcptr Q, long Qlen, long n, long prec) +{ + long i, j, k, m; + arb_ptr R, S, T, tmp; + arb_t t; + + if (n <= 2) + { + if (n >= 1) + arb_zero(Qinv); + if (n == 2) + arb_inv(Qinv + 1, Q + 1, prec); + return; + } + + m = n_sqrt(n); + + arb_init(t); + R = _arb_vec_init((n - 1) * m); + S = _arb_vec_init(n - 1); + T = _arb_vec_init(n - 1); + + arb_zero(Qinv); + arb_inv(Qinv + 1, Q + 1, prec); + + _arb_poly_inv_series(Ri(1), Q + 1, FLINT_MIN(Qlen, n) - 1, n - 1, prec); + for (i = 2; i <= m; i++) + _arb_poly_mullow(Ri(i), Ri((i + 1) / 2), n - 1, Ri(i / 2), n - 1, n - 1, prec); + + for (i = 2; i < m; i++) + arb_div_ui(Qinv + i, Ri(i) + i - 1, i, prec); + + _arb_vec_set(S, Ri(m), n - 1); + + for (i = m; i < n; i += m) + { + arb_div_ui(Qinv + i, S + i - 1, i, prec); + + for (j = 1; j < m && i + j < n; j++) + { + arb_mul(t, S + 0, Ri(j) + i + j - 1, prec); + for (k = 1; k <= i + j - 1; k++) + arb_addmul(t, S + k, Ri(j) + i + j - 1 - k, prec); + arb_div_ui(Qinv + i + j, t, i + j, prec); + } + + if (i + 1 < n) + { + _arb_poly_mullow(T, S, n - 1, Ri(m), n - 1, n - 1, prec); + tmp = S; S = T; T = tmp; + } + } + + arb_clear(t); + _arb_vec_clear(R, (n - 1) * m); + _arb_vec_clear(S, n - 1); + _arb_vec_clear(T, n - 1); +} + +void +arb_poly_revert_series_lagrange_fast(arb_poly_t Qinv, + const arb_poly_t Q, long n, long prec) +{ + long Qlen = Q->length; + + if (Qlen < 2 || !arb_is_zero(Q->coeffs) + || arb_contains_zero(Q->coeffs + 1)) + { + printf("Exception (arb_poly_revert_series_lagrange_fast). Input \n" + "must have zero constant term and nonzero coefficient of x^1.\n"); + abort(); + } + + if (Qinv != Q) + { + arb_poly_fit_length(Qinv, n); + _arb_poly_revert_series_lagrange_fast(Qinv->coeffs, Q->coeffs, Qlen, n, prec); + } + else + { + arb_poly_t t; + arb_poly_init2(t, n); + _arb_poly_revert_series_lagrange_fast(t->coeffs, Q->coeffs, Qlen, n, prec); + arb_poly_swap(Qinv, t); + arb_poly_clear(t); + } + + _arb_poly_set_length(Qinv, n); + _arb_poly_normalise(Qinv); +} + diff --git a/arb_poly/revert_series_newton.c b/arb_poly/revert_series_newton.c new file mode 100644 index 000000000..bfbca7bb0 --- /dev/null +++ b/arb_poly/revert_series_newton.c @@ -0,0 +1,106 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +#define CUTOFF 5 + +void +_arb_poly_revert_series_newton(arb_ptr Qinv, arb_srcptr Q, long Qlen, long n, long prec) +{ + long i, k, a[FLINT_BITS]; + arb_ptr T, U, V; + + if (n <= 2) + { + if (n >= 1) + arb_zero(Qinv); + if (n == 2) + arb_inv(Qinv + 1, Q + 1, prec); + return; + } + + T = _arb_vec_init(n); + U = _arb_vec_init(n); + V = _arb_vec_init(n); + + k = n; + for (i = 1; (1L << i) < k; i++); + a[i = 0] = k; + while (k >= CUTOFF) + a[++i] = (k = (k + 1) / 2); + + _arb_poly_revert_series_lagrange(Qinv, Q, Qlen, k, prec); + _arb_vec_zero(Qinv + k, n - k); + + for (i--; i >= 0; i--) + { + k = a[i]; + _arb_poly_compose_series(T, Q, FLINT_MIN(Qlen, k), Qinv, k, k, prec); + _arb_poly_derivative(U, T, k, prec); arb_zero(U + k - 1); + arb_zero(T + 1); + _arb_poly_div_series(V, T, k, U, k, k, prec); + _arb_poly_derivative(T, Qinv, k, prec); + _arb_poly_mullow(U, V, k, T, k, k, prec); + _arb_vec_sub(Qinv, Qinv, U, k, prec); + } + + _arb_vec_clear(T, n); + _arb_vec_clear(U, n); + _arb_vec_clear(V, n); +} + +void +arb_poly_revert_series_newton(arb_poly_t Qinv, + const arb_poly_t Q, long n, long prec) +{ + long Qlen = Q->length; + + if (Qlen < 2 || !arb_is_zero(Q->coeffs) + || arb_contains_zero(Q->coeffs + 1)) + { + printf("Exception (arb_poly_revert_series_newton). Input must \n" + "have zero constant term and nonzero coefficient of x^1.\n"); + abort(); + } + + if (Qinv != Q) + { + arb_poly_fit_length(Qinv, n); + _arb_poly_revert_series_newton(Qinv->coeffs, Q->coeffs, Qlen, n, prec); + } + else + { + arb_poly_t t; + arb_poly_init2(t, n); + _arb_poly_revert_series_newton(t->coeffs, Q->coeffs, Qlen, n, prec); + arb_poly_swap(Qinv, t); + arb_poly_clear(t); + } + + _arb_poly_set_length(Qinv, n); + _arb_poly_normalise(Qinv); +} + diff --git a/arb_poly/rsqrt_series.c b/arb_poly/rsqrt_series.c new file mode 100644 index 000000000..50d3863fb --- /dev/null +++ b/arb_poly/rsqrt_series.c @@ -0,0 +1,98 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_rsqrt_series(arb_ptr g, + arb_srcptr h, long hlen, long len, long prec) +{ + hlen = FLINT_MIN(hlen, len); + + arb_rsqrt(g, h, prec); + + if (hlen == 1) + { + _arb_vec_zero(g + 1, len - 1); + } + else if (len == 2) + { + arb_div(g + 1, h + 1, h, prec); + arb_mul(g + 1, g + 1, g, prec); + arb_mul_2exp_si(g + 1, g + 1, -1); + arb_neg(g + 1, g + 1); + } + else + { + arb_ptr t, u; + long tlen; + t = _arb_vec_init(2 * len); + u = t + len; + + NEWTON_INIT(1, len) + + NEWTON_LOOP(m, n) + tlen = FLINT_MIN(2 * m - 1, n); + _arb_poly_mullow(t, g, m, g, m, tlen, prec); + _arb_poly_mullow(u, g, m, t, tlen, n, prec); + _arb_poly_mullow(t, u, n, h, hlen, n, prec); + _arb_vec_scalar_mul_2exp_si(g + m, t + m, n - m, -1); + _arb_vec_neg(g + m, g + m, n - m); + NEWTON_END_LOOP + + NEWTON_END + + _arb_vec_clear(t, 2 * len); + } +} + +void +arb_poly_rsqrt_series(arb_poly_t g, const arb_poly_t h, long n, long prec) +{ + if (n == 0) + { + arb_poly_zero(g); + return; + } + + if (g == h) + { + arb_poly_t t; + arb_poly_init(t); + arb_poly_rsqrt_series(t, h, n, prec); + arb_poly_swap(g, t); + arb_poly_clear(t); + return; + } + + arb_poly_fit_length(g, n); + if (h->length == 0) + _arb_vec_indeterminate(g->coeffs, n); + else + _arb_poly_rsqrt_series(g->coeffs, h->coeffs, h->length, n, prec); + _arb_poly_set_length(g, n); + _arb_poly_normalise(g); +} + diff --git a/arb_poly/set.c b/arb_poly/set.c new file mode 100644 index 000000000..1de46ac19 --- /dev/null +++ b/arb_poly/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + 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_poly.h" + +void +arb_poly_set(arb_poly_t dest, const arb_poly_t src) +{ + long len = arb_poly_length(src); + + arb_poly_fit_length(dest, len); + _arb_vec_set(dest->coeffs, src->coeffs, len); + _arb_poly_set_length(dest, len); +} diff --git a/arb_poly/set_coeff_fmprb.c b/arb_poly/set_coeff_fmprb.c new file mode 100644 index 000000000..7a78684b2 --- /dev/null +++ b/arb_poly/set_coeff_fmprb.c @@ -0,0 +1,42 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +arb_poly_set_coeff_arb(arb_poly_t poly, long n, const arb_t x) +{ + arb_poly_fit_length(poly, n + 1); + + if (n + 1 > poly->length) + { + _arb_vec_zero(poly->coeffs + poly->length, n - poly->length); + poly->length = n + 1; + } + + arb_set(poly->coeffs + n, x); + _arb_poly_normalise(poly); +} + diff --git a/arb_poly/set_coeff_si.c b/arb_poly/set_coeff_si.c new file mode 100644 index 000000000..5e559ac2d --- /dev/null +++ b/arb_poly/set_coeff_si.c @@ -0,0 +1,42 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +arb_poly_set_coeff_si(arb_poly_t poly, long n, long x) +{ + arb_poly_fit_length(poly, n + 1); + + if (n + 1 > poly->length) + { + _arb_vec_zero(poly->coeffs + poly->length, n - poly->length); + poly->length = n + 1; + } + + arb_set_si(poly->coeffs + n, x); + _arb_poly_normalise(poly); +} + diff --git a/arb_poly/set_fmpq_poly.c b/arb_poly/set_fmpq_poly.c new file mode 100644 index 000000000..0cf931ccb --- /dev/null +++ b/arb_poly/set_fmpq_poly.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_poly.h" + +void +arb_poly_set_fmpq_poly(arb_poly_t poly, const fmpq_poly_t src, long prec) +{ + long i, len = src->length; + + arb_poly_fit_length(poly, len); + _arb_poly_set_length(poly, len); + + for (i = 0; i < len; i++) + { + fmpq t; + + t.num = (fmpz) src->coeffs[i]; + t.den = (fmpz) *src->den; + + arb_set_fmpq(poly->coeffs + i, &t, prec); + } +} diff --git a/arb_poly/set_fmpz_poly.c b/arb_poly/set_fmpz_poly.c new file mode 100644 index 000000000..2db7a3ae0 --- /dev/null +++ b/arb_poly/set_fmpz_poly.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_poly.h" + +void +arb_poly_set_fmpz_poly(arb_poly_t poly, const fmpz_poly_t src, long prec) +{ + long i, len = fmpz_poly_length(src); + + arb_poly_fit_length(poly, len); + _arb_poly_set_length(poly, len); + + for (i = 0; i < len; i++) + arb_set_round_fmpz(poly->coeffs + i, src->coeffs + i, prec); +} diff --git a/arb_poly/set_length.c b/arb_poly/set_length.c new file mode 100644 index 000000000..8815555a4 --- /dev/null +++ b/arb_poly/set_length.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_poly.h" + +void +_arb_poly_set_length(arb_poly_t poly, long len) +{ + long i; + + if (poly->length > len) + { + for (i = len; i < poly->length; i++) + arb_zero(poly->coeffs + i); + } + + poly->length = len; +} diff --git a/arb_poly/set_si.c b/arb_poly/set_si.c new file mode 100644 index 000000000..c7e0a1d1c --- /dev/null +++ b/arb_poly/set_si.c @@ -0,0 +1,42 @@ +/*============================================================================= + + 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_poly.h" + +void +arb_poly_set_si(arb_poly_t poly, long c) +{ + if (c == 0) + { + arb_poly_zero(poly); + } + else + { + arb_poly_fit_length(poly, 1); + arb_set_si(poly->coeffs, c); + _arb_poly_set_length(poly, 1); + } +} + diff --git a/arb_poly/shift_left.c b/arb_poly/shift_left.c new file mode 100644 index 000000000..d8fcf096f --- /dev/null +++ b/arb_poly/shift_left.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) 2008, 2009 William Hart + Copyright (C) 2010 Sebastian Pancratz + Copyright (C) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_shift_left(arb_ptr res, arb_srcptr poly, long len, long n) +{ + long i; + + /* Copy in reverse to avoid writing over unshifted coefficients */ + if (res != poly) + { + for (i = len; i--; ) + arb_set(res + n + i, poly + i); + } + else + { + for (i = len; i--; ) + arb_swap(res + n + i, res + i); + } + + for (i = 0; i < n; i++) + arb_zero(res + i); +} + +void +arb_poly_shift_left(arb_poly_t res, const arb_poly_t poly, long n) +{ + if (n == 0) + { + arb_poly_set(res, poly); + return; + } + + if (poly->length == 0) + { + arb_poly_zero(res); + return; + } + + arb_poly_fit_length(res, poly->length + n); + _arb_poly_shift_left(res->coeffs, poly->coeffs, poly->length, n); + _arb_poly_set_length(res, poly->length + n); +} + diff --git a/arb_poly/shift_right.c b/arb_poly/shift_right.c new file mode 100644 index 000000000..9de2ec690 --- /dev/null +++ b/arb_poly/shift_right.c @@ -0,0 +1,68 @@ +/*============================================================================= + + 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) 2008, 2009 William Hart + Copyright (C) 2010 Sebastian Pancratz + Copyright (C) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_shift_right(arb_ptr res, arb_srcptr poly, long len, long n) +{ + long i; + + /* Copy in forward order to avoid writing over unshifted coefficients */ + if (res != poly) + { + for (i = 0; i < len - n; i++) + arb_set(res + i, poly + n + i); + } + else + { + for (i = 0; i < len - n; i++) + arb_swap(res + i, res + n + i); + } + +} + +void +arb_poly_shift_right(arb_poly_t res, const arb_poly_t poly, long n) +{ + if (n == 0) + { + arb_poly_set(res, poly); + return; + } + + if (poly->length <= n) + { + arb_poly_zero(res); + return; + } + + arb_poly_fit_length(res, poly->length - n); + _arb_poly_shift_right(res->coeffs, poly->coeffs, poly->length, n); + _arb_poly_set_length(res, poly->length - n); +} + diff --git a/arb_poly/sin_cos_series.c b/arb_poly/sin_cos_series.c new file mode 100644 index 000000000..32f95df9a --- /dev/null +++ b/arb_poly/sin_cos_series.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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +#define TANGENT_CUTOFF 80 + +void +_arb_poly_sin_cos_series(arb_ptr s, arb_ptr c, const arb_srcptr h, long hlen, long n, long prec) +{ + hlen = FLINT_MIN(hlen, n); + + if (hlen == 1) + { + arb_sin_cos(s, c, h, prec); + _arb_vec_zero(s + 1, n - 1); + _arb_vec_zero(c + 1, n - 1); + } + else if (n == 2) + { + arb_t t; + arb_init(t); + arb_set(t, h + 1); + arb_sin_cos(s, c, h, prec); + arb_mul(s + 1, c, t, prec); + arb_neg(t, t); + arb_mul(c + 1, s, t, prec); + arb_clear(t); + } + else if (hlen < TANGENT_CUTOFF) + _arb_poly_sin_cos_series_basecase(s, c, h, hlen, n, prec); + else + _arb_poly_sin_cos_series_tangent(s, c, h, hlen, n, prec); +} + +void +arb_poly_sin_cos_series(arb_poly_t s, arb_poly_t c, + const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (n == 0) + { + arb_poly_zero(s); + arb_poly_zero(c); + return; + } + + if (hlen == 0) + { + arb_poly_zero(s); + arb_poly_one(c); + return; + } + + if (hlen == 1) + n = 1; + + arb_poly_fit_length(s, n); + arb_poly_fit_length(c, n); + _arb_poly_sin_cos_series(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(s, n); + _arb_poly_normalise(s); + _arb_poly_set_length(c, n); + _arb_poly_normalise(c); +} + diff --git a/arb_poly/sin_cos_series_basecase.c b/arb_poly/sin_cos_series_basecase.c new file mode 100644 index 000000000..68a513f5f --- /dev/null +++ b/arb_poly/sin_cos_series_basecase.c @@ -0,0 +1,100 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_sin_cos_series_basecase(arb_ptr s, + arb_ptr c, arb_srcptr h, long hlen, long n, long prec) +{ + long j, k, alen = FLINT_MIN(n, hlen); + arb_ptr a; + arb_t t, u; + + arb_sin_cos(s, c, h, prec); + + if (hlen == 1) + { + _arb_vec_zero(s + 1, n - 1); + _arb_vec_zero(c + 1, n - 1); + return; + } + + arb_init(t); + arb_init(u); + a = _arb_vec_init(alen); + + for (k = 1; k < alen; k++) + arb_mul_ui(a + k, h + k, k, prec); + + for (k = 1; k < n; k++) + { + arb_zero(t); + arb_zero(u); + + for (j = 1; j < FLINT_MIN(k + 1, hlen); j++) + { + arb_submul(t, a + j, s + k - j, prec); + arb_addmul(u, a + j, c + k - j, prec); + } + + arb_div_ui(c + k, t, k, prec); + arb_div_ui(s + k, u, k, prec); + } + + arb_clear(t); + arb_clear(u); + _arb_vec_clear(a, alen); +} + +void +arb_poly_sin_cos_series_basecase(arb_poly_t s, arb_poly_t c, + const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (n == 0) + { + arb_poly_zero(s); + arb_poly_zero(c); + return; + } + + if (hlen == 0) + { + arb_poly_zero(s); + arb_poly_one(c); + return; + } + + arb_poly_fit_length(s, n); + arb_poly_fit_length(c, n); + _arb_poly_sin_cos_series_basecase(s->coeffs, c->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(s, n); + _arb_poly_normalise(s); + _arb_poly_set_length(c, n); + _arb_poly_normalise(c); +} + diff --git a/arb_poly/sin_cos_series_tangent.c b/arb_poly/sin_cos_series_tangent.c new file mode 100644 index 000000000..c9e1f46f2 --- /dev/null +++ b/arb_poly/sin_cos_series_tangent.c @@ -0,0 +1,127 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_sin_cos_series_tangent(arb_ptr s, arb_ptr c, + const arb_srcptr h, long hlen, long len, long prec) +{ + arb_ptr t, u, v; + arb_t s0, c0; + hlen = FLINT_MIN(hlen, len); + + if (hlen == 1) + { + arb_sin_cos(s, c, h, prec); + _arb_vec_zero(s + 1, len - 1); + _arb_vec_zero(c + 1, len - 1); + return; + } + + /* + sin(x) = 2*tan(x/2)/(1+tan(x/2)^2) + cos(x) = (1-tan(x/2)^2)/(1+tan(x/2)^2) + */ + + arb_init(s0); + arb_init(c0); + + t = _arb_vec_init(3 * len); + u = t + len; + v = u + len; + + /* sin, cos of h0 */ + arb_sin_cos(s0, c0, h, prec); + + /* t = tan((h-h0)/2) */ + arb_zero(u); + _arb_vec_scalar_mul_2exp_si(u + 1, h + 1, hlen - 1, -1); + _arb_poly_tan_series(t, u, hlen, len, prec); + + /* v = 1 + t^2 */ + _arb_poly_mullow(v, t, len, t, len, len, prec); + arb_add_ui(v, v, 1, prec); + + /* u = 1/(1+t^2) */ + _arb_poly_inv_series(u, v, len, len, prec); + + /* sine */ + _arb_poly_mullow(s, t, len, u, len, len, prec); + _arb_vec_scalar_mul_2exp_si(s, s, len, 1); + + /* cosine */ + arb_sub_ui(v, v, 2, prec); + _arb_vec_neg(v, v, len); + _arb_poly_mullow(c, v, len, u, len, len, prec); + + /* sin(h0 + h1) = cos(h0) sin(h1) + sin(h0) cos(h1) + cos(h0 + h1) = cos(h0) cos(h1) - sin(h0) sin(h1) */ + if (!arb_is_zero(s0)) + { + _arb_vec_scalar_mul(t, s, len, c0, prec); + _arb_vec_scalar_mul(u, c, len, s0, prec); + _arb_vec_scalar_mul(v, s, len, s0, prec); + _arb_vec_add(s, t, u, len, prec); + _arb_vec_scalar_mul(t, c, len, c0, prec); + _arb_vec_sub(c, t, v, len, prec); + } + + _arb_vec_clear(t, 3 * len); + + arb_clear(s0); + arb_clear(c0); +} + +void +arb_poly_sin_cos_series_tangent(arb_poly_t s, arb_poly_t c, + const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (n == 0) + { + arb_poly_zero(s); + arb_poly_zero(c); + return; + } + + if (hlen == 0) + { + arb_poly_zero(s); + arb_poly_one(c); + return; + } + + arb_poly_fit_length(s, n); + arb_poly_fit_length(c, n); + _arb_poly_sin_cos_series_tangent(s->coeffs, c->coeffs, + h->coeffs, hlen, n, prec); + _arb_poly_set_length(s, n); + _arb_poly_normalise(s); + _arb_poly_set_length(c, n); + _arb_poly_normalise(c); +} + diff --git a/arb_poly/sin_series.c b/arb_poly/sin_series.c new file mode 100644 index 000000000..5dacb62b0 --- /dev/null +++ b/arb_poly/sin_series.c @@ -0,0 +1,73 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_sin_series(arb_ptr g, arb_srcptr h, long hlen, long n, long prec) +{ + hlen = FLINT_MIN(hlen, n); + + if (hlen == 1) + { + arb_sin(g, h, prec); + _arb_vec_zero(g + 1, n - 1); + } + else if (n == 2) + { + arb_t t; + arb_init(t); + arb_sin_cos(g, t, h, prec); + arb_mul(g + 1, h + 1, t, prec); /* safe since hlen >= 2 */ + arb_clear(t); + } + else + { + arb_ptr t = _arb_vec_init(n); + _arb_poly_sin_cos_series(g, t, h, hlen, n, prec); + _arb_vec_clear(t, n); + } +} + +void +arb_poly_sin_series(arb_poly_t g, const arb_poly_t h, long n, long prec) +{ + long hlen = h->length; + + if (hlen == 0 || n == 0) + { + arb_poly_zero(g); + return; + } + + if (hlen == 1) + n = 1; + + arb_poly_fit_length(g, n); + _arb_poly_sin_series(g->coeffs, h->coeffs, hlen, n, prec); + _arb_poly_set_length(g, n); + _arb_poly_normalise(g); +} + diff --git a/arb_poly/sqrt_series.c b/arb_poly/sqrt_series.c new file mode 100644 index 000000000..df60b0fed --- /dev/null +++ b/arb_poly/sqrt_series.c @@ -0,0 +1,83 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +void +_arb_poly_sqrt_series(arb_ptr g, + arb_srcptr h, long hlen, long len, long prec) +{ + hlen = FLINT_MIN(hlen, len); + + if (hlen == 1) + { + arb_sqrt(g, h, prec); + _arb_vec_zero(g + 1, len - 1); + } + else if (len == 2) + { + arb_sqrt(g, h, prec); + arb_div(g + 1, h + 1, h, prec); + arb_mul(g + 1, g + 1, g, prec); + arb_mul_2exp_si(g + 1, g + 1, -1); + } + else + { + arb_ptr t; + t = _arb_vec_init(len); + _arb_poly_rsqrt_series(t, h, hlen, len, prec); + _arb_poly_mullow(g, t, len, h, hlen, len, prec); + _arb_vec_clear(t, len); + } +} + +void +arb_poly_sqrt_series(arb_poly_t g, const arb_poly_t h, long n, long prec) +{ + if (n == 0) + { + arb_poly_zero(g); + return; + } + + if (g == h) + { + arb_poly_t t; + arb_poly_init(t); + arb_poly_sqrt_series(t, h, n, prec); + arb_poly_swap(g, t); + arb_poly_clear(t); + return; + } + + arb_poly_fit_length(g, n); + if (h->length == 0) + _arb_vec_indeterminate(g->coeffs, n); + else + _arb_poly_sqrt_series(g->coeffs, h->coeffs, h->length, n, prec); + _arb_poly_set_length(g, n); + _arb_poly_normalise(g); +} + diff --git a/arb_poly/sub.c b/arb_poly/sub.c new file mode 100644 index 000000000..fb6e53f2c --- /dev/null +++ b/arb_poly/sub.c @@ -0,0 +1,58 @@ +/*============================================================================= + + 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_poly.h" + +void +_arb_poly_sub(arb_ptr res, arb_srcptr poly1, long len1, + arb_srcptr poly2, long len2, long prec) +{ + long i, min = FLINT_MIN(len1, len2); + + for (i = 0; i < min; i++) + arb_sub(res + i, poly1 + i, poly2 + i, prec); + + for (i = min; i < len1; i++) + arb_set_round(res + i, poly1 + i, prec); + + for (i = min; i < len2; i++) + arb_neg_round(res + i, poly2 + i, prec); +} + +void +arb_poly_sub(arb_poly_t res, const arb_poly_t poly1, + const arb_poly_t poly2, long prec) +{ + long max = FLINT_MAX(poly1->length, poly2->length); + + arb_poly_fit_length(res, max); + + _arb_poly_sub(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, + poly2->length, prec); + + _arb_poly_set_length(res, max); + _arb_poly_normalise(res); +} + diff --git a/arb_poly/tan_series.c b/arb_poly/tan_series.c new file mode 100644 index 000000000..c0afd01f5 --- /dev/null +++ b/arb_poly/tan_series.c @@ -0,0 +1,103 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +#define TAN_NEWTON_CUTOFF 20 + +void +_arb_poly_tan_series(arb_ptr g, + arb_srcptr h, long hlen, long len, long prec) +{ + hlen = FLINT_MIN(hlen, len); + + if (hlen == 1) + { + arb_tan(g, h, prec); + _arb_vec_zero(g + 1, len - 1); + } + else if (len == 2) + { + arb_t t; + arb_init(t); + arb_tan(g, h, prec); + arb_mul(t, g, g, prec); + arb_add_ui(t, t, 1, prec); + arb_mul(g + 1, t, h + 1, prec); /* safe since hlen >= 2 */ + arb_clear(t); + } + else + { + arb_ptr t, u; + + t = _arb_vec_init(2 * len); + u = t + len; + + NEWTON_INIT(TAN_NEWTON_CUTOFF, len) + + NEWTON_BASECASE(n) + _arb_poly_sin_cos_series_basecase(t, u, h, hlen, n, prec); + _arb_poly_div_series(g, t, n, u, n, n, prec); + NEWTON_END_BASECASE + + NEWTON_LOOP(m, n) + _arb_poly_mullow(u, g, m, g, m, n, prec); + arb_add_ui(u, u, 1, prec); + _arb_poly_atan_series(t, g, m, n, prec); + _arb_poly_sub(t + m, h + m, FLINT_MAX(0, hlen - m), t + m, n - m, prec); + _arb_poly_mullow(g + m, u, n, t + m, n - m, n - m, prec); + NEWTON_END_LOOP + + NEWTON_END + + _arb_vec_clear(t, 2 * len); + } +} + +void +arb_poly_tan_series(arb_poly_t g, const arb_poly_t h, long n, long prec) +{ + if (h->length == 0 || n == 0) + { + arb_poly_zero(g); + return; + } + + if (g == h) + { + arb_poly_t t; + arb_poly_init(t); + arb_poly_tan_series(t, h, n, prec); + arb_poly_swap(g, t); + arb_poly_clear(t); + return; + } + + arb_poly_fit_length(g, n); + _arb_poly_tan_series(g->coeffs, h->coeffs, h->length, n, prec); + _arb_poly_set_length(g, n); + _arb_poly_normalise(g); +} + diff --git a/arb_poly/test/t-acos_series.c b/arb_poly/test/t-acos_series.c new file mode 100644 index 000000000..2f634d6a6 --- /dev/null +++ b/arb_poly/test/t-acos_series.c @@ -0,0 +1,101 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("acos_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b, c, d; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); + + arb_poly_acos_series(b, a, n, rbits2); + + /* Check cos(acos(x)) = x */ + arb_poly_sin_cos_series_basecase(d, c, b, n, rbits2); + + fmpq_poly_truncate(A, n); + if (!arb_poly_contains_fmpq_poly(c, A)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_acos_series(a, a, n, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-add.c b/arb_poly/test/t-add.c new file mode 100644 index 000000000..b0edd3f71 --- /dev/null +++ b/arb_poly/test/t-add.c @@ -0,0 +1,96 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("add...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 100000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); + fmpq_poly_add(C, A, B); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_add(c, a, b, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-asin_series.c b/arb_poly/test/t-asin_series.c new file mode 100644 index 000000000..9dab9ece0 --- /dev/null +++ b/arb_poly/test/t-asin_series.c @@ -0,0 +1,101 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("asin_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b, c, d; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); + + arb_poly_asin_series(b, a, n, rbits2); + + /* Check sin(asin(x)) = x */ + arb_poly_sin_cos_series_basecase(c, d, b, n, rbits2); + + fmpq_poly_truncate(A, n); + if (!arb_poly_contains_fmpq_poly(c, A)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_asin_series(a, a, n, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-atan_series.c b/arb_poly/test/t-atan_series.c new file mode 100644 index 000000000..a11aafe38 --- /dev/null +++ b/arb_poly/test/t-atan_series.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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("atan_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b, c, d; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); + + arb_poly_atan_series(b, a, n, rbits2); + + /* Check 2 atan(x) = atan(2x/(1-x^2)) + C */ + arb_poly_mullow(c, a, a, n, rbits2); + arb_poly_one(d); + arb_poly_sub(c, d, c, rbits2); + arb_poly_add(d, a, a, rbits2); + + if (arb_poly_length(c) != 0) + { + arb_poly_div_series(c, d, c, n, rbits2); + arb_poly_atan_series(c, c, n, rbits2); + arb_poly_add(d, b, b, rbits2); + + /* TODO: also check the first coefficient */ + arb_poly_set_coeff_si(c, 0, 0); + arb_poly_set_coeff_si(d, 0, 0); + + if (!arb_poly_overlaps(c, d)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + } + + arb_poly_atan_series(a, a, n, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-binomial_transform.c b/arb_poly/test/t-binomial_transform.c new file mode 100644 index 000000000..0565e77e5 --- /dev/null +++ b/arb_poly/test/t-binomial_transform.c @@ -0,0 +1,119 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("binomial_transform...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 5000; iter++) + { + arb_poly_t a, b, c, d; + long j, n, prec; + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + n = n_randint(state, 20); + prec = 2 + n_randint(state, 200); + + arb_poly_randtest(a, state, n, prec, 10); + arb_poly_randtest(b, state, n, prec, 10); + arb_poly_randtest(c, state, n, prec, 10); + + /* check self-inversion property */ + arb_poly_binomial_transform(b, a, n, prec); + arb_poly_binomial_transform(c, b, n, prec); + + arb_poly_set(d, a); + arb_poly_truncate(d, n); + + if (!arb_poly_contains(c, d)) + { + printf("FAIL (containment)\n\n"); + printf("n = %ld, prec = %ld\n\n", n, prec); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c: "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d: "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_binomial_transform(d, d, n, prec); + if (!arb_poly_equal(d, b)) + { + printf("FAIL (aliasing)\n\n"); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("d: "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + /* compare with power series operations */ + arb_poly_zero(d); + for (j = 1; j < n; j++) + arb_poly_set_coeff_si(d, j, -1); + arb_poly_compose_series(c, a, d, n, prec); + for (j = 0; j < n; j++) + arb_poly_set_coeff_si(d, j, 1); + arb_poly_mullow(c, c, d, n, prec); + + if (!arb_poly_overlaps(b, c)) + { + printf("FAIL (power series)\n\n"); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c: "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-binomial_transform_basecase.c b/arb_poly/test/t-binomial_transform_basecase.c new file mode 100644 index 000000000..dee007b4c --- /dev/null +++ b/arb_poly/test/t-binomial_transform_basecase.c @@ -0,0 +1,119 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("binomial_transform_basecase...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 5000; iter++) + { + arb_poly_t a, b, c, d; + long j, n, prec; + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + n = n_randint(state, 20); + prec = 2 + n_randint(state, 200); + + arb_poly_randtest(a, state, n, prec, 10); + arb_poly_randtest(b, state, n, prec, 10); + arb_poly_randtest(c, state, n, prec, 10); + + /* check self-inversion property */ + arb_poly_binomial_transform_basecase(b, a, n, prec); + arb_poly_binomial_transform_basecase(c, b, n, prec); + + arb_poly_set(d, a); + arb_poly_truncate(d, n); + + if (!arb_poly_contains(c, d)) + { + printf("FAIL (containment)\n\n"); + printf("n = %ld, prec = %ld\n\n", n, prec); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c: "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d: "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_binomial_transform_basecase(d, d, n, prec); + if (!arb_poly_equal(d, b)) + { + printf("FAIL (aliasing)\n\n"); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("d: "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + /* compare with power series operations */ + arb_poly_zero(d); + for (j = 1; j < n; j++) + arb_poly_set_coeff_si(d, j, -1); + arb_poly_compose_series(c, a, d, n, prec); + for (j = 0; j < n; j++) + arb_poly_set_coeff_si(d, j, 1); + arb_poly_mullow(c, c, d, n, prec); + + if (!arb_poly_overlaps(b, c)) + { + printf("FAIL (power series)\n\n"); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c: "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-binomial_transform_convolution.c b/arb_poly/test/t-binomial_transform_convolution.c new file mode 100644 index 000000000..a90401a23 --- /dev/null +++ b/arb_poly/test/t-binomial_transform_convolution.c @@ -0,0 +1,119 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("binomial_transform_convolution...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 5000; iter++) + { + arb_poly_t a, b, c, d; + long j, n, prec; + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + n = n_randint(state, 20); + prec = 2 + n_randint(state, 200); + + arb_poly_randtest(a, state, n, prec, 10); + arb_poly_randtest(b, state, n, prec, 10); + arb_poly_randtest(c, state, n, prec, 10); + + /* check self-inversion property */ + arb_poly_binomial_transform_convolution(b, a, n, prec); + arb_poly_binomial_transform_convolution(c, b, n, prec); + + arb_poly_set(d, a); + arb_poly_truncate(d, n); + + if (!arb_poly_contains(c, d)) + { + printf("FAIL (containment)\n\n"); + printf("n = %ld, prec = %ld\n\n", n, prec); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c: "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d: "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_binomial_transform_convolution(d, d, n, prec); + if (!arb_poly_equal(d, b)) + { + printf("FAIL (aliasing)\n\n"); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("d: "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + /* compare with power series operations */ + arb_poly_zero(d); + for (j = 1; j < n; j++) + arb_poly_set_coeff_si(d, j, -1); + arb_poly_compose_series(c, a, d, n, prec); + for (j = 0; j < n; j++) + arb_poly_set_coeff_si(d, j, 1); + arb_poly_mullow(c, c, d, n, prec); + + if (!arb_poly_overlaps(b, c)) + { + printf("FAIL (power series)\n\n"); + + printf("a: "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b: "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c: "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-borel_transform.c b/arb_poly/test/t-borel_transform.c new file mode 100644 index 000000000..45d86c114 --- /dev/null +++ b/arb_poly/test/t-borel_transform.c @@ -0,0 +1,91 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("borel_transform...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + arb_poly_t a, b, c, d; + long n, prec; + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + n = n_randint(state, 30); + prec = n_randint(state, 200); + + arb_poly_randtest(a, state, n, prec, 10); + arb_poly_randtest(b, state, n, prec, 10); + arb_poly_randtest(c, state, n, prec, 10); + + arb_poly_borel_transform(b, a, prec); + arb_poly_inv_borel_transform(c, b, prec); + + if (!arb_poly_contains(c, a)) + { + printf("FAIL (containment)\n\n"); + abort(); + } + + arb_poly_set(d, a); + arb_poly_borel_transform(d, d, prec); + if (!arb_poly_equal(d, b)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_inv_borel_transform(d, d, prec); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-compose.c b/arb_poly/test/t-compose.c new file mode 100644 index 000000000..2e0e188b1 --- /dev/null +++ b/arb_poly/test/t-compose.c @@ -0,0 +1,116 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("compose...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 3000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); + fmpq_poly_compose(C, A, B); + + arb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 4); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_compose(c, a, b, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_compose(d, d, b, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_compose(d, a, d, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-compose_divconquer.c b/arb_poly/test/t-compose_divconquer.c new file mode 100644 index 000000000..437b505a5 --- /dev/null +++ b/arb_poly/test/t-compose_divconquer.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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("compose_divconquer...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 3000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); + fmpq_poly_compose(C, A, B); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_compose_divconquer(c, a, b, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_compose_divconquer(d, d, b, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_compose_divconquer(d, a, d, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-compose_horner.c b/arb_poly/test/t-compose_horner.c new file mode 100644 index 000000000..5d67ab8cc --- /dev/null +++ b/arb_poly/test/t-compose_horner.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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("compose_horner...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 3000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 20), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); + fmpq_poly_compose(C, A, B); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_compose_horner(c, a, b, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_compose_horner(d, d, b, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_compose_horner(d, a, d, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-compose_series.c b/arb_poly/test/t-compose_series.c new file mode 100644 index 000000000..e0f11c0f0 --- /dev/null +++ b/arb_poly/test/t-compose_series.c @@ -0,0 +1,118 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("compose_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 3000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3, n; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + n = 2 + n_randint(state, 25); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 25), qbits2); + fmpq_poly_set_coeff_ui(B, 0, 0); + fmpq_poly_compose_series(C, A, B, n); + + arb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 4); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_compose_series(c, a, b, n, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("n = %ld, bits3 = %ld\n", n, rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_compose_series(d, d, b, n, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_compose_series(d, a, d, n, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-compose_series_horner.c b/arb_poly/test/t-compose_series_horner.c new file mode 100644 index 000000000..ff02a1c75 --- /dev/null +++ b/arb_poly/test/t-compose_series_horner.c @@ -0,0 +1,116 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("compose_series_horner...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 3000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3, n; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + n = 2 + n_randint(state, 25); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 25), qbits2); + fmpq_poly_set_coeff_ui(B, 0, 0); + fmpq_poly_compose_series(C, A, B, n); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_compose_series_horner(c, a, b, n, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("n = %ld, bits3 = %ld\n", n, rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_compose_series_horner(d, d, b, n, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_compose_series_horner(d, a, d, n, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-div_series.c b/arb_poly/test/t-div_series.c new file mode 100644 index 000000000..705a44a07 --- /dev/null +++ b/arb_poly/test/t-div_series.c @@ -0,0 +1,128 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("div_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, p, qbits, rbits1, rbits2; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + p = 1 + n_randint(state, 20); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, m, qbits); + + do { + fmpq_poly_randtest_not_zero(B, state, n, qbits); + } while (B->coeffs[0] == 0); + + fmpq_poly_div_series(C, A, B, p); + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits1); + arb_poly_div_series(c, a, b, p, rbits2); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_div_series(d, d, b, p, rbits2); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_div_series(d, a, d, p, rbits2); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_div_series(c, d, d, p, rbits2); + arb_poly_div_series(d, d, d, p, rbits2); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 3)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-divrem.c b/arb_poly/test/t-divrem.c new file mode 100644 index 000000000..ea6f5b6f3 --- /dev/null +++ b/arb_poly/test/t-divrem.c @@ -0,0 +1,136 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("divrem...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 100000; iter++) + { + long m, n, qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t A, B, Q, R; + arb_poly_t a, b, q, r; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(Q); + fmpq_poly_init(R); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(q); + arb_poly_init(r); + + fmpq_poly_randtest(A, state, m, qbits1); + fmpq_poly_randtest_not_zero(B, state, n, qbits2); + + fmpq_poly_divrem(Q, R, A, B); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + + arb_poly_divrem(q, r, a, b, rbits3); + + if (!arb_poly_contains_fmpq_poly(q, Q) || + !arb_poly_contains_fmpq_poly(r, R)) + { + printf("FAIL\n\n"); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("Q = "); fmpq_poly_print(Q); printf("\n\n"); + printf("R = "); fmpq_poly_print(R); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("q = "); arb_poly_printd(q, 15); printf("\n\n"); + printf("r = "); arb_poly_printd(r, 15); printf("\n\n"); + + abort(); + } + + arb_poly_divrem(a, r, a, b, rbits3); + if (!arb_poly_equal(a, q)) + { + printf("FAIL (aliasing q, a)\n\n"); + } + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_divrem(b, r, a, b, rbits3); + if (!arb_poly_equal(b, q)) + { + printf("FAIL (aliasing q, b)\n\n"); + abort(); + } + arb_poly_set_fmpq_poly(b, B, rbits2); + + arb_poly_divrem(q, a, a, b, rbits3); + if (!arb_poly_equal(a, r)) + { + printf("FAIL (aliasing r, a)\n\n"); + abort(); + } + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_divrem(q, b, a, b, rbits3); + if (!arb_poly_equal(b, r)) + { + printf("FAIL (aliasing r, b)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(Q); + fmpq_poly_clear(R); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(q); + arb_poly_clear(r); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-evaluate.c b/arb_poly/test/t-evaluate.c new file mode 100644 index 000000000..5c1effdb0 --- /dev/null +++ b/arb_poly/test/t-evaluate.c @@ -0,0 +1,104 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("evaluate...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t F; + fmpq_t X, Y; + arb_poly_t f; + arb_t x, y; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_init(F); + fmpq_init(X); + fmpq_init(Y); + + arb_poly_init(f); + arb_init(x); + arb_init(y); + + fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); + fmpq_randtest(X, state, qbits2); + fmpq_poly_evaluate_fmpq(Y, F, X); + + arb_poly_set_fmpq_poly(f, F, rbits1); + arb_set_fmpq(x, X, rbits2); + arb_poly_evaluate(y, f, x, rbits3); + + if (!arb_contains_fmpq(y, Y)) + { + printf("FAIL\n\n"); + + printf("F = "); fmpq_poly_print(F); printf("\n\n"); + printf("X = "); fmpq_print(X); printf("\n\n"); + printf("Y = "); fmpq_print(Y); printf("\n\n"); + + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("x = "); arb_printd(x, 15); printf("\n\n"); + printf("y = "); arb_printd(y, 15); printf("\n\n"); + + abort(); + } + + /* aliasing */ + arb_poly_evaluate(x, f, x, rbits3); + if (!arb_contains_fmpq(x, Y)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(F); + fmpq_clear(X); + fmpq_clear(Y); + + arb_poly_clear(f); + arb_clear(x); + arb_clear(y); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-evaluate2.c b/arb_poly/test/t-evaluate2.c new file mode 100644 index 000000000..448ee409f --- /dev/null +++ b/arb_poly/test/t-evaluate2.c @@ -0,0 +1,87 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("evaluate2...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + arb_poly_t f, g; + arb_t x, y1, z1, y2, z2; + + arb_init(x); + arb_init(y1); + arb_init(z1); + arb_init(y2); + arb_init(z2); + arb_poly_init(f); + arb_poly_init(g); + + arb_randtest(x, state, 2 + n_randint(state, 1000), 5); + arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); + arb_poly_derivative(g, f, 2 + n_randint(state, 1000)); + + arb_poly_evaluate2(y1, z1, f, x, 2 + n_randint(state, 1000)); + + arb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); + arb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); + + if (!arb_overlaps(y1, y2) || !arb_overlaps(z1, z2)) + { + printf("FAIL\n\n"); + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("g = "); arb_poly_printd(g, 15); printf("\n\n"); + printf("x = "); arb_printd(x, 15); printf("\n\n"); + printf("y1 = "); arb_printd(y1, 15); printf("\n\n"); + printf("z1 = "); arb_printd(z1, 15); printf("\n\n"); + printf("y2 = "); arb_printd(y2, 15); printf("\n\n"); + printf("z2 = "); arb_printd(z2, 15); printf("\n\n"); + abort(); + } + + arb_poly_clear(f); + arb_poly_clear(g); + arb_clear(x); + arb_clear(y1); + arb_clear(z1); + arb_clear(y2); + arb_clear(z2); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-evaluate2_horner.c b/arb_poly/test/t-evaluate2_horner.c new file mode 100644 index 000000000..b485fcbc8 --- /dev/null +++ b/arb_poly/test/t-evaluate2_horner.c @@ -0,0 +1,87 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("evaluate2_horner...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + arb_poly_t f, g; + arb_t x, y1, z1, y2, z2; + + arb_init(x); + arb_init(y1); + arb_init(z1); + arb_init(y2); + arb_init(z2); + arb_poly_init(f); + arb_poly_init(g); + + arb_randtest(x, state, 2 + n_randint(state, 1000), 5); + arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); + arb_poly_derivative(g, f, 2 + n_randint(state, 1000)); + + arb_poly_evaluate2_horner(y1, z1, f, x, 2 + n_randint(state, 1000)); + + arb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); + arb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); + + if (!arb_overlaps(y1, y2) || !arb_overlaps(z1, z2)) + { + printf("FAIL\n\n"); + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("g = "); arb_poly_printd(g, 15); printf("\n\n"); + printf("x = "); arb_printd(x, 15); printf("\n\n"); + printf("y1 = "); arb_printd(y1, 15); printf("\n\n"); + printf("z1 = "); arb_printd(z1, 15); printf("\n\n"); + printf("y2 = "); arb_printd(y2, 15); printf("\n\n"); + printf("z2 = "); arb_printd(z2, 15); printf("\n\n"); + abort(); + } + + arb_poly_clear(f); + arb_poly_clear(g); + arb_clear(x); + arb_clear(y1); + arb_clear(z1); + arb_clear(y2); + arb_clear(z2); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-evaluate2_rectangular.c b/arb_poly/test/t-evaluate2_rectangular.c new file mode 100644 index 000000000..1fde7215e --- /dev/null +++ b/arb_poly/test/t-evaluate2_rectangular.c @@ -0,0 +1,87 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("evaluate2_rectangular...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + arb_poly_t f, g; + arb_t x, y1, z1, y2, z2; + + arb_init(x); + arb_init(y1); + arb_init(z1); + arb_init(y2); + arb_init(z2); + arb_poly_init(f); + arb_poly_init(g); + + arb_randtest(x, state, 2 + n_randint(state, 1000), 5); + arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); + arb_poly_derivative(g, f, 2 + n_randint(state, 1000)); + + arb_poly_evaluate2_rectangular(y1, z1, f, x, 2 + n_randint(state, 1000)); + + arb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); + arb_poly_evaluate_horner(z2, g, x, 2 + n_randint(state, 1000)); + + if (!arb_overlaps(y1, y2) || !arb_overlaps(z1, z2)) + { + printf("FAIL\n\n"); + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("g = "); arb_poly_printd(g, 15); printf("\n\n"); + printf("x = "); arb_printd(x, 15); printf("\n\n"); + printf("y1 = "); arb_printd(y1, 15); printf("\n\n"); + printf("z1 = "); arb_printd(z1, 15); printf("\n\n"); + printf("y2 = "); arb_printd(y2, 15); printf("\n\n"); + printf("z2 = "); arb_printd(z2, 15); printf("\n\n"); + abort(); + } + + arb_poly_clear(f); + arb_poly_clear(g); + arb_clear(x); + arb_clear(y1); + arb_clear(z1); + arb_clear(y2); + arb_clear(z2); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-evaluate_horner.c b/arb_poly/test/t-evaluate_horner.c new file mode 100644 index 000000000..7f06f7e7b --- /dev/null +++ b/arb_poly/test/t-evaluate_horner.c @@ -0,0 +1,104 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("evaluate_horner...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t F; + fmpq_t X, Y; + arb_poly_t f; + arb_t x, y; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_init(F); + fmpq_init(X); + fmpq_init(Y); + + arb_poly_init(f); + arb_init(x); + arb_init(y); + + fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); + fmpq_randtest(X, state, qbits2); + fmpq_poly_evaluate_fmpq(Y, F, X); + + arb_poly_set_fmpq_poly(f, F, rbits1); + arb_set_fmpq(x, X, rbits2); + arb_poly_evaluate_horner(y, f, x, rbits3); + + if (!arb_contains_fmpq(y, Y)) + { + printf("FAIL\n\n"); + + printf("F = "); fmpq_poly_print(F); printf("\n\n"); + printf("X = "); fmpq_print(X); printf("\n\n"); + printf("Y = "); fmpq_print(Y); printf("\n\n"); + + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("x = "); arb_printd(x, 15); printf("\n\n"); + printf("y = "); arb_printd(y, 15); printf("\n\n"); + + abort(); + } + + /* aliasing */ + arb_poly_evaluate_horner(x, f, x, rbits3); + if (!arb_contains_fmpq(x, Y)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(F); + fmpq_clear(X); + fmpq_clear(Y); + + arb_poly_clear(f); + arb_clear(x); + arb_clear(y); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-evaluate_rectangular.c b/arb_poly/test/t-evaluate_rectangular.c new file mode 100644 index 000000000..bb9fb514f --- /dev/null +++ b/arb_poly/test/t-evaluate_rectangular.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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("evaluate_rectangular...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + arb_poly_t f; + arb_t x, y1, y2; + + arb_init(x); + arb_init(y1); + arb_init(y2); + arb_poly_init(f); + + arb_randtest(x, state, 2 + n_randint(state, 1000), 5); + arb_poly_randtest(f, state, 2 + n_randint(state, 100), 2 + n_randint(state, 1000), 5); + + arb_poly_evaluate_rectangular(y1, f, x, 2 + n_randint(state, 1000)); + arb_poly_evaluate_horner(y2, f, x, 2 + n_randint(state, 1000)); + + if (!arb_overlaps(y1, y2)) + { + printf("FAIL\n\n"); + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("x = "); arb_printd(x, 15); printf("\n\n"); + printf("y1 = "); arb_printd(y1, 15); printf("\n\n"); + printf("y2 = "); arb_printd(y2, 15); printf("\n\n"); + abort(); + } + + arb_poly_clear(f); + arb_clear(x); + arb_clear(y1); + arb_clear(y2); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-evaluate_vec_fast.c b/arb_poly/test/t-evaluate_vec_fast.c new file mode 100644 index 000000000..c3bde1634 --- /dev/null +++ b/arb_poly/test/t-evaluate_vec_fast.c @@ -0,0 +1,104 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("evaluate_vec_fast...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long i, n, qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t F; + fmpq * X, * Y; + arb_poly_t f; + arb_ptr x, y; + + qbits1 = 2 + n_randint(state, 100); + qbits2 = 2 + n_randint(state, 100); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + n = n_randint(state, 10); + + fmpq_poly_init(F); + X = _fmpq_vec_init(n); + Y = _fmpq_vec_init(n); + + arb_poly_init(f); + x = _arb_vec_init(n); + y = _arb_vec_init(n); + + fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); + for (i = 0; i < n; i++) + fmpq_randtest(X + i, state, qbits2); + for (i = 0; i < n; i++) + fmpq_poly_evaluate_fmpq(Y + i, F, X + i); + + arb_poly_set_fmpq_poly(f, F, rbits1); + for (i = 0; i < n; i++) + arb_set_fmpq(x + i, X + i, rbits2); + arb_poly_evaluate_vec_fast(y, f, x, n, rbits3); + + for (i = 0; i < n; i++) + { + if (!arb_contains_fmpq(y + i, Y + i)) + { + printf("FAIL (%ld of %ld)\n\n", i, n); + + printf("F = "); fmpq_poly_print(F); printf("\n\n"); + printf("X = "); fmpq_print(X + i); printf("\n\n"); + printf("Y = "); fmpq_print(Y + i); printf("\n\n"); + + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("x = "); arb_printd(x + i, 15); printf("\n\n"); + printf("y = "); arb_printd(y + i, 15); printf("\n\n"); + + abort(); + } + } + + fmpq_poly_clear(F); + _fmpq_vec_clear(X, n); + _fmpq_vec_clear(Y, n); + + arb_poly_clear(f); + _arb_vec_clear(x, n); + _arb_vec_clear(y, n); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-evaluate_vec_iter.c b/arb_poly/test/t-evaluate_vec_iter.c new file mode 100644 index 000000000..f7cd2a39f --- /dev/null +++ b/arb_poly/test/t-evaluate_vec_iter.c @@ -0,0 +1,104 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("evaluate_vec_iter...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long i, n, qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t F; + fmpq * X, * Y; + arb_poly_t f; + arb_ptr x, y; + + qbits1 = 2 + n_randint(state, 100); + qbits2 = 2 + n_randint(state, 100); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + n = n_randint(state, 10); + + fmpq_poly_init(F); + X = _fmpq_vec_init(n); + Y = _fmpq_vec_init(n); + + arb_poly_init(f); + x = _arb_vec_init(n); + y = _arb_vec_init(n); + + fmpq_poly_randtest(F, state, 1 + n_randint(state, 20), qbits1); + for (i = 0; i < n; i++) + fmpq_randtest(X + i, state, qbits2); + for (i = 0; i < n; i++) + fmpq_poly_evaluate_fmpq(Y + i, F, X + i); + + arb_poly_set_fmpq_poly(f, F, rbits1); + for (i = 0; i < n; i++) + arb_set_fmpq(x + i, X + i, rbits2); + arb_poly_evaluate_vec_iter(y, f, x, n, rbits3); + + for (i = 0; i < n; i++) + { + if (!arb_contains_fmpq(y + i, Y + i)) + { + printf("FAIL (%ld of %ld)\n\n", i, n); + + printf("F = "); fmpq_poly_print(F); printf("\n\n"); + printf("X = "); fmpq_print(X + i); printf("\n\n"); + printf("Y = "); fmpq_print(Y + i); printf("\n\n"); + + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("x = "); arb_printd(x + i, 15); printf("\n\n"); + printf("y = "); arb_printd(y + i, 15); printf("\n\n"); + + abort(); + } + } + + fmpq_poly_clear(F); + _fmpq_vec_clear(X, n); + _fmpq_vec_clear(Y, n); + + arb_poly_clear(f); + _arb_vec_clear(x, n); + _arb_vec_clear(y, n); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-exp_series.c b/arb_poly/test/t-exp_series.c new file mode 100644 index 000000000..9144223bb --- /dev/null +++ b/arb_poly/test/t-exp_series.c @@ -0,0 +1,219 @@ +/*============================================================================= + + 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_poly.h" + + +/* hack: avoid overflow since exp currently uses mpfr */ +void +fmpq_poly_randtest_small(fmpq_poly_t A, flint_rand_t state, long len, long bits) +{ + fmpq_poly_randtest(A, state, len, bits); + if (A->length > 0) + { + bits = _fmpz_vec_max_bits(A->coeffs, A->length); + bits = FLINT_ABS(bits); + fmpz_mul_2exp(A->den, A->den, bits); + _fmpq_poly_normalise(A); + } +} + +int main() +{ + long iter; + flint_rand_t state; + + printf("exp_series...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with fmpq_poly */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A, B; + arb_poly_t a, b; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + + fmpq_poly_init(A); + fmpq_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + + fmpq_poly_randtest(A, state, m, qbits); + fmpq_poly_set_coeff_ui(A, 0, 0UL); + arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); + + fmpq_poly_exp_series(B, A, n); + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_exp_series(b, a, n, rbits2); + + if (!arb_poly_contains_fmpq_poly(b, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + } + + /* test aliasing */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + if (n_randint(state, 100) == 0) + { + m = 1 + n_randint(state, 400); + n = 1 + n_randint(state, 400); + } + else + { + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + } + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + + fmpq_poly_randtest_small(A, state, m, qbits); + + arb_poly_randtest(a, state, 1 + n_randint(state, 300), rbits1, 5); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_exp_series(b, a, n, rbits2); + arb_poly_exp_series(a, a, n, rbits2); + + if (!arb_poly_equal(a, b)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + } + + /* test that log(exp(f)) contains f */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2, rbits3; + fmpq_poly_t A; + arb_poly_t a, b, c; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + if (n_randint(state, 100) == 0) + { + m = 1 + n_randint(state, 400); + n = 1 + n_randint(state, 400); + } + else + { + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + } + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + arb_poly_randtest(b, state, 1 + n_randint(state, 300), rbits1, 5); + + do { + fmpq_poly_randtest_small(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_exp_series(b, a, n, rbits3); + } while (b->length == 0 || arb_contains_zero(b->coeffs)); + + arb_poly_log_series(c, b, n, rbits2); + + fmpq_poly_truncate(A, n); + + if (!arb_poly_contains_fmpq_poly(c, A)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-exp_series_basecase.c b/arb_poly/test/t-exp_series_basecase.c new file mode 100644 index 000000000..1cce5c058 --- /dev/null +++ b/arb_poly/test/t-exp_series_basecase.c @@ -0,0 +1,199 @@ +/*============================================================================= + + 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_poly.h" + + +/* hack: avoid overflow since exp currently uses mpfr */ +void +fmpq_poly_randtest_small(fmpq_poly_t A, flint_rand_t state, long len, long bits) +{ + fmpq_poly_randtest(A, state, len, bits); + if (A->length > 0) + { + bits = _fmpz_vec_max_bits(A->coeffs, A->length); + bits = FLINT_ABS(bits); + fmpz_mul_2exp(A->den, A->den, bits); + _fmpq_poly_normalise(A); + } +} + +int main() +{ + long iter; + flint_rand_t state; + + printf("exp_series_basecase...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with fmpq_poly */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A, B; + arb_poly_t a, b; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 40); + n = 1 + n_randint(state, 40); + + fmpq_poly_init(A); + fmpq_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + + fmpq_poly_randtest(A, state, m, qbits); + fmpq_poly_set_coeff_ui(A, 0, 0UL); + + fmpq_poly_exp_series(B, A, n); + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_exp_series_basecase(b, a, n, rbits2); + + if (!arb_poly_contains_fmpq_poly(b, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + } + + /* test aliasing */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 40); + n = 1 + n_randint(state, 40); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + + fmpq_poly_randtest_small(A, state, m, qbits); + + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_exp_series_basecase(b, a, n, rbits2); + arb_poly_exp_series_basecase(a, a, n, rbits2); + + if (!arb_poly_equal(a, b)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + } + + /* test that log(exp(f)) contains f */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2, rbits3; + fmpq_poly_t A; + arb_poly_t a, b, c; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 40); + n = 1 + n_randint(state, 40); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + do { + fmpq_poly_randtest_small(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_exp_series_basecase(b, a, n, rbits3); + } while (b->length == 0 || arb_contains_zero(b->coeffs)); + + arb_poly_log_series(c, b, n, rbits2); + + fmpq_poly_truncate(A, n); + + if (!arb_poly_contains_fmpq_poly(c, A)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-get_coeff_ptr.c b/arb_poly/test/t-get_coeff_ptr.c new file mode 100644 index 000000000..dbe808d8e --- /dev/null +++ b/arb_poly/test/t-get_coeff_ptr.c @@ -0,0 +1,73 @@ +/*============================================================================= + + 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) 2010 Sebastian Pancratz + Copyright (C) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int +main(void) +{ + int i, result; + flint_rand_t state; + + printf("get_coeff_ptr...."); + fflush(stdout); + + flint_randinit(state); + + for (i = 0; i < 1000; i++) + { + arb_poly_t A; + arb_t a; + long n = n_randint(state, 100); + + arb_poly_init(A); + arb_poly_randtest(A, state, n_randint(state, 100), 100, 10); + arb_init(a); + + arb_poly_get_coeff_arb(a, A, n); + + result = n < arb_poly_length(A) ? + arb_equal(a, arb_poly_get_coeff_ptr(A, n)) : + arb_poly_get_coeff_ptr(A, n) == NULL; + if (!result) + { + printf("FAIL:\n"); + printf("A = "), arb_poly_printd(A, 10), printf("\n\n"); + printf("a = "), arb_print(a), printf("\n\n"); + printf("n = %ld\n\n", n); + abort(); + } + + arb_poly_clear(A); + arb_clear(a); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return 0; +} + diff --git a/arb_poly/test/t-get_set_coeff_fmprb.c b/arb_poly/test/t-get_set_coeff_fmprb.c new file mode 100644 index 000000000..76d8a242a --- /dev/null +++ b/arb_poly/test/t-get_set_coeff_fmprb.c @@ -0,0 +1,79 @@ +/*============================================================================= + + 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) 2009 William Hart + Copyright (C) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int +main(void) +{ + int i, j, result; + flint_rand_t state; + + printf("get/set_coeff_arb...."); + fflush(stdout); + + flint_randinit(state); + + for (i = 0; i < 100; i++) + { + arb_poly_t a; + arb_t x1, x2; + slong coeff, len; + + arb_poly_init(a); + arb_init(x1); + arb_init(x2); + len = n_randint(state, 100) + 1; + + for (j = 0; j < 100; j++) + { + arb_randtest(x1, state, 2 + n_randint(state, 200), 10); + coeff = n_randint(state, len); + arb_poly_set_coeff_arb(a, coeff, x1); + arb_poly_get_coeff_arb(x2, a, coeff); + + result = (arb_equal(x1, x2)); + if (!result) + { + printf("FAIL:\n"); + printf("x1 = "), arb_print(x1), printf("\n"); + printf("x2 = "), arb_print(x2), printf("\n"); + printf("coeff = %ld, length = %ld\n", coeff, len); + abort(); + } + } + + arb_clear(x1); + arb_clear(x2); + arb_poly_clear(a); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return 0; +} + diff --git a/arb_poly/test/t-interpolate_barycentric.c b/arb_poly/test/t-interpolate_barycentric.c new file mode 100644 index 000000000..872d2cb53 --- /dev/null +++ b/arb_poly/test/t-interpolate_barycentric.c @@ -0,0 +1,107 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("interpolate_barycentric...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long i, n, qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t P; + arb_poly_t R, S; + fmpq_t t, u; + arb_ptr xs, ys; + + fmpq_poly_init(P); + arb_poly_init(R); + arb_poly_init(S); + fmpq_init(t); + fmpq_init(u); + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 5); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); + n = P->length; + + xs = _arb_vec_init(n); + ys = _arb_vec_init(n); + + arb_poly_set_fmpq_poly(R, P, rbits1); + + if (n > 0) + { + fmpq_randtest(t, state, qbits2); + arb_set_fmpq(xs, t, rbits2); + + for (i = 1; i < n; i++) + { + fmpq_randtest_not_zero(u, state, qbits2); + fmpq_abs(u, u); + fmpq_add(t, t, u); + arb_set_fmpq(xs + i, t, rbits2); + } + } + + for (i = 0; i < n; i++) + arb_poly_evaluate(ys + i, R, xs + i, rbits2); + + arb_poly_interpolate_barycentric(S, xs, ys, n, rbits3); + + if (!arb_poly_contains_fmpq_poly(S, P)) + { + printf("FAIL:\n"); + printf("P = "); fmpq_poly_print(P); printf("\n\n"); + printf("R = "); arb_poly_printd(R, 15); printf("\n\n"); + printf("S = "); arb_poly_printd(S, 15); printf("\n\n"); + abort(); + } + + fmpq_poly_clear(P); + arb_poly_clear(R); + arb_poly_clear(S); + fmpq_clear(t); + fmpq_clear(u); + _arb_vec_clear(xs, n); + _arb_vec_clear(ys, n); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-interpolate_fast.c b/arb_poly/test/t-interpolate_fast.c new file mode 100644 index 000000000..26ed9adcb --- /dev/null +++ b/arb_poly/test/t-interpolate_fast.c @@ -0,0 +1,107 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("interpolate_fast...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long i, n, qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t P; + arb_poly_t R, S; + fmpq_t t, u; + arb_ptr xs, ys; + + fmpq_poly_init(P); + arb_poly_init(R); + arb_poly_init(S); + fmpq_init(t); + fmpq_init(u); + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 5); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); + n = P->length; + + xs = _arb_vec_init(n); + ys = _arb_vec_init(n); + + arb_poly_set_fmpq_poly(R, P, rbits1); + + if (n > 0) + { + fmpq_randtest(t, state, qbits2); + arb_set_fmpq(xs, t, rbits2); + + for (i = 1; i < n; i++) + { + fmpq_randtest_not_zero(u, state, qbits2); + fmpq_abs(u, u); + fmpq_add(t, t, u); + arb_set_fmpq(xs + i, t, rbits2); + } + } + + for (i = 0; i < n; i++) + arb_poly_evaluate(ys + i, R, xs + i, rbits2); + + arb_poly_interpolate_fast(S, xs, ys, n, rbits3); + + if (!arb_poly_contains_fmpq_poly(S, P)) + { + printf("FAIL:\n"); + printf("P = "); fmpq_poly_print(P); printf("\n\n"); + printf("R = "); arb_poly_printd(R, 15); printf("\n\n"); + printf("S = "); arb_poly_printd(S, 15); printf("\n\n"); + abort(); + } + + fmpq_poly_clear(P); + arb_poly_clear(R); + arb_poly_clear(S); + fmpq_clear(t); + fmpq_clear(u); + _arb_vec_clear(xs, n); + _arb_vec_clear(ys, n); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-interpolate_newton.c b/arb_poly/test/t-interpolate_newton.c new file mode 100644 index 000000000..a2695a51f --- /dev/null +++ b/arb_poly/test/t-interpolate_newton.c @@ -0,0 +1,107 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("interpolate_newton...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long i, n, qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t P; + arb_poly_t R, S; + fmpq_t t, u; + arb_ptr xs, ys; + + fmpq_poly_init(P); + arb_poly_init(R); + arb_poly_init(S); + fmpq_init(t); + fmpq_init(u); + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 5); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_randtest(P, state, 1 + n_randint(state, 20), qbits1); + n = P->length; + + xs = _arb_vec_init(n); + ys = _arb_vec_init(n); + + arb_poly_set_fmpq_poly(R, P, rbits1); + + if (n > 0) + { + fmpq_randtest(t, state, qbits2); + arb_set_fmpq(xs, t, rbits2); + + for (i = 1; i < n; i++) + { + fmpq_randtest_not_zero(u, state, qbits2); + fmpq_abs(u, u); + fmpq_add(t, t, u); + arb_set_fmpq(xs + i, t, rbits2); + } + } + + for (i = 0; i < n; i++) + arb_poly_evaluate(ys + i, R, xs + i, rbits2); + + arb_poly_interpolate_newton(S, xs, ys, n, rbits3); + + if (!arb_poly_contains_fmpq_poly(S, P)) + { + printf("FAIL:\n"); + printf("P = "); fmpq_poly_print(P); printf("\n\n"); + printf("R = "); arb_poly_printd(R, 15); printf("\n\n"); + printf("S = "); arb_poly_printd(S, 15); printf("\n\n"); + abort(); + } + + fmpq_poly_clear(P); + arb_poly_clear(R); + arb_poly_clear(S); + fmpq_clear(t); + fmpq_clear(u); + _arb_vec_clear(xs, n); + _arb_vec_clear(ys, n); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-inv_series.c b/arb_poly/test/t-inv_series.c new file mode 100644 index 000000000..3816a36ee --- /dev/null +++ b/arb_poly/test/t-inv_series.c @@ -0,0 +1,100 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("inv_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A, B; + arb_poly_t a, b; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + + fmpq_poly_init(A); + fmpq_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + + do { + fmpq_poly_randtest_not_zero(A, state, m, qbits); + } while (A->coeffs[0] == 0); + + arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); + + fmpq_poly_inv_series(B, A, n); + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_inv_series(b, a, n, rbits2); + + if (!arb_poly_contains_fmpq_poly(b, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + arb_poly_inv_series(a, a, n, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-log_series.c b/arb_poly/test/t-log_series.c new file mode 100644 index 000000000..b7028bd11 --- /dev/null +++ b/arb_poly/test/t-log_series.c @@ -0,0 +1,190 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("log_series...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with fmpq_poly */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A, B; + arb_poly_t a, b; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + + fmpq_poly_init(A); + fmpq_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + + fmpq_poly_randtest_not_zero(A, state, m, qbits); + fmpq_poly_set_coeff_ui(A, 0, 1UL); + + fmpq_poly_log_series(B, A, n); + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); + arb_poly_log_series(b, a, n, rbits2); + + if (!arb_poly_contains_fmpq_poly(b, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + } + + /* test aliasing */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + + do { + fmpq_poly_randtest_not_zero(A, state, m, qbits); + } while (fmpz_sgn(A->coeffs + 0) <= 0); + + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_log_series(b, a, n, rbits2); + arb_poly_log_series(a, a, n, rbits2); + + if (!arb_poly_equal(a, b)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + } + + /* test that exp(log(f)) contains f */ + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2, rbits3; + fmpq_poly_t A; + arb_poly_t a, b, c; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + do { + fmpq_poly_randtest_not_zero(A, state, m, qbits); + } while (fmpz_sgn(A->coeffs + 0) <= 0); + + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); + arb_poly_log_series(b, a, n, rbits2); + arb_poly_exp_series_basecase(c, b, n, rbits3); + + fmpq_poly_truncate(A, n); + + if (!arb_poly_contains_fmpq_poly(c, A)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-mul.c b/arb_poly/test/t-mul.c new file mode 100644 index 000000000..7655b1356 --- /dev/null +++ b/arb_poly/test/t-mul.c @@ -0,0 +1,141 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("mul...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 100000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); + fmpq_poly_mul(C, A, B); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_mul(c, a, b, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_mul(d, d, b, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_mul(d, a, d, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + /* test squaring */ + arb_poly_set(b, a); + arb_poly_mul(c, a, b, rbits3); + arb_poly_mul(d, a, a, rbits3); + if (!arb_poly_overlaps(c, d)) /* not guaranteed to be identical */ + { + printf("FAIL (squaring)\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_mul(a, a, a, rbits3); + if (!arb_poly_equal(d, a)) + { + printf("FAIL (aliasing, squaring)\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-mullow.c b/arb_poly/test/t-mullow.c new file mode 100644 index 000000000..3e78f8420 --- /dev/null +++ b/arb_poly/test/t-mullow.c @@ -0,0 +1,144 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("mullow...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with fmpq_poly */ + for (iter = 0; iter < 100000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3, trunc; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + trunc = n_randint(state, 10); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); + fmpq_poly_mullow(C, A, B, trunc); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_mullow(c, a, b, trunc, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + printf("trunc = %ld\n", trunc); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_mullow(d, d, b, trunc, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_mullow(d, a, d, trunc, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + /* test squaring */ + arb_poly_set(b, a); + arb_poly_mullow(c, a, b, trunc, rbits3); + arb_poly_mullow(d, a, a, trunc, rbits3); + if (!arb_poly_overlaps(c, d)) /* not guaranteed to be identical */ + { + printf("FAIL (squaring)\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_mullow(a, a, a, trunc, rbits3); + if (!arb_poly_equal(d, a)) + { + printf("FAIL (aliasing, squaring)\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-mullow_block.c b/arb_poly/test/t-mullow_block.c new file mode 100644 index 000000000..a9218dcb5 --- /dev/null +++ b/arb_poly/test/t-mullow_block.c @@ -0,0 +1,223 @@ +/*============================================================================= + + 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_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("mullow_block...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with fmpq_poly */ + for (iter = 0; iter < 10000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3, trunc; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 1000); + qbits2 = 2 + n_randint(state, 1000); + rbits1 = 2 + n_randint(state, 1000); + rbits2 = 2 + n_randint(state, 1000); + rbits3 = 2 + n_randint(state, 1000); + trunc = n_randint(state, 100); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 100), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 100), qbits2); + fmpq_poly_mullow(C, A, B, trunc); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_mullow_block(c, a, b, trunc, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + printf("trunc = %ld\n", trunc); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_mullow_block(d, d, b, trunc, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_mullow_block(d, a, d, trunc, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + /* test squaring */ + arb_poly_set(b, a); + arb_poly_mullow_block(c, a, b, trunc, rbits3); + arb_poly_mullow_block(d, a, a, trunc, rbits3); + if (!arb_poly_overlaps(c, d)) /* not guaranteed to be identical */ + { + printf("FAIL (squaring)\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_mullow_block(a, a, a, trunc, rbits3); + if (!arb_poly_equal(d, a)) + { + printf("FAIL (aliasing, squaring)\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + for (iter = 0; iter < 3000; iter++) + { + long rbits1, rbits2, rbits3, trunc; + arb_poly_t a, b, c, ab, ac, bc, abc, abc2; + + rbits1 = 2 + n_randint(state, 300); + rbits2 = 2 + n_randint(state, 300); + rbits3 = 2 + n_randint(state, 300); + trunc = n_randint(state, 100); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(ab); + arb_poly_init(ac); + arb_poly_init(bc); + arb_poly_init(abc); + arb_poly_init(abc2); + + arb_poly_randtest(a, state, 1 + n_randint(state, 100), rbits1, 1 + n_randint(state, 100)); + arb_poly_randtest(b, state, 1 + n_randint(state, 100), rbits2, 1 + n_randint(state, 100)); + arb_poly_randtest(c, state, 1 + n_randint(state, 100), rbits2, 1 + n_randint(state, 100)); + + /* check a*(b+c) = a*b + a*c */ + arb_poly_mullow_block(ab, a, b, trunc, rbits3); + arb_poly_mullow_block(ac, a, c, trunc, rbits3); + arb_poly_add(abc, ab, ac, rbits3); + + arb_poly_add(bc, b, c, rbits3); + arb_poly_mullow_block(abc2, a, bc, trunc, rbits3); + + if (!arb_poly_overlaps(abc, abc2)) + { + printf("FAIL (a*(b+c) = a*b + a*c) \n\n"); + printf("bits3 = %ld\n", rbits3); + printf("trunc = %ld\n", trunc); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + /* check (b+c)^2 = b^2 + 2bc + c^2 */ + arb_poly_mullow_block(a, b, c, trunc, rbits3); + arb_poly_scalar_mul_2exp_si(a, a, 1); + arb_poly_mullow_block(abc, b, b, trunc, rbits3); + arb_poly_mullow_block(abc2, c, c, trunc, rbits3); + arb_poly_add(abc, abc, a, rbits3); + arb_poly_add(abc, abc, abc2, rbits3); + + arb_poly_mullow_block(abc2, bc, bc, trunc, rbits3); + + if (!arb_poly_overlaps(abc, abc2)) + { + printf("FAIL ((b+c)^2 = b^2 + 2bc + c^2) \n\n"); + printf("bits3 = %ld\n", rbits3); + printf("trunc = %ld\n", trunc); + + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + printf("abc = "); arb_poly_printd(abc, 15); printf("\n\n"); + printf("abc2 = "); arb_poly_printd(abc2, 15); printf("\n\n"); + + abort(); + } + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(ab); + arb_poly_clear(ac); + arb_poly_clear(bc); + arb_poly_clear(abc); + arb_poly_clear(abc2); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-mullow_classical.c b/arb_poly/test/t-mullow_classical.c new file mode 100644 index 000000000..2aca4690e --- /dev/null +++ b/arb_poly/test/t-mullow_classical.c @@ -0,0 +1,144 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("mullow_classical...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with fmpq_poly */ + for (iter = 0; iter < 100000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3, trunc; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c, d; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + trunc = n_randint(state, 10); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); + fmpq_poly_mullow(C, A, B, trunc); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_mullow_classical(c, a, b, trunc, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + printf("trunc = %ld\n", trunc); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_mullow_classical(d, d, b, trunc, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_mullow_classical(d, a, d, trunc, rbits3); + if (!arb_poly_equal(d, c)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + /* test squaring */ + arb_poly_set(b, a); + arb_poly_mullow_classical(c, a, b, trunc, rbits3); + arb_poly_mullow_classical(d, a, a, trunc, rbits3); + if (!arb_poly_overlaps(c, d)) /* not guaranteed to be identical */ + { + printf("FAIL (squaring)\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_mullow_classical(a, a, a, trunc, rbits3); + if (!arb_poly_equal(d, a)) + { + printf("FAIL (aliasing, squaring)\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-pow_fmprb_series.c b/arb_poly/test/t-pow_fmprb_series.c new file mode 100644 index 000000000..3430dde19 --- /dev/null +++ b/arb_poly/test/t-pow_fmprb_series.c @@ -0,0 +1,115 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("pow_arb_series...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with exp/log */ + for (iter = 0; iter < 10000; iter++) + { + long prec, trunc; + arb_poly_t f, g, h1, h2; + arb_t c; + + prec = 2 + n_randint(state, 200); + trunc = n_randint(state, 20); + + arb_poly_init(f); + arb_poly_init(g); + arb_poly_init(h1); + arb_poly_init(h2); + arb_init(c); + + /* generate binomials */ + if (n_randint(state, 20) == 0) + { + arb_randtest(c, state, prec, 10); + arb_poly_set_coeff_arb(f, 0, c); + arb_randtest(c, state, prec, 10); + arb_poly_set_coeff_arb(f, 1 + n_randint(state, 20), c); + } + else + { + arb_poly_randtest(f, state, 1 + n_randint(state, 20), prec, 10); + } + + arb_poly_randtest(h1, state, 1 + n_randint(state, 20), prec, 10); + + arb_randtest(c, state, prec, 10); + arb_poly_set_arb(g, c); + + /* f^c */ + arb_poly_pow_arb_series(h1, f, c, trunc, prec); + + /* f^c = exp(c*log(f)) */ + arb_poly_log_series(h2, f, trunc, prec); + arb_poly_mullow(h2, h2, g, trunc, prec); + arb_poly_exp_series(h2, h2, trunc, prec); + + if (!arb_poly_overlaps(h1, h2)) + { + printf("FAIL\n\n"); + + printf("prec = %ld\n", prec); + printf("trunc = %ld\n", trunc); + + printf("f = "); arb_poly_printd(f, 15); printf("\n\n"); + printf("c = "); arb_printd(c, 15); printf("\n\n"); + printf("h1 = "); arb_poly_printd(h1, 15); printf("\n\n"); + printf("h2 = "); arb_poly_printd(h2, 15); printf("\n\n"); + + abort(); + } + + arb_poly_pow_arb_series(f, f, c, trunc, prec); + + if (!arb_poly_overlaps(f, h1)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + arb_poly_clear(f); + arb_poly_clear(g); + arb_poly_clear(h1); + arb_poly_clear(h2); + arb_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-pow_series.c b/arb_poly/test/t-pow_series.c new file mode 100644 index 000000000..997df5a5e --- /dev/null +++ b/arb_poly/test/t-pow_series.c @@ -0,0 +1,117 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("pow_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 50000; iter++) + { + long rbits1, rbits2, len; + arb_poly_t a, b, c, d; + + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + len = n_randint(state, 25); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + + if (n_randint(state, 4) == 0) + arb_poly_randtest(a, state, 1, rbits1, 25); + else + arb_poly_randtest(a, state, 1 + n_randint(state, 20), rbits1, 5); + + if (n_randint(state, 4) == 0) + arb_poly_randtest(b, state, 1, rbits1, 25); + else + arb_poly_randtest(b, state, 1 + n_randint(state, 20), rbits1, 5); + + arb_poly_randtest(c, state, 1 + n_randint(state, 20), rbits1, 5); + + arb_poly_pow_series(c, a, b, len, rbits2); + + /* a^b = exp(b log a) */ + arb_poly_log_series(d, a, len, rbits2); + arb_poly_mullow(d, d, b, len, rbits2); + arb_poly_exp_series(d, d, len, rbits2); + + if (!arb_poly_overlaps(c, d)) + { + printf("FAIL (iter %ld)\n\n", iter); + printf("bits2 = %ld\n", rbits2); + printf("len = %ld\n", len); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + /* check aliasing */ + if (iter < 5000) + { + arb_poly_set(d, a); + arb_poly_pow_series(d, d, b, len, rbits2); + + if (!arb_poly_overlaps(c, d)) + { + printf("FAIL (aliasing 1)\n"); + abort(); + } + + arb_poly_set(d, b); + arb_poly_pow_series(d, a, d, len, rbits2); + + if (!arb_poly_overlaps(c, d)) + { + printf("FAIL (aliasing 2)\n"); + abort(); + } + } + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-pow_ui.c b/arb_poly/test/t-pow_ui.c new file mode 100644 index 000000000..2c152999b --- /dev/null +++ b/arb_poly/test/t-pow_ui.c @@ -0,0 +1,96 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("pow_ui...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with fmpz_poly */ + for (iter = 0; iter < 10000; iter++) + { + long zbits1, rbits1, rbits2; + ulong e; + fmpz_poly_t A, B; + arb_poly_t a, b; + + zbits1 = 2 + n_randint(state, 100); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + e = n_randint(state, 30); + + fmpz_poly_init(A); + fmpz_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + + fmpz_poly_randtest(A, state, 1 + n_randint(state, 8), zbits1); + fmpz_poly_pow(B, A, e); + + arb_poly_set_fmpz_poly(a, A, rbits1); + arb_poly_pow_ui(b, a, e, rbits2); + + if (!arb_poly_contains_fmpz_poly(b, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + printf("e = %lu\n", e); + + printf("A = "); fmpz_poly_print(A); printf("\n\n"); + printf("B = "); fmpz_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + arb_poly_pow_ui(a, a, e, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpz_poly_clear(A); + fmpz_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-pow_ui_trunc_binexp.c b/arb_poly/test/t-pow_ui_trunc_binexp.c new file mode 100644 index 000000000..3b6ae4d5b --- /dev/null +++ b/arb_poly/test/t-pow_ui_trunc_binexp.c @@ -0,0 +1,98 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("pow_ui_trunc_binexp...."); + fflush(stdout); + + flint_randinit(state); + + /* compare with fmpz_poly */ + for (iter = 0; iter < 10000; iter++) + { + long zbits1, rbits1, rbits2, trunc; + ulong e; + fmpz_poly_t A, B; + arb_poly_t a, b; + + zbits1 = 2 + n_randint(state, 100); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + e = n_randint(state, 50); + trunc = n_randint(state, 40); + + fmpz_poly_init(A); + fmpz_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + + fmpz_poly_randtest(A, state, 1 + n_randint(state, 10), zbits1); + fmpz_poly_pow_trunc(B, A, e, trunc); + + arb_poly_set_fmpz_poly(a, A, rbits1); + arb_poly_pow_ui_trunc_binexp(b, a, e, trunc, rbits2); + + if (!arb_poly_contains_fmpz_poly(b, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + printf("e = %lu\n", e); + printf("trunc = %ld\n", trunc); + + printf("A = "); fmpz_poly_print(A); printf("\n\n"); + printf("B = "); fmpz_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + arb_poly_pow_ui_trunc_binexp(a, a, e, trunc, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpz_poly_clear(A); + fmpz_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-revert_series.c b/arb_poly/test/t-revert_series.c new file mode 100644 index 000000000..f482147fb --- /dev/null +++ b/arb_poly/test/t-revert_series.c @@ -0,0 +1,101 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("revert_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 1000; iter++) + { + long qbits1, rbits1, rbits2, n; + fmpq_poly_t A, B; + arb_poly_t a, b, c; + + qbits1 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + n = 2 + n_randint(state, 25); + + fmpq_poly_init(A); + fmpq_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + do { + fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); + fmpq_poly_set_coeff_ui(A, 0, 0); + } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); + + fmpq_poly_revert_series(B, A, n); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_revert_series(b, a, n, rbits2); + + if (!arb_poly_contains_fmpq_poly(b, B)) + { + printf("FAIL\n\n"); + printf("n = %ld, bits2 = %ld\n", n, rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(c, a); + arb_poly_revert_series(c, c, n, rbits2); + if (!arb_poly_equal(c, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-revert_series_lagrange.c b/arb_poly/test/t-revert_series_lagrange.c new file mode 100644 index 000000000..7ef11b2c5 --- /dev/null +++ b/arb_poly/test/t-revert_series_lagrange.c @@ -0,0 +1,101 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("revert_series_lagrange...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 1000; iter++) + { + long qbits1, rbits1, rbits2, n; + fmpq_poly_t A, B; + arb_poly_t a, b, c; + + qbits1 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + n = 2 + n_randint(state, 25); + + fmpq_poly_init(A); + fmpq_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + do { + fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); + fmpq_poly_set_coeff_ui(A, 0, 0); + } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); + + fmpq_poly_revert_series(B, A, n); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_revert_series_lagrange(b, a, n, rbits2); + + if (!arb_poly_contains_fmpq_poly(b, B)) + { + printf("FAIL\n\n"); + printf("n = %ld, bits2 = %ld\n", n, rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(c, a); + arb_poly_revert_series_lagrange(c, c, n, rbits2); + if (!arb_poly_equal(c, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-revert_series_lagrange_fast.c b/arb_poly/test/t-revert_series_lagrange_fast.c new file mode 100644 index 000000000..3e789931e --- /dev/null +++ b/arb_poly/test/t-revert_series_lagrange_fast.c @@ -0,0 +1,101 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("revert_series_lagrange_fast...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 1000; iter++) + { + long qbits1, rbits1, rbits2, n; + fmpq_poly_t A, B; + arb_poly_t a, b, c; + + qbits1 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + n = 2 + n_randint(state, 25); + + fmpq_poly_init(A); + fmpq_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + do { + fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); + fmpq_poly_set_coeff_ui(A, 0, 0); + } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); + + fmpq_poly_revert_series(B, A, n); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_revert_series_lagrange_fast(b, a, n, rbits2); + + if (!arb_poly_contains_fmpq_poly(b, B)) + { + printf("FAIL\n\n"); + printf("n = %ld, bits2 = %ld\n", n, rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(c, a); + arb_poly_revert_series_lagrange_fast(c, c, n, rbits2); + if (!arb_poly_equal(c, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-revert_series_newton.c b/arb_poly/test/t-revert_series_newton.c new file mode 100644 index 000000000..7ed1fde8b --- /dev/null +++ b/arb_poly/test/t-revert_series_newton.c @@ -0,0 +1,101 @@ +/*============================================================================= + + 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) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("revert_series_newton...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 1000; iter++) + { + long qbits1, rbits1, rbits2, n; + fmpq_poly_t A, B; + arb_poly_t a, b, c; + + qbits1 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + n = 2 + n_randint(state, 25); + + fmpq_poly_init(A); + fmpq_poly_init(B); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + do { + fmpq_poly_randtest(A, state, 1 + n_randint(state, 25), qbits1); + fmpq_poly_set_coeff_ui(A, 0, 0); + } while (A->length < 2 || fmpz_is_zero(A->coeffs + 1)); + + fmpq_poly_revert_series(B, A, n); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_revert_series_newton(b, a, n, rbits2); + + if (!arb_poly_contains_fmpq_poly(b, B)) + { + printf("FAIL\n\n"); + printf("n = %ld, bits2 = %ld\n", n, rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(c, a); + arb_poly_revert_series_newton(c, c, n, rbits2); + if (!arb_poly_equal(c, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-rsqrt_series.c b/arb_poly/test/t-rsqrt_series.c new file mode 100644 index 000000000..0af053682 --- /dev/null +++ b/arb_poly/test/t-rsqrt_series.c @@ -0,0 +1,99 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("rsqrt_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b, c; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + fmpq_poly_randtest_not_zero(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_randtest(b, state, 1 + n_randint(state, 30), rbits1, 5); + + arb_poly_rsqrt_series(b, a, n, rbits2); + + /* Check 1/((1/sqrt(a))^2) = a */ + arb_poly_mullow(c, b, b, n, rbits2); + arb_poly_inv_series(c, c, n, rbits2); + + fmpq_poly_truncate(A, n); + if (!arb_poly_contains_fmpq_poly(c, A)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_rsqrt_series(a, a, n, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-shift_left_right.c b/arb_poly/test/t-shift_left_right.c new file mode 100644 index 000000000..f65bbbc64 --- /dev/null +++ b/arb_poly/test/t-shift_left_right.c @@ -0,0 +1,126 @@ +/*============================================================================= + + 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) 2009 William Hart + Copyright (C) 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int +main(void) +{ + int i, result; + flint_rand_t state; + + printf("shift_left/right...."); + fflush(stdout); + + flint_randinit(state); + + /* Check aliasing of a and b for left shift */ + for (i = 0; i < 1000; i++) + { + arb_poly_t a, b; + long shift = n_randint(state, 100); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); + + arb_poly_shift_left(b, a, shift); + arb_poly_shift_left(a, a, shift); + + result = (arb_poly_equal(a, b)); + if (!result) + { + printf("FAIL:\n"); + arb_poly_printd(a, 10), printf("\n\n"); + arb_poly_printd(b, 10), printf("\n\n"); + abort(); + } + + arb_poly_clear(a); + arb_poly_clear(b); + } + + /* Check aliasing of a and b for right shift */ + for (i = 0; i < 1000; i++) + { + arb_poly_t a, b; + long shift = n_randint(state, 100); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); + + arb_poly_shift_right(b, a, shift); + arb_poly_shift_right(a, a, shift); + + result = (arb_poly_equal(a, b)); + if (!result) + { + printf("FAIL:\n"); + arb_poly_printd(a, 10), printf("\n\n"); + arb_poly_printd(b, 10), printf("\n\n"); + abort(); + } + + arb_poly_clear(a); + arb_poly_clear(b); + } + + /* Check shift left then right does nothing */ + for (i = 0; i < 1000; i++) + { + arb_poly_t a, b, c; + long shift = n_randint(state, 100); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_randtest(a, state, n_randint(state, 100), 2 + n_randint(state, 200), 10); + + arb_poly_shift_left(b, a, shift); + arb_poly_shift_right(c, b, shift); + + result = (arb_poly_equal(c, a)); + if (!result) + { + printf("FAIL:\n"); + arb_poly_printd(a, 10), printf("\n\n"); + arb_poly_printd(b, 10), printf("\n\n"); + arb_poly_printd(c, 10), printf("\n\n"); + abort(); + } + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return 0; +} + diff --git a/arb_poly/test/t-sin_cos_series.c b/arb_poly/test/t-sin_cos_series.c new file mode 100644 index 000000000..81a509bd0 --- /dev/null +++ b/arb_poly/test/t-sin_cos_series.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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("sin_cos_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 1000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A, B; + arb_poly_t a, b, c, d, e; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + fmpq_poly_init(B); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + arb_poly_init(e); + + fmpq_poly_randtest(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_sin_cos_series(b, c, a, n, rbits2); + + /* Check sin(x)^2 + cos(x)^2 = 1 */ + arb_poly_mullow(d, b, b, n, rbits2); + arb_poly_mullow(e, c, c, n, rbits2); + arb_poly_add(d, d, e, rbits2); + + fmpq_poly_one(B); + if (!arb_poly_contains_fmpq_poly(d, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_sin_cos_series(d, c, d, n, rbits2); + if (!arb_poly_equal(b, d)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, a); + arb_poly_sin_cos_series(b, d, d, n, rbits2); + if (!arb_poly_equal(c, d)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + arb_poly_clear(e); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-sin_cos_series_basecase.c b/arb_poly/test/t-sin_cos_series_basecase.c new file mode 100644 index 000000000..9e671d7d9 --- /dev/null +++ b/arb_poly/test/t-sin_cos_series_basecase.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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("sin_cos_series_basecase...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A, B; + arb_poly_t a, b, c, d, e; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + fmpq_poly_init(B); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + arb_poly_init(e); + + fmpq_poly_randtest(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_sin_cos_series_basecase(b, c, a, n, rbits2); + + /* Check sin(x)^2 + cos(x)^2 = 1 */ + arb_poly_mullow(d, b, b, n, rbits2); + arb_poly_mullow(e, c, c, n, rbits2); + arb_poly_add(d, d, e, rbits2); + + fmpq_poly_one(B); + if (!arb_poly_contains_fmpq_poly(d, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_sin_cos_series_basecase(d, c, d, n, rbits2); + if (!arb_poly_equal(b, d)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, a); + arb_poly_sin_cos_series_basecase(b, d, d, n, rbits2); + if (!arb_poly_equal(c, d)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + arb_poly_clear(e); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-sin_cos_series_tangent.c b/arb_poly/test/t-sin_cos_series_tangent.c new file mode 100644 index 000000000..8526dfabd --- /dev/null +++ b/arb_poly/test/t-sin_cos_series_tangent.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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("sin_cos_series_tangent...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A, B; + arb_poly_t a, b, c, d, e; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + fmpq_poly_init(B); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + arb_poly_init(e); + + fmpq_poly_randtest(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_sin_cos_series_tangent(b, c, a, n, rbits2); + + /* Check sin(x)^2 + cos(x)^2 = 1 */ + arb_poly_mullow(d, b, b, n, rbits2); + arb_poly_mullow(e, c, c, n, rbits2); + arb_poly_add(d, d, e, rbits2); + + fmpq_poly_one(B); + if (!arb_poly_contains_fmpq_poly(d, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_sin_cos_series_tangent(d, c, d, n, rbits2); + if (!arb_poly_equal(b, d)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, a); + arb_poly_sin_cos_series_tangent(b, d, d, n, rbits2); + if (!arb_poly_equal(c, d)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + arb_poly_clear(e); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-sin_series_cos_series.c b/arb_poly/test/t-sin_series_cos_series.c new file mode 100644 index 000000000..7122b29a8 --- /dev/null +++ b/arb_poly/test/t-sin_series_cos_series.c @@ -0,0 +1,115 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("sin_series/cos_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 2000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A, B; + arb_poly_t a, b, c, d, e; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + fmpq_poly_init(B); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + arb_poly_init(e); + + fmpq_poly_randtest(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_sin_series(b, a, n, rbits2); + arb_poly_cos_series(c, a, n, rbits2); + + /* Check sin(x)^2 + cos(x)^2 = 1 */ + arb_poly_mullow(d, b, b, n, rbits2); + arb_poly_mullow(e, c, c, n, rbits2); + arb_poly_add(d, d, e, rbits2); + + fmpq_poly_one(B); + if (!arb_poly_contains_fmpq_poly(d, B)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + printf("d = "); arb_poly_printd(d, 15); printf("\n\n"); + + abort(); + } + + arb_poly_set(d, a); + arb_poly_sin_series(d, d, n, rbits2); + if (!arb_poly_equal(b, d)) + { + printf("FAIL (aliasing 1)\n\n"); + abort(); + } + + arb_poly_set(d, a); + arb_poly_cos_series(d, d, n, rbits2); + if (!arb_poly_equal(c, d)) + { + printf("FAIL (aliasing 2)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + arb_poly_clear(e); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-sqrt_series.c b/arb_poly/test/t-sqrt_series.c new file mode 100644 index 000000000..400437254 --- /dev/null +++ b/arb_poly/test/t-sqrt_series.c @@ -0,0 +1,96 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("sqrt_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 10000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b, c; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 30); + n = 1 + n_randint(state, 30); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + fmpq_poly_randtest_not_zero(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + + arb_poly_sqrt_series(b, a, n, rbits2); + + /* Check sqrt(a)^2 = a */ + arb_poly_mullow(c, b, b, n, rbits2); + + fmpq_poly_truncate(A, n); + if (!arb_poly_contains_fmpq_poly(c, A)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_sqrt_series(a, a, n, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/test/t-sub.c b/arb_poly/test/t-sub.c new file mode 100644 index 000000000..901a9bbec --- /dev/null +++ b/arb_poly/test/t-sub.c @@ -0,0 +1,96 @@ +/*============================================================================= + + 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_poly.h" + + +int main() +{ + long iter; + flint_rand_t state; + + printf("sub...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 100000; iter++) + { + long qbits1, qbits2, rbits1, rbits2, rbits3; + fmpq_poly_t A, B, C; + arb_poly_t a, b, c; + + qbits1 = 2 + n_randint(state, 200); + qbits2 = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + rbits3 = 2 + n_randint(state, 200); + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(C); + + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + + fmpq_poly_randtest(A, state, 1 + n_randint(state, 10), qbits1); + fmpq_poly_randtest(B, state, 1 + n_randint(state, 10), qbits2); + fmpq_poly_sub(C, A, B); + + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_set_fmpq_poly(b, B, rbits2); + arb_poly_sub(c, a, b, rbits3); + + if (!arb_poly_contains_fmpq_poly(c, C)) + { + printf("FAIL\n\n"); + printf("bits3 = %ld\n", rbits3); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("B = "); fmpq_poly_print(B); printf("\n\n"); + printf("C = "); fmpq_poly_print(C); printf("\n\n"); + + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/arb_poly/test/t-tan_series.c b/arb_poly/test/t-tan_series.c new file mode 100644 index 000000000..22b2096d3 --- /dev/null +++ b/arb_poly/test/t-tan_series.c @@ -0,0 +1,106 @@ +/*============================================================================= + + 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, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arb_poly.h" + +int main() +{ + long iter; + flint_rand_t state; + + printf("tan_series...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 2000; iter++) + { + long m, n, qbits, rbits1, rbits2; + fmpq_poly_t A; + arb_poly_t a, b, c, d, e; + + qbits = 2 + n_randint(state, 200); + rbits1 = 2 + n_randint(state, 200); + rbits2 = 2 + n_randint(state, 200); + + m = 1 + n_randint(state, 50); + n = 1 + n_randint(state, 50); + + fmpq_poly_init(A); + arb_poly_init(a); + arb_poly_init(b); + arb_poly_init(c); + arb_poly_init(d); + arb_poly_init(e); + + fmpq_poly_randtest(A, state, m, qbits); + arb_poly_set_fmpq_poly(a, A, rbits1); + arb_poly_randtest(b, state, 1 + n_randint(state, 50), rbits1, 5); + + arb_poly_tan_series(b, a, n, rbits2); + + /* check tan(x) = 2*tan(x/2)/(1-tan(x/2)^2) */ + arb_poly_scalar_mul_2exp_si(c, a, -1); + arb_poly_tan_series(c, c, n, rbits2); + arb_poly_mullow(d, c, c, n, rbits2); + arb_poly_one(e); + arb_poly_sub(e, e, d, rbits2); + arb_poly_div_series(c, c, e, n, rbits2); + arb_poly_scalar_mul_2exp_si(c, c, 1); + + if (!arb_poly_overlaps(b, c)) + { + printf("FAIL\n\n"); + printf("bits2 = %ld\n", rbits2); + + printf("A = "); fmpq_poly_print(A); printf("\n\n"); + printf("a = "); arb_poly_printd(a, 15); printf("\n\n"); + printf("b = "); arb_poly_printd(b, 15); printf("\n\n"); + printf("c = "); arb_poly_printd(c, 15); printf("\n\n"); + + abort(); + } + + arb_poly_tan_series(a, a, n, rbits2); + if (!arb_poly_equal(a, b)) + { + printf("FAIL (aliasing)\n\n"); + abort(); + } + + fmpq_poly_clear(A); + arb_poly_clear(a); + arb_poly_clear(b); + arb_poly_clear(c); + arb_poly_clear(d); + arb_poly_clear(e); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/arb_poly/tree.c b/arb_poly/tree.c new file mode 100644 index 000000000..6f549cc7b --- /dev/null +++ b/arb_poly/tree.c @@ -0,0 +1,121 @@ +/*============================================================================= + + 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_poly.h" + +arb_ptr * _arb_poly_tree_alloc(long len) +{ + arb_ptr * tree = NULL; + + if (len) + { + long i, height = FLINT_CLOG2(len); + + tree = flint_malloc(sizeof(arb_ptr) * (height + 1)); + for (i = 0; i <= height; i++) + tree[i] = _arb_vec_init(len + (len >> i) + 1); + } + + return tree; +} + +void _arb_poly_tree_free(arb_ptr * tree, long len) +{ + if (len) + { + long i, height = FLINT_CLOG2(len); + + for (i = 0; i <= height; i++) + _arb_vec_clear(tree[i], len + (len >> i) + 1); + + flint_free(tree); + } +} + +void +_arb_poly_tree_build(arb_ptr * tree, arb_srcptr roots, long len, long prec) +{ + long height, pow, left, i; + arb_ptr pa, pb; + arb_srcptr a, b; + + if (len == 0) + return; + + height = FLINT_CLOG2(len); + + /* zeroth level, (x-a) */ + for (i = 0; i < len; i++) + { + arb_one(tree[0] + (2 * i + 1)); + arb_neg(tree[0] + (2 * i), roots + i); + } + + /* first level, (x-a)(x-b) = x^2 + (-a-b)*x + a*b */ + if (height > 1) + { + pa = tree[1]; + + for (i = 0; i < len / 2; i++) + { + a = (arb_srcptr) (roots + (2 * i)); + b = (arb_srcptr) (roots + (2 * i + 1)); + + arb_mul(pa + (3 * i), a, b, prec); + arb_add(pa + (3 * i + 1), a, b, prec); + arb_neg(pa + (3 * i + 1), pa + (3 * i + 1)); + arb_one(pa + (3 * i + 2)); + } + + if (len & 1) + { + arb_neg(pa + (3 * (len / 2)), roots + len - 1); + arb_one(pa + (3 * (len / 2) + 1)); + } + } + + for (i = 1; i < height - 1; i++) + { + left = len; + pow = 1L << i; + pa = tree[i]; + pb = tree[i + 1]; + + while (left >= 2 * pow) + { + _arb_poly_mul_monic(pb, pa, pow + 1, pa + pow + 1, pow + 1, prec); + left -= 2 * pow; + pa += 2 * pow + 2; + pb += 2 * pow + 1; + } + + if (left > pow) + { + _arb_poly_mul_monic(pb, pa, pow + 1, pa + pow + 1, left - pow + 1, prec); + } + else if (left > 0) + _arb_vec_set(pb, pa, left + 1); + } +} diff --git a/mag.h b/mag.h index 9ca2db85e..89dcbdfd5 100644 --- a/mag.h +++ b/mag.h @@ -449,6 +449,10 @@ 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); + #include "fmpr.h" void mag_set_fmpr(mag_t x, const fmpr_t y); diff --git a/mag/set_d_2exp_fmpz.c b/mag/set_d_2exp_fmpz.c new file mode 100644 index 000000000..76efb3efc --- /dev/null +++ b/mag/set_d_2exp_fmpz.c @@ -0,0 +1,53 @@ +/*============================================================================= + + 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" + +void +mag_set_d_2exp_fmpz(mag_t z, double c, const fmpz_t exp) +{ + if (c == 0.0) + { + mag_zero(z); + } + else if (c > 1e300 || c < 0.0) /* not implemented */ + { + abort(); + } + else + { + int cexp, fix; + mp_limb_t man; + + c = frexp(c, &cexp); + + man = (mp_limb_t)(c * (double)(LIMB_ONE << MAG_BITS)) + 1; + + fix = man >> (MAG_BITS); + man = (man >> fix) + fix; /* XXX: need +fix? */ + MAG_MAN(z) = man; + _fmpz_add_fast(MAG_EXPREF(z), exp, cexp + fix); + } +} diff --git a/mag/set_fmpr.c b/mag/set_fmpr.c index 0564bbe71..012b8d8c8 100644 --- a/mag/set_fmpr.c +++ b/mag/set_fmpr.c @@ -29,10 +29,16 @@ void mag_set_fmpr(mag_t x, const fmpr_t y) { - arf_t t; - arf_init(t); - arf_set_fmpr(t, y); - arf_get_mag(x, t); - arf_clear(t); + if (fmpr_is_special(y)) + { + if (fmpr_is_zero(y)) + mag_zero(x); + else + mag_inf(x); + } + else + { + mag_set_fmpz_2exp_fmpz(x, fmpr_manref(y), fmpr_expref(y)); + } } diff --git a/mag/set_fmpz_2exp_fmpz.c b/mag/set_fmpz_2exp_fmpz.c new file mode 100644 index 000000000..6f0ff5b6b --- /dev/null +++ b/mag/set_fmpz_2exp_fmpz.c @@ -0,0 +1,44 @@ +/*============================================================================= + + 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" + +void +mag_set_fmpz_2exp_fmpz(mag_t z, const fmpz_t man, const fmpz_t exp) +{ + if (fmpz_is_zero(man)) + { + mag_zero(z); + } + else + { + mp_limb_t m; + long cexp; + + m = fmpz_abs_ubound_ui_2exp(&cexp, man, MAG_BITS); + MAG_MAN(z) = m; + _fmpz_add_fast(MAG_EXPREF(z), exp, cexp + MAG_BITS); + } +} diff --git a/mag/test/t-set_d_2exp_fmpz.c b/mag/test/t-set_d_2exp_fmpz.c new file mode 100644 index 000000000..9a7651405 --- /dev/null +++ b/mag/test/t-set_d_2exp_fmpz.c @@ -0,0 +1,123 @@ +/*============================================================================= + + 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 "double_extras.h" +#include "mag.h" + +/* XXX: d_randtest is not good enough */ + +#define EXP_MINUS_32 2.3283064365386962891e-10 +#define EXP_MINUS_64 5.42101086242752217e-20 + +double +d_randtest2(flint_rand_t state) +{ + mp_limb_t m1, m2; + double t; + + if (FLINT_BITS == 64) + { + m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); + + t = ((double) m1) * EXP_MINUS_64; + } + else + { + m1 = n_randtest(state) | (UWORD(1) << (FLINT_BITS - 1)); + m2 = n_randtest(state); + + t = ((double) m1) * EXP_MINUS_32 + + ((double) m2) * EXP_MINUS_64; + } + + return t; +} + +int main() +{ + long iter; + flint_rand_t state; + + printf("set_d_2exp_fmpz...."); + fflush(stdout); + + flint_randinit(state); + + for (iter = 0; iter < 100000; iter++) + { + fmpr_t a, b, c; + fmpz_t e; + mag_t m; + double x; + + fmpr_init(a); + fmpr_init(b); + fmpr_init(c); + fmpz_init(e); + mag_init(m); + + x = d_randtest2(state); + x = ldexp(x, 100 - n_randint(state, 200)); + + if (n_randint(state, 100) == 0) + x = 0.0; + + fmpz_randtest(e, state, 10); + + fmpr_set_d(a, x); + fmpr_mul_2exp_fmpz(a, a, e); + + mag_set_d_2exp_fmpz(m, x, e); + + mag_get_fmpr(b, m); + + fmpr_set(c, a); + fmpr_mul_ui(c, c, 1025, MAG_BITS, FMPR_RND_UP); + fmpr_mul_2exp_si(c, c, -10); + + MAG_CHECK_BITS(m) + + if (!(fmpr_cmpabs(a, b) <= 0 && fmpr_cmpabs(b, c) <= 0)) + { + printf("FAIL\n\n"); + printf("a = "); fmpr_print(a); printf("\n\n"); + printf("b = "); fmpr_print(b); printf("\n\n"); + printf("c = "); fmpr_print(c); printf("\n\n"); + abort(); + } + + fmpr_clear(a); + fmpr_clear(b); + fmpr_clear(c); + fmpz_clear(e); + mag_clear(m); + } + + flint_randclear(state); + flint_cleanup(); + printf("PASS\n"); + return EXIT_SUCCESS; +} +